Added IdentityCache to fix Identity bug of ListDiff

pull/2/head
Harald Wolff 2019-10-15 12:19:33 +02:00
parent 67eae8f9df
commit bec1e483c4
4 changed files with 68 additions and 21 deletions

View File

@ -126,6 +126,7 @@
<Compile Include="test\WeakValueDictionaryTests.cs" />
<Compile Include="collections\WeakKeyReferenceDictionary.cs" />
<Compile Include="odb\values\ODBByteBuffer.cs" />
<Compile Include="odb\ng\IdentityCache.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="odb\" />

View File

@ -0,0 +1,56 @@
using System;
using ln.types.collections;
namespace ln.types.odb.ng
{
public class IdentityCache
{
WeakKeyReferenceDictionary<object, Guid> reverseCache = new WeakKeyReferenceDictionary<object, Guid>();
WeakValueDictionary<Guid, object> forwardCache = new WeakValueDictionary<Guid, object>();
public IdentityCache()
{
}
public bool TryGetValue(Guid identity,out object o)
{
lock (this)
{
return forwardCache.TryGetValue(identity, out o);
}
}
public bool TryGetValue(Guid identity, out object o, Func<object> instantiator)
{
lock (this)
{
if (!TryGetValue(identity, out o))
{
o = instantiator();
forwardCache.Add(identity, o);
reverseCache.Add(o, identity);
}
return false;
}
}
public bool TryGetIdentity(object o,out Guid identity)
{
lock (this)
{
return reverseCache.TryGetValue(o, out identity);
}
}
public void Ensure(Guid identity,object o)
{
lock (this)
{
if (!forwardCache.ContainsKey(identity))
forwardCache.Add(identity, o);
if (!reverseCache.ContainsKey(o))
reverseCache.Add(o, identity);
}
}
}
}

View File

@ -22,7 +22,8 @@ namespace ln.types.odb.ng
public static Mapper Default { get; set; } = new Mapper((IStorageContainer)null);
public IStorageContainer StorageContainer { get; private set; }
public IdentityCache IdentityCache { get; } = new IdentityCache();
Dictionary<Type, IODBMapping> mappings = new Dictionary<Type, IODBMapping>();
mappings.ObjectMapping ObjectMapping { get; }

View File

@ -11,9 +11,6 @@ namespace ln.types.odb.ng.mappings
public class ClassMapping : IODBMapping
{
WeakKeyReferenceDictionary<object, Guid> reverseCache = new WeakKeyReferenceDictionary<object, Guid>();
WeakValueDictionary<Guid, object> forwardCache = new WeakValueDictionary<Guid, object>();
public delegate object GetID(object o);
public delegate object SetID(object o, object id);
@ -51,26 +48,21 @@ namespace ln.types.odb.ng.mappings
return false;
}
private object GetObjectForDocument(Document document)
private object GetObjectForDocument(Mapper mapper,Document document)
{
if (IsReferenceType && forwardCache.TryGetValue(document.ID, out object o))
return o;
object oi = Activator.CreateInstance(MappedType, true);
if (IsReferenceType)
{
forwardCache.Add(document.ID, oi);
reverseCache.Add(oi, document.ID);
if (mapper.IdentityCache.TryGetValue(document.ID, out object o, () => Activator.CreateInstance(MappedType, true)))
return o;
}
return oi;
return Activator.CreateInstance(MappedType, true);
}
public object UnmapValue(Mapper mapper,ODBEntity oval)
{
Document document = oval as Document;
object o = GetObjectForDocument(document);
object o = GetObjectForDocument(mapper,document);
Apply(mapper, document, o);
@ -116,10 +108,7 @@ namespace ln.types.odb.ng.mappings
if (IsReferenceType)
{
if (!forwardCache.ContainsKey(documentID))
forwardCache.Add(documentID, value);
if (!reverseCache.ContainsKey(value))
reverseCache.Add(value, documentID);
mapper.IdentityCache.Ensure(documentID, value);
}
return document;
@ -130,10 +119,10 @@ namespace ln.types.odb.ng.mappings
if (Object.ReferenceEquals(value, null))
return ODBNull.Instance;
if (!reverseCache.TryGetValue(value, out Guid documentID))
documentID = Guid.NewGuid();
if (!mapper.IdentityCache.TryGetIdentity(value, out Guid documentID))
documentID = Guid.NewGuid();
return MapDocument(mapper, documentID, value);
return MapDocument(mapper, documentID, value);
}
public Type GetFieldType(Mapper mapper,string fieldName)