using System; using System.Collections.Generic; using ln.types.odb.values; using System.Linq; using ln.types.odb.ng.storage.bases; using ln.types.threads; using ln.types.odb.ng.diff; using ln.types.collections; namespace ln.types.odb.ng.storage.session { public class SessionStorage : ChainedStorage { public SessionStorageContainer SessionContainer { get; } WeakKeyDictionary cache = new WeakKeyDictionary(); public SessionStorage(SessionStorageContainer session, IStorage storage) :base(storage) { SessionContainer = session; } public override Document Load(Guid documentID) { lock (this) { if (!Storage.Contains(documentID)) throw new KeyNotFoundException(); Document keyDocument = new Document(documentID); if (cache.ContainsKey(keyDocument)) return cache.GetKeyInstance(keyDocument); Document document = Storage.Load(documentID); Document cacheDocument = document.Clone() as Document; cache.Add(document, cacheDocument); return document; } } public override void Save(Document document) { lock (this) { if (cache.ContainsKey(document)) { using (Storage.Lock()) { Document cacheDocument = cache[document]; Document storageDocument = Storage.Load(document.ID); DocumentDiff documentDiff = new DocumentDiff(cacheDocument, document); documentDiff.Apply(storageDocument); Storage.Save(storageDocument); cache[document] = document.Clone() as Document; } } else { Storage.Save(document); cache.Add(document, document.Clone() as Document); } } } public override void Delete(Guid documentID) { lock (this) { Document keyDocument = new Document(documentID); Storage.Delete(documentID); cache.Remove(keyDocument); } } public override bool IsCaching => true; } }