ln.objects/ng/storage/session/SessionStorage.cs

85 lines
2.2 KiB
C#

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<Document, Document> cache = new WeakKeyDictionary<Document, Document>();
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;
}
}