using System; using System.Collections.Generic; using ln.types.odb.ng.storage.bases; using ln.types.btree; using ln.types.cache; using NUnit.Framework; using ln.types.threads; using ln.objects.catalog; namespace ln.types.odb.ng.storage.cache { public class CachingStorage : StorageBase { public int CacheSize => cache.Count; public int MaxCacheSize { get => cache.MaxCacheSize; set => cache.MaxCacheSize = value; } IStorage storage; Cache cache = new Cache(); public CachingStorage(IStorage storage) { this.storage = storage; } public override bool IsOpen => storage.IsOpen; public override void Close() { if (IsOpen) { cache.Clear(); storage.Close(); } } public override void Delete(Guid documentID) { lock (this) { storage.Delete(documentID); cache.Forget(documentID); } } public override void EnsureIndex(params string[] path) => storage.EnsureIndex(path); public override IEnumerable GetDocumentIDs() => storage.GetDocumentIDs(); public override IEnumerable GetDocumentIDs(string path, Predicate predicate) => storage.GetDocumentIDs(path, predicate); public override Document Load(Guid documentID) { if (!Contains(documentID)) throw new KeyNotFoundException(); Document document = null; if (!cache.TryGet(documentID,out document)) document = storage.Load(documentID); cache.Ensure(documentID, document); return document; } public override bool Open() { return storage.Open(); } public override void Save(Document document) { lock (this) { storage.Save(document); } } public override bool Contains(Guid documentID) => storage.Contains(documentID); public override void Dispose() { storage.Dispose(); cache.Clear(); cache = null; } public override bool Refresh(Document document) { return storage.Refresh(document); } public override bool IsCaching => true; } }