From 649db2d8f8261d2c925459a9eb70b6bfd2389a51 Mon Sep 17 00:00:00 2001 From: RogueException Date: Sat, 24 Oct 2015 22:50:14 -0300 Subject: [PATCH] Improved GlobalUser cache --- src/Discord.Net/DiscordClient.Members.cs | 2 +- src/Discord.Net/DiscordClient.Messages.cs | 5 +++- src/Discord.Net/Models/GlobalUser.cs | 36 +++++++---------------- src/Discord.Net/Models/User.cs | 35 ++++++++-------------- 4 files changed, 29 insertions(+), 49 deletions(-) diff --git a/src/Discord.Net/DiscordClient.Members.cs b/src/Discord.Net/DiscordClient.Members.cs index 41cece723..3ea034951 100644 --- a/src/Discord.Net/DiscordClient.Members.cs +++ b/src/Discord.Net/DiscordClient.Members.cs @@ -10,7 +10,7 @@ namespace Discord public Members(DiscordClient client, object writerLock) : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } private string GetKey(string userId, string serverId) - => (serverId ?? "Private") + '_' + userId; + => User.GetId(userId, serverId); public User this[string userId, string serverId] => this[GetKey(userId, serverId)]; diff --git a/src/Discord.Net/DiscordClient.Messages.cs b/src/Discord.Net/DiscordClient.Messages.cs index 92f36a5fe..bd334fbf7 100644 --- a/src/Discord.Net/DiscordClient.Messages.cs +++ b/src/Discord.Net/DiscordClient.Messages.cs @@ -13,7 +13,10 @@ namespace Discord private bool _isEnabled; public Messages(DiscordClient client, object writerLock, bool isEnabled) - : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } + : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) + { + _isEnabled = isEnabled; + } public Message GetOrAdd(string id, string channelId, string userId) { diff --git a/src/Discord.Net/Models/GlobalUser.cs b/src/Discord.Net/Models/GlobalUser.cs index 65cc7e543..329371f62 100644 --- a/src/Discord.Net/Models/GlobalUser.cs +++ b/src/Discord.Net/Models/GlobalUser.cs @@ -9,9 +9,8 @@ namespace Discord { internal sealed class GlobalUser : CachedObject { - private readonly ConcurrentDictionary _servers; - private int _refCount; - + private readonly ConcurrentDictionary _users; + /// Returns the email for this user. /// This field is only ever populated for the current logged in user. [JsonIgnore] @@ -27,15 +26,12 @@ namespace Discord /// Returns a collection of all server-specific data for every server this user is a member of. [JsonIgnore] - public IEnumerable Memberships => _servers.Select(x => _client.Members[Id, x.Key]); - /// Returns a collection of all servers this user is a member of. - [JsonIgnore] - public IEnumerable Servers => _servers.Select(x => _client.Servers[x.Key]); + public IEnumerable Memberships => _users.Select(x => _client.Members[Id, x.Key]); internal GlobalUser(DiscordClient client, string id) : base(client, id) { - _servers = new ConcurrentDictionary(); + _users = new ConcurrentDictionary(); } internal override void OnCached() { } internal override void OnUncached() { } @@ -48,24 +44,14 @@ namespace Discord IsVerified = model.IsVerified; } - internal void AddServer(string serverId) - { - _servers.TryAdd(serverId, true); - } - internal bool RemoveServer(string serverId) - { - bool ignored; - return _servers.TryRemove(serverId, out ignored); - } - - internal void AddRef() - { - Interlocked.Increment(ref _refCount); - } - internal void RemoveRef() + internal void AddUser(User user) => _users.TryAdd(user.Id, user); + internal void RemoveUser(User user) { - if (Interlocked.Decrement(ref _refCount) == 0) - _client.Users.TryRemove(Id); + if (_users.TryRemove(user.Id, out user)) + { + if (_users.Count == 0) + _client.Users.TryRemove(Id); + } } public override string ToString() => Id; diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index 16013404f..3519c4f31 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -11,12 +11,15 @@ namespace Discord { private static readonly string[] _initialRoleIds = new string[0]; + internal static string GetId(string userId, string serverId) => (serverId ?? "Private") + '_' + userId; + private ConcurrentDictionary _channels; private ConcurrentDictionary _permissions; private ServerPermissions _serverPermissions; - private bool _hasRef; private string[] _roleIds; + /// Returns a unique identifier combining this user's id with its server's. + internal string UniqueId => GetId(Id, ServerId); /// Returns the name of this user on this server. public string Name { get; private set; } /// Returns a by-name unique identifier separating this user from others with the same name. @@ -81,20 +84,13 @@ namespace Discord internal override void OnCached() { var server = Server; - if (server != null) - { - server.AddMember(this); - if (Id == _client.CurrentUserId) - server.CurrentMember = this; - } + server.AddMember(this); + if (Id == _client.CurrentUserId) + server.CurrentMember = this; + var user = GlobalUser; - if (user != null) - { - if (server == null || !server.IsVirtual) - user.AddServer(ServerId); - user.AddRef(); - _hasRef = true; - } + if (server == null || !server.IsVirtual) + user.AddUser(this); } internal override void OnUncached() { @@ -105,14 +101,9 @@ namespace Discord if (Id == _client.CurrentUserId) server.CurrentMember = null; } - var user = GlobalUser; - if (user != null) - { - user.RemoveServer(ServerId); - if (_hasRef) - user.RemoveRef(); - } - _hasRef = false; + var globalUser = GlobalUser; + if (globalUser != null) + globalUser.RemoveUser(this); } public override string ToString() => Id;