157 lines
3.9 KiB
C#
157 lines
3.9 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;
|
|
namespace ln.types.odb.ng.storage.session
|
|
{
|
|
public class SessionStorage : ChainedStorage
|
|
{
|
|
public SessionStorageContainer SessionContainer { get; }
|
|
|
|
Dictionary<Guid, CachedDocument> documentCache = new Dictionary<Guid, CachedDocument>();
|
|
|
|
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();
|
|
|
|
if (!documentCache.ContainsKey(documentID))
|
|
{
|
|
Document cacheDocument = Storage.Load(documentID);
|
|
documentCache.Add(documentID, new CachedDocument(cacheDocument));
|
|
}
|
|
else
|
|
{
|
|
DateTime storageTimeStamp = GetStorageTimestamp(documentID);
|
|
if (!storageTimeStamp.Equals(documentCache[documentID].CachedCopy.StorageTimeStamp))
|
|
{
|
|
Document storageDocument = Storage.Load(documentID);
|
|
CachedDocument cd = documentCache[documentID];
|
|
|
|
storageDocument.CloneTo(cd.CachedCopy);
|
|
storageDocument.CloneTo(cd.WorkingCopy);
|
|
}
|
|
}
|
|
return documentCache[documentID].WorkingCopy;
|
|
}
|
|
}
|
|
|
|
public override void Save(Document document)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (GetDocumentLocked(document.ID))
|
|
throw new LockingException();
|
|
|
|
if (!documentCache.ContainsKey(document.ID))
|
|
{
|
|
Storage.Save(document);
|
|
documentCache.Add(document.ID, new CachedDocument(document.Clone() as Document, document));
|
|
}
|
|
else
|
|
{
|
|
if (Storage.LockDocument(document.ID))
|
|
{
|
|
DateTime storageTimestamp = Storage.GetStorageTimestamp(document.ID);
|
|
Document cacheDocument = documentCache[document.ID].CachedCopy;
|
|
|
|
if (cacheDocument.StorageTimeStamp.Equals(storageTimestamp))
|
|
{
|
|
Storage.SaveRelease(document);
|
|
documentCache[document.ID] = new CachedDocument(document.Clone() as Document, document);
|
|
}
|
|
else
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new LockingException();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void Delete(Guid documentID)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (GetDocumentLocked(documentID))
|
|
throw new LockingException();
|
|
|
|
if (documentCache.ContainsKey(documentID))
|
|
{
|
|
documentCache.Remove(documentID);
|
|
}
|
|
Storage.Delete(documentID);
|
|
}
|
|
}
|
|
|
|
public void Sync(Guid documentID)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (documentCache.ContainsKey(documentID))
|
|
Sync(documentCache[documentID].WorkingCopy);
|
|
}
|
|
}
|
|
|
|
public void Sync(Document document)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (!documentCache.TryGetValue(document.ID, out CachedDocument cachedDocument))
|
|
throw new KeyNotFoundException();
|
|
|
|
if (!GetStorageTimestamp(document.ID).Equals(document.StorageTimeStamp))
|
|
{
|
|
Document cacheDocument = cachedDocument.CachedCopy;
|
|
Document storageDocument = Storage.Load(document.ID);
|
|
|
|
DocumentDiff cacheDiff = new DocumentDiff(cacheDocument, document);
|
|
DocumentDiff storageDiff = new DocumentDiff(cacheDocument, storageDocument);
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class CachedDocument
|
|
{
|
|
public Document CachedCopy;
|
|
public Document WorkingCopy;
|
|
|
|
public bool ConcurrentlyChanged;
|
|
|
|
public CachedDocument(Document cachedCopy)
|
|
{
|
|
CachedCopy = cachedCopy;
|
|
WorkingCopy = cachedCopy.Clone() as Document;
|
|
ConcurrentlyChanged = false;
|
|
}
|
|
public CachedDocument(Document cachedCopy, Document workingCopy)
|
|
{
|
|
CachedCopy = cachedCopy;
|
|
WorkingCopy = workingCopy;
|
|
ConcurrentlyChanged = false;
|
|
}
|
|
}
|
|
}
|
|
}
|