ln.types/odb/ng/storage/bases/StorageBase.cs

120 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using ln.types.odb.values;
using System.Linq;
using ln.types.btree;
using System.Threading;
using System.Runtime.ConstrainedExecution;
namespace ln.types.odb.ng.storage.bases
{
public abstract class StorageBase : IStorage
{
BTree<Guid> lockedDocuments = new BTree<Guid>();
public StorageBase()
{
}
public abstract bool Open();
public abstract void Close();
public abstract bool IsOpen { get; }
public abstract Document Load(Guid documentID);
public abstract void Save(Document document);
public abstract void Delete(Guid documentID);
public virtual bool GetDocumentLocked(Guid documentID)
{
lock (this)
{
return lockedDocuments.ContainsKey(documentID);
}
}
public virtual bool LockDocument(Guid documentID)
{
lock (this)
{
if (lockedDocuments.ContainsKey(documentID))
return false;
lockedDocuments.Add(documentID);
return true;
}
}
public virtual bool ReleaseDocument(Guid documentID)
{
lock (this)
{
lockedDocuments.Remove(documentID);
return true;
}
}
public virtual void SaveRelease(Document document)
{
lock (this)
{
ReleaseDocument(document.ID);
Save(document);
}
}
public virtual DateTime GetStorageTimestamp(Guid documentID)
{
Document doc = Load(documentID);
return doc.StorageTimeStamp;
}
/* Enumeration */
public abstract IEnumerable<Guid> GetDocumentIDs();
public abstract IEnumerable<Guid> GetDocumentIDs(string path, Predicate<ODBEntity> predicate);
/* Indeces */
public abstract void EnsureIndex(params string[] path);
public virtual void Dispose()
{
if (IsOpen)
Close();
}
public virtual bool Contains(Guid documentID)
{
return GetDocumentIDs().Contains(documentID);
}
class LockedDocumentID
{
public Guid DocumentID { get; }
int waiting;
public LockedDocumentID(Guid documentID)
{
DocumentID = documentID;
}
public void Lock()
{
waiting++;
Monitor.Enter(this);
}
public bool Release()
{
waiting--;
Monitor.Exit(this);
return waiting > 0;
}
public override bool Equals(object obj)
{
return (obj is LockedDocumentID) && DocumentID.Equals((obj as LockedDocumentID).DocumentID);
}
public override int GetHashCode() => DocumentID.GetHashCode();
}
}
}