Memory improvements
This commit is contained in:
@@ -949,20 +949,7 @@ namespace Discord
|
|||||||
await _gatewayLogger.WarningAsync("PRESENCE_UPDATE referenced an unknown guild.").ConfigureAwait(false);
|
await _gatewayLogger.WarningAsync("PRESENCE_UPDATE referenced an unknown guild.").ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data.Status == UserStatus.Offline)
|
guild.UpdatePresence(data, DataStore);
|
||||||
guild.RemovePresence(data.User.Id);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
guild.AddOrUpdatePresence(data);
|
|
||||||
if (data.Roles.IsSpecified || data.Nick.IsSpecified) //Happens when a user we haven't seen before logs in
|
|
||||||
{
|
|
||||||
CachedGuildUser user = guild.GetUser(data.User.Id);
|
|
||||||
if (user == null)
|
|
||||||
guild.AddUser(data, DataStore);
|
|
||||||
else
|
|
||||||
user.Update(data, UpdateSource.WebSocket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace Discord
|
|||||||
//if (model.Roles.IsSpecified)
|
//if (model.Roles.IsSpecified)
|
||||||
UpdateRoles(model.Roles);
|
UpdateRoles(model.Roles);
|
||||||
}
|
}
|
||||||
public void Update(PresenceModel model, UpdateSource source)
|
public virtual void Update(PresenceModel model, UpdateSource source)
|
||||||
{
|
{
|
||||||
if (source == UpdateSource.Rest && IsAttached) return;
|
if (source == UpdateSource.Rest && IsAttached) return;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ namespace Discord
|
|||||||
private TaskCompletionSource<bool> _downloaderPromise;
|
private TaskCompletionSource<bool> _downloaderPromise;
|
||||||
private ConcurrentHashSet<ulong> _channels;
|
private ConcurrentHashSet<ulong> _channels;
|
||||||
private ConcurrentDictionary<ulong, CachedGuildUser> _members;
|
private ConcurrentDictionary<ulong, CachedGuildUser> _members;
|
||||||
private ConcurrentDictionary<ulong, Presence> _presences;
|
|
||||||
private ConcurrentDictionary<ulong, VoiceState> _voiceStates;
|
private ConcurrentDictionary<ulong, VoiceState> _voiceStates;
|
||||||
|
|
||||||
public bool Available { get; private set; }
|
public bool Available { get; private set; }
|
||||||
@@ -53,12 +52,8 @@ namespace Discord
|
|||||||
_channels = new ConcurrentHashSet<ulong>();
|
_channels = new ConcurrentHashSet<ulong>();
|
||||||
if (_members == null)
|
if (_members == null)
|
||||||
_members = new ConcurrentDictionary<ulong, CachedGuildUser>();
|
_members = new ConcurrentDictionary<ulong, CachedGuildUser>();
|
||||||
if (_presences == null)
|
|
||||||
_presences = new ConcurrentDictionary<ulong, Presence>();
|
|
||||||
if (_roles == null)
|
if (_roles == null)
|
||||||
_roles = new ConcurrentDictionary<ulong, Role>();
|
_roles = new ConcurrentDictionary<ulong, Role>();
|
||||||
if (_voiceStates == null)
|
|
||||||
_voiceStates = new ConcurrentDictionary<ulong, VoiceState>();
|
|
||||||
if (Emojis == null)
|
if (Emojis == null)
|
||||||
Emojis = ImmutableArray.Create<Emoji>();
|
Emojis = ImmutableArray.Create<Emoji>();
|
||||||
if (Features == null)
|
if (Features == null)
|
||||||
@@ -69,17 +64,15 @@ namespace Discord
|
|||||||
base.Update(model as Model, source);
|
base.Update(model as Model, source);
|
||||||
|
|
||||||
MemberCount = model.MemberCount;
|
MemberCount = model.MemberCount;
|
||||||
|
|
||||||
var channels = new ConcurrentHashSet<ulong>();
|
var channels = new ConcurrentHashSet<ulong>(1, (int)(model.Channels.Length * 1.05));
|
||||||
if (model.Channels != null)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < model.Channels.Length; i++)
|
for (int i = 0; i < model.Channels.Length; i++)
|
||||||
AddChannel(model.Channels[i], dataStore, channels);
|
AddChannel(model.Channels[i], dataStore, channels);
|
||||||
}
|
}
|
||||||
_channels = channels;
|
_channels = channels;
|
||||||
|
|
||||||
var members = new ConcurrentDictionary<ulong, CachedGuildUser>();
|
var members = new ConcurrentDictionary<ulong, CachedGuildUser>(1, (int)(model.Presences.Length * 1.05));
|
||||||
if (model.Members != null)
|
|
||||||
{
|
{
|
||||||
DownloadedMemberCount = 0;
|
DownloadedMemberCount = 0;
|
||||||
for (int i = 0; i < model.Members.Length; i++)
|
for (int i = 0; i < model.Members.Length; i++)
|
||||||
@@ -87,23 +80,17 @@ namespace Discord
|
|||||||
_downloaderPromise = new TaskCompletionSource<bool>();
|
_downloaderPromise = new TaskCompletionSource<bool>();
|
||||||
if (!model.Large)
|
if (!model.Large)
|
||||||
_downloaderPromise.SetResult(true);
|
_downloaderPromise.SetResult(true);
|
||||||
}
|
|
||||||
_members = members;
|
|
||||||
|
|
||||||
var presences = new ConcurrentDictionary<ulong, Presence>();
|
|
||||||
if (model.Presences != null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < model.Presences.Length; i++)
|
for (int i = 0; i < model.Presences.Length; i++)
|
||||||
{
|
{
|
||||||
var presence = model.Presences[i];
|
var presence = model.Presences[i];
|
||||||
AddOrUpdatePresence(presence, presences);
|
UpdatePresence(presence, dataStore, members);
|
||||||
//AddUser(presence, dataStore, members);
|
//AddUser(presence, dataStore, members);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_presences = presences;
|
_members = members;
|
||||||
|
|
||||||
var voiceStates = new ConcurrentDictionary<ulong, VoiceState>();
|
var voiceStates = new ConcurrentDictionary<ulong, VoiceState>(1, (int)(model.VoiceStates.Length * 1.05));
|
||||||
if (model.VoiceStates != null)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < model.VoiceStates.Length; i++)
|
for (int i = 0; i < model.VoiceStates.Length; i++)
|
||||||
AddOrUpdateVoiceState(model.VoiceStates[i], dataStore, voiceStates);
|
AddOrUpdateVoiceState(model.VoiceStates[i], dataStore, voiceStates);
|
||||||
@@ -128,29 +115,7 @@ namespace Discord
|
|||||||
_channels.TryRemove(id);
|
_channels.TryRemove(id);
|
||||||
return Discord.DataStore.RemoveChannel(id) as ICachedGuildChannel;
|
return Discord.DataStore.RemoveChannel(id) as ICachedGuildChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Presence AddOrUpdatePresence(PresenceModel model, ConcurrentDictionary<ulong, Presence> presences = null)
|
|
||||||
{
|
|
||||||
var game = model.Game != null ? new Game(model.Game) : (Game?)null;
|
|
||||||
var presence = new Presence(model.Status, game);
|
|
||||||
(presences ?? _presences)[model.User.Id] = presence;
|
|
||||||
return presence;
|
|
||||||
}
|
|
||||||
public Presence? GetPresence(ulong id)
|
|
||||||
{
|
|
||||||
Presence presence;
|
|
||||||
if (_presences.TryGetValue(id, out presence))
|
|
||||||
return presence;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
public Presence? RemovePresence(ulong id)
|
|
||||||
{
|
|
||||||
Presence presence;
|
|
||||||
if (_presences.TryRemove(id, out presence))
|
|
||||||
return presence;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Role AddRole(RoleModel model, ConcurrentDictionary<ulong, Role> roles = null)
|
public Role AddRole(RoleModel model, ConcurrentDictionary<ulong, Role> roles = null)
|
||||||
{
|
{
|
||||||
var role = new Role(this, model);
|
var role = new Role(this, model);
|
||||||
@@ -165,28 +130,6 @@ namespace Discord
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
|
|
||||||
{
|
|
||||||
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel;
|
|
||||||
var voiceState = new VoiceState(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress);
|
|
||||||
(voiceStates ?? _voiceStates)[model.UserId] = voiceState;
|
|
||||||
return voiceState;
|
|
||||||
}
|
|
||||||
public VoiceState? GetVoiceState(ulong id)
|
|
||||||
{
|
|
||||||
VoiceState voiceState;
|
|
||||||
if (_voiceStates.TryGetValue(id, out voiceState))
|
|
||||||
return voiceState;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
public VoiceState? RemoveVoiceState(ulong id)
|
|
||||||
{
|
|
||||||
VoiceState voiceState;
|
|
||||||
if (_voiceStates.TryRemove(id, out voiceState))
|
|
||||||
return voiceState;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<IGuildUser> GetUserAsync(ulong id) => Task.FromResult<IGuildUser>(GetUser(id));
|
public override Task<IGuildUser> GetUserAsync(ulong id) => Task.FromResult<IGuildUser>(GetUser(id));
|
||||||
public override Task<IGuildUser> GetCurrentUserAsync()
|
public override Task<IGuildUser> GetCurrentUserAsync()
|
||||||
=> Task.FromResult<IGuildUser>(CurrentUser);
|
=> Task.FromResult<IGuildUser>(CurrentUser);
|
||||||
@@ -197,7 +140,6 @@ namespace Discord
|
|||||||
=> Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members.OrderBy(x => x.Id).Skip(offset).Take(limit).ToImmutableArray());
|
=> Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members.OrderBy(x => x.Id).Skip(offset).Take(limit).ToImmutableArray());
|
||||||
public CachedGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null)
|
public CachedGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null)
|
||||||
{
|
{
|
||||||
var user = Discord.GetOrAddUser(model.User, dataStore);
|
|
||||||
members = members ?? _members;
|
members = members ?? _members;
|
||||||
|
|
||||||
CachedGuildUser member;
|
CachedGuildUser member;
|
||||||
@@ -205,6 +147,7 @@ namespace Discord
|
|||||||
member.Update(model, UpdateSource.WebSocket);
|
member.Update(model, UpdateSource.WebSocket);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
var user = Discord.GetOrAddUser(model.User, dataStore);
|
||||||
member = new CachedGuildUser(this, user, model);
|
member = new CachedGuildUser(this, user, model);
|
||||||
members[user.Id] = member;
|
members[user.Id] = member;
|
||||||
user.AddRef();
|
user.AddRef();
|
||||||
@@ -243,6 +186,22 @@ namespace Discord
|
|||||||
return member;
|
return member;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
public void UpdatePresence(PresenceModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null)
|
||||||
|
{
|
||||||
|
members = members ?? _members;
|
||||||
|
|
||||||
|
CachedGuildUser member;
|
||||||
|
if (members.TryGetValue(model.User.Id, out member))
|
||||||
|
member.Update(model, UpdateSource.WebSocket);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var user = Discord.GetOrAddUser(model.User, dataStore);
|
||||||
|
member = new CachedGuildUser(this, user, model);
|
||||||
|
members[user.Id] = member;
|
||||||
|
user.AddRef();
|
||||||
|
DownloadedMemberCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
public async Task DownloadMembersAsync()
|
public async Task DownloadMembersAsync()
|
||||||
{
|
{
|
||||||
if (!HasAllMembers)
|
if (!HasAllMembers)
|
||||||
@@ -254,6 +213,28 @@ namespace Discord
|
|||||||
_downloaderPromise.TrySetResult(true);
|
_downloaderPromise.TrySetResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
|
||||||
|
{
|
||||||
|
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel;
|
||||||
|
var voiceState = new VoiceState(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress);
|
||||||
|
(voiceStates ?? _voiceStates)[model.UserId] = voiceState;
|
||||||
|
return voiceState;
|
||||||
|
}
|
||||||
|
public VoiceState? GetVoiceState(ulong id)
|
||||||
|
{
|
||||||
|
VoiceState voiceState;
|
||||||
|
if (_voiceStates.TryGetValue(id, out voiceState))
|
||||||
|
return voiceState;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public VoiceState? RemoveVoiceState(ulong id)
|
||||||
|
{
|
||||||
|
VoiceState voiceState;
|
||||||
|
if (_voiceStates.TryRemove(id, out voiceState))
|
||||||
|
return voiceState;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public CachedGuild Clone() => MemberwiseClone() as CachedGuild;
|
public CachedGuild Clone() => MemberwiseClone() as CachedGuild;
|
||||||
|
|
||||||
new internal ICachedGuildChannel ToChannel(ChannelModel model)
|
new internal ICachedGuildChannel ToChannel(ChannelModel model)
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
internal class CachedGuildUser : GuildUser, ICachedUser
|
internal class CachedGuildUser : GuildUser, ICachedUser
|
||||||
{
|
{
|
||||||
|
private Game? _game;
|
||||||
|
private UserStatus _status;
|
||||||
|
|
||||||
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
||||||
public new CachedGuild Guild => base.Guild as CachedGuild;
|
public new CachedGuild Guild => base.Guild as CachedGuild;
|
||||||
public new CachedPublicUser User => base.User as CachedPublicUser;
|
public new CachedPublicUser User => base.User as CachedPublicUser;
|
||||||
|
|
||||||
public Presence? Presence => Guild.GetPresence(Id);
|
public override Game? Game => _game;
|
||||||
public override Game? Game => Presence?.Game;
|
public override UserStatus Status => _status;
|
||||||
public override UserStatus Status => Presence?.Status ?? UserStatus.Offline;
|
|
||||||
|
|
||||||
public VoiceState? VoiceState => Guild.GetVoiceState(Id);
|
public VoiceState? VoiceState => Guild.GetVoiceState(Id);
|
||||||
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
|
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
|
||||||
@@ -28,6 +30,14 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(PresenceModel model, UpdateSource source)
|
||||||
|
{
|
||||||
|
base.Update(model, source);
|
||||||
|
|
||||||
|
_status = model.Status;
|
||||||
|
_game = model.Game != null ? new Game(model.Game) : (Game?)null;
|
||||||
|
}
|
||||||
|
|
||||||
public CachedGuildUser Clone() => MemberwiseClone() as CachedGuildUser;
|
public CachedGuildUser Clone() => MemberwiseClone() as CachedGuildUser;
|
||||||
ICachedUser ICachedUser.Clone() => Clone();
|
ICachedUser ICachedUser.Clone() => Clone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
namespace Discord
|
|
||||||
{
|
|
||||||
internal struct Presence : IPresence
|
|
||||||
{
|
|
||||||
public UserStatus Status { get; }
|
|
||||||
public Game? Game { get; }
|
|
||||||
|
|
||||||
public Presence(UserStatus status, Game? game)
|
|
||||||
{
|
|
||||||
Status = status;
|
|
||||||
Game = game;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user