using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using Remora.Discord.API.Abstractions.Objects; using Remora.Rest.Core; namespace Catalogger.Backend.Cache.InMemoryCache; public class ChannelCache { private readonly ConcurrentDictionary _channels = new(); private readonly ConcurrentDictionary> _guildChannels = new(); public int Size => _channels.Count; public void Set(IChannel channel, Snowflake? guildId = null) { _channels[channel.ID] = channel; if (guildId == null) { if (!channel.GuildID.TryGet(out var snowflake)) return; guildId = snowflake; } // Add to set of guild channels _guildChannels.AddOrUpdate(guildId.Value, _ => [channel.ID], (_, l) => { l.Add(channel.ID); return l; }); } public bool TryGet(Snowflake id, [NotNullWhen(true)] out IChannel? channel) => _channels.TryGetValue(id, out channel); public void Remove(Snowflake? guildId, Snowflake id, out IChannel? channel) { _channels.Remove(id, out channel); if (guildId == null) return; // Remove from set of guild channels _guildChannels.AddOrUpdate(guildId.Value, _ => [], (_, s) => { s.Remove(id); return s; }); } /// /// Gets all of a guild's cached channels. /// /// The guild to get the channels of /// A list of cached channels public IEnumerable GuildChannels(Snowflake guildId) => !_guildChannels.TryGetValue(guildId, out var channelIds) ? [] : channelIds.Select(id => _channels.GetValueOrDefault(id)) .Where(c => c != null).Select(c => c!); }