using System; using System.Collections.Generic; using System.Linq; using StardewModdingAPI.Toolkit.Framework.UpdateData; using StardewModdingAPI.Web.Framework.Clients; namespace StardewModdingAPI.Web.Framework.Caching.Mods { /// Manages cached mod data in-memory. internal class ModCacheMemoryRepository : BaseCacheRepository, IModCacheRepository { /********* ** Fields *********/ /// The cached mod data indexed by {site key}:{ID}. private readonly IDictionary> Mods = new Dictionary>(StringComparer.OrdinalIgnoreCase); /********* ** Public methods *********/ /// Get the cached mod data. /// The mod site to search. /// The mod's unique ID within the . /// The fetched mod. /// Whether to update the mod's 'last requested' date. public bool TryGetMod(ModSiteKey site, string id, out Cached mod, bool markRequested = true) { // get mod if (!this.Mods.TryGetValue(this.GetKey(site, id), out var cachedMod)) { mod = null; return false; } // bump 'last requested' if (markRequested) cachedMod.LastRequested = DateTimeOffset.UtcNow; mod = cachedMod; return true; } /// Save data fetched for a mod. /// The mod site on which the mod is found. /// The mod's unique ID within the . /// The mod data. public void SaveMod(ModSiteKey site, string id, IModPage mod) { string key = this.GetKey(site, id); this.Mods[key] = new Cached(mod); } /// Delete data for mods which haven't been requested within a given time limit. /// The minimum age for which to remove mods. public void RemoveStaleMods(TimeSpan age) { DateTimeOffset minDate = DateTimeOffset.UtcNow.Subtract(age); string[] staleKeys = this.Mods .Where(p => p.Value.LastRequested < minDate) .Select(p => p.Key) .ToArray(); foreach (string key in staleKeys) this.Mods.Remove(key); } /********* ** Private methods *********/ /// Get a cache key. /// The mod site. /// The mod ID. private string GetKey(ModSiteKey site, string id) { return $"{site}:{id.Trim()}".ToLower(); } } }