void AddToObjCache(ulong oid, object obj, DBObjectMetadata metadata) { if (_objBigCache != null) { CompactObjCacheIfNeeded(); _objBigCache[oid] = new WeakReference(obj); _objBigMetadata.Add(obj, metadata); return; } if (_objSmallCache == null) { _objSmallCache = new Dictionary <ulong, object>(); _objSmallMetadata = new Dictionary <object, DBObjectMetadata>(ReferenceEqualityComparer <object> .Instance); } else if (_objSmallCache.Count > 30) { _objBigCache = new Dictionary <ulong, WeakReference>(); _objBigMetadata = new ConditionalWeakTable <object, DBObjectMetadata>(); foreach (var pair in _objSmallCache) { _objBigCache.Add(pair.Key, new WeakReference(pair.Value)); } _objSmallCache = null; foreach (var pair in _objSmallMetadata) { _objBigMetadata.Add(pair.Key, pair.Value); } _objSmallMetadata = null; _objBigCache.Add(oid, new WeakReference(obj)); _objBigMetadata.Add(obj, metadata); return; } _objSmallCache.Add(oid, obj); _objSmallMetadata.Add(obj, metadata); }
object ReadObjFinish(ulong oid, TableInfo tableInfo, ByteArrayReader reader) { var tableVersion = reader.ReadVUInt32(); var metadata = new DBObjectMetadata(oid, DBObjectState.Read); var obj = tableInfo.Creator(this, metadata); AddToObjCache(oid, obj, metadata); tableInfo.GetLoader(tableVersion)(this, metadata, reader, obj); return(obj); }
public void Delete(ulong oid) { object obj = null; if (_objSmallCache != null) { if (_objSmallCache.TryGetValue(oid, out obj)) { _objSmallCache.Remove(oid); } } else if (_objBigCache != null) { WeakReference weakobj; if (_objBigCache.TryGetValue(oid, out weakobj)) { obj = weakobj.Target; _objBigCache.Remove(oid); } } _dirtyObjSet?.Remove(oid); _keyValueTrProtector.Start(); _keyValueTr.SetKeyPrefix(ObjectDB.AllObjectsPrefix); if (_keyValueTr.FindExactKey(BuildKeyFromOid(oid))) { _keyValueTr.EraseCurrent(); } if (obj == null) { return; } DBObjectMetadata metadata = null; if (_objSmallMetadata != null) { if (!_objSmallMetadata.TryGetValue(obj, out metadata)) { return; } } else if (_objBigMetadata != null) { if (!_objBigMetadata.TryGetValue(obj, out metadata)) { return; } } if (metadata == null) { return; } metadata.State = DBObjectState.Deleted; }
public object New(Type type) { var tableInfo = AutoRegisterType(type); tableInfo.EnsureClientTypeVersion(); var oid = 0ul; var metadata = new DBObjectMetadata(oid, DBObjectState.Dirty); var obj = tableInfo.Creator(this, metadata); tableInfo.Initializer(this, metadata, obj); if (oid != 0) { AddToObjCache(oid, obj, metadata); AddToDirtySet(oid, obj); } return(obj); }
public object Singleton(Type type) { var tableInfo = AutoRegisterType(type); tableInfo.EnsureClientTypeVersion(); var oid = (ulong)tableInfo.SingletonOid; var obj = GetObjFromObjCacheByOid(oid); if (obj == null) { var content = tableInfo.SingletonContent(_transactionNumber); if (content == null) { _keyValueTrProtector.Start(); _keyValueTr.SetKeyPrefix(ObjectDB.AllObjectsPrefix); if (_keyValueTr.FindExactKey(BuildKeyFromOid(oid))) { content = _keyValueTr.GetValueAsByteArray(); tableInfo.CacheSingletonContent(_transactionNumber, content); } } if (content != null) { var reader = new ByteArrayReader(content); reader.SkipVUInt32(); obj = ReadObjFinish(oid, tableInfo, reader); } } if (obj != null) { if (!type.IsInstanceOfType(obj)) { throw new BTDBException($"Internal error oid {oid} does not belong to {tableInfo.Name}"); } return(obj); } _updatedTables?.Remove(tableInfo); var metadata = new DBObjectMetadata(oid, DBObjectState.Dirty); obj = tableInfo.Creator(this, metadata); tableInfo.Initializer(this, metadata, obj); AddToObjCache(oid, obj, metadata); AddToDirtySet(oid, obj); return(obj); }
void StoreObject(object o) { var type = o.GetType(); if (!type.IsClass) { throw new BTDBException("You can store only classes, not " + type.ToSimpleName()); } var tableInfo = _owner.TablesInfo.FindByType(type); IfNeededPersistTableInfo(tableInfo); DBObjectMetadata metadata = null; if (_objSmallMetadata != null) { _objSmallMetadata.TryGetValue(o, out metadata); } else if (_objBigMetadata != null) { _objBigMetadata.TryGetValue(o, out metadata); } if (metadata == null) { throw new BTDBException("Metadata for object not found"); } if (metadata.State == DBObjectState.Deleted) { return; } var writer = new ByteBufferWriter(); writer.WriteVUInt32(tableInfo.Id); writer.WriteVUInt32(tableInfo.ClientTypeVersion); tableInfo.Saver(this, metadata, writer, o); if (tableInfo.IsSingletonOid(metadata.Id)) { tableInfo.CacheSingletonContent(_transactionNumber + 1, null); } _keyValueTrProtector.Start(); _keyValueTr.SetKeyPrefix(ObjectDB.AllObjectsPrefix); _keyValueTr.CreateOrUpdateKeyValue(BuildKeyFromOid(metadata.Id), writer.Data.ToByteArray()); }