예제 #1
0
 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);
 }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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());
        }