// Copyright (C) 2021-present sam (starshines.gay) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . 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!); public void RemoveGuild(Snowflake guildId) { if (!_guildChannels.TryGetValue(guildId, out var channelIds)) return; foreach (var id in channelIds) { _channels.Remove(id, out _); } _guildChannels.Remove(guildId, out _); } }