From 1c35027e316795523f616a609fccf3094a27194d Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Mon, 7 Jun 2010 13:19:39 +0000 Subject: [PATCH] Concurrency logic refactored in Registry; implemented Registry.Delete; IDataObject turned into a class; some access modifiers replaced with a stronger ones --- Core/DataObject.cs | 17 ++++++----- Core/IDataObject.cs | 8 +++-- Core/Registry.cs | 72 ++++++++++++++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 34 deletions(-) diff --git a/Core/DataObject.cs b/Core/DataObject.cs index 866cccb..135d187 100644 --- a/Core/DataObject.cs +++ b/Core/DataObject.cs @@ -12,7 +12,7 @@ namespace FLocal.Core { private TKey? _id; - public TKey id { + public override TKey id { get { if(this.isNewObject) { throw new ObjectDoesntHaveAnIdException(); @@ -21,7 +21,7 @@ namespace FLocal.Core { } } - public bool isNewObject { + private bool isNewObject { get { return !this._id.HasValue; } @@ -29,25 +29,28 @@ namespace FLocal.Core { private bool isJustCreated; - public DataObject() { + internal DataObject() { Debug.Assert(this is T); this.isJustCreated = true; this._id = null; } public static T LoadById(TKey id) { - return registry.Get(id); + return registry.Get(id, false); } - protected virtual void AfterCreate() { } + protected virtual void AfterCreate(bool forLoadingFromHash) { } - public void CreateByIdFromRegistry(TKey id) { + internal override void CreateByIdFromRegistry(TKey id, bool forLoadingFromHash) { if(!this.isJustCreated) throw new CriticalException("Object already has an id"); this._id = id; this.isJustCreated = false; - this.AfterCreate(); + this.AfterCreate(forLoadingFromHash); } + internal override void markAsDeletedFromRegistry() { + } + private static Registry registry { get { return Registry.instance; diff --git a/Core/IDataObject.cs b/Core/IDataObject.cs index 14dac6b..45640e3 100644 --- a/Core/IDataObject.cs +++ b/Core/IDataObject.cs @@ -5,7 +5,7 @@ using System.Text; namespace FLocal.Core { - interface IDataObject /*: IDataObject*/ + public abstract class IDataObject where TData : IDataObject, new() where TKey : struct { @@ -13,14 +13,16 @@ namespace FLocal.Core { //static TData CreateByIdFromRegistry(TKey id); - void CreateByIdFromRegistry(TKey id); + internal abstract void CreateByIdFromRegistry(TKey id, bool forLoadingFromHash); //TKey GetId(); - TKey id { + public abstract TKey id { get; } + internal abstract void markAsDeletedFromRegistry(); + } } diff --git a/Core/Registry.cs b/Core/Registry.cs index c3a2a66..d364ee2 100644 --- a/Core/Registry.cs +++ b/Core/Registry.cs @@ -8,42 +8,66 @@ namespace FLocal.Core { where TData : IDataObject, new() where TKey : struct { - public static readonly Registry instance = new Registry(); + internal static readonly Registry instance = new Registry(); private Dictionary storage; - private HashSet locks; + private Dictionary locks; - protected Registry() { + private Registry() { this.storage = new Dictionary(); - this.locks = new HashSet(); + this.locks = new Dictionary(); } - public TData Get(TKey id) { - if(this.locks.Contains(id)) throw new CriticalException("Locked"); - if(!this.storage.ContainsKey(id)) { - try { - this.locks.Add(id); - - //this.storage[id] = IDataObject.CreateByIdFromRegistry(id); - //this.storage[id] = TData.CreateByIdFromRegistry(id); - TData obj = new TData(); - obj.CreateByIdFromRegistry(id); - this.storage[id] = obj; - - this.locks.Remove(id); - } catch(FLocalException e) { - this.locks.Remove(id); - throw e; - } + internal TData Get(TKey id, bool forLoadingFromHash) { + if(!this.locks.ContainsKey(id)) { + lock(this.locks) { + if(!this.locks.ContainsKey(id)) { + this.locks.Add(id, new object()); + } + } + } + lock(this.locks[id]) { + if(!this.storage.ContainsKey(id)) { + + //this.storage[id] = IDataObject.CreateByIdFromRegistry(id); + //this.storage[id] = TData.CreateByIdFromRegistry(id); + TData obj = new TData(); + obj.CreateByIdFromRegistry(id, forLoadingFromHash); + this.storage[id] = obj; + } } - return this.storage[id]; + + lock(this.locks) { + if(this.storage.ContainsKey(id)) { + return this.storage[id]; + } + } + + return this.Get(id, forLoadingFromHash); } - public bool IsCached(TKey id) { +/* public bool IsCached(TKey id) { if(this.locks.Contains(id)) throw new CriticalException("locked"); return this.storage.ContainsKey(id); - } + }*/ + + internal void Delete(TKey[] idsToDelete) { + foreach(TKey id in idsToDelete) { + lock(this.locks[id]) { + IDataObject obj = null; + lock(this.locks) { + if(this.storage.ContainsKey(id)) { + obj = this.storage[id]; + this.storage.Remove(id); + } + } + if(obj != null) { + obj.markAsDeletedFromRegistry(); + } + } + } + } }