예제 #1
0
        public bool ReadObject(out object? @object)
        {
            var id = (int)_reader.ReadVUInt32();

            if (id == 0)
            {
                @object = null;
                return(false);
            }
            id--;
            var o = RetriveObj(id);

            if (o != null)
            {
                var mp = o as IMemorizedPosition;
                if (mp == null)
                {
                    @object = o;
                    return(false);
                }
                PushReturningPosition(((ICanMemorizePosition)_reader).MemorizeCurrentPosition());
                mp.Restore();
            }
            else
            {
                PushReturningPosition(null);
            }
            _lastIdOfObj = id;
            @object      = null;
            return(true);
        }
예제 #2
0
파일: FileKeyIndex.cs 프로젝트: saryn/BTDB
 public FileKeyIndex(AbstractBufferedReader reader, Guid?guid, bool withCommitUlong, bool modern)
 {
     _guid            = guid;
     _generation      = reader.ReadVInt64();
     _trLogFileId     = reader.ReadVUInt32();
     _trLogOffset     = reader.ReadVUInt32();
     _keyValueCount   = (long)reader.ReadVUInt64();
     _commitUlong     = withCommitUlong ? reader.ReadVUInt64() : 0;
     _compressionType = modern ? (KeyIndexCompression)reader.ReadUInt8() : KeyIndexCompression.Old;
 }
예제 #3
0
            public object?LoadObject()
            {
                var typeId = _reader.ReadVUInt32();

                if (typeId == 0)
                {
                    return(null);
                }
                if (typeId == 1)
                {
                    var backRefId = _reader.ReadVUInt32();
                    return(_backRefs[(int)backRefId]);
                }
                return(_mapping.Load(typeId, _reader, this));
            }
예제 #4
0
        internal static void SkipHeader(AbstractBufferedReader reader)
        {
            FileCollectionWithFileInfos.SkipHeader(reader);
            var type            = (KVFileType)reader.ReadUInt8();
            var withCommitUlong = type == KVFileType.KeyIndexWithCommitUlong || type == KVFileType.ModernKeyIndex || type == KVFileType.ModernKeyIndexWithUlongs;

            reader.SkipVInt64();  // generation
            reader.SkipVUInt32(); // trLogFileId
            reader.SkipVUInt32(); // trLogOffset
            reader.SkipVUInt64(); // keyValueCount
            if (withCommitUlong)
            {
                reader.SkipVUInt64();                  // commitUlong
            }
            if (type == KVFileType.ModernKeyIndex || type == KVFileType.ModernKeyIndexWithUlongs)
            {
                reader.SkipUInt8();
            }
            if (type == KVFileType.ModernKeyIndexWithUlongs)
            {
                var ulongCount = reader.ReadVUInt32();
                while (ulongCount-- > 0)
                {
                    reader.SkipVUInt64();
                }
            }
        }
예제 #5
0
 public HashKeyIndex(AbstractBufferedReader reader, Guid?guid)
 {
     _guid       = guid;
     _subId      = reader.ReadVInt64();
     _generation = reader.ReadVInt64();
     _keyLen     = reader.ReadVUInt32();
 }
예제 #6
0
        void IterateInlineDict(AbstractBufferedReader reader, IFieldHandler keyHandler, IFieldHandler valueHandler, bool skipping)
        {
            var skip  = skipping || _visitor != null && !_visitor.StartDictionary();
            var count = reader.ReadVUInt32();

            while (count-- > 0)
            {
                var skipKey = skip || _visitor != null && !_visitor.StartDictKey();
                IterateHandler(reader, keyHandler, skipKey, null);
                if (!skipKey)
                {
                    _visitor?.EndDictKey();
                }
                var skipValue = skip || _visitor != null && !_visitor.StartDictValue();
                IterateHandler(reader, valueHandler, skipValue, null);
                if (!skipValue)
                {
                    _visitor?.EndDictValue();
                }
            }
            if (!skip)
            {
                _visitor?.EndDictionary();
            }
        }
예제 #7
0
        // ReSharper disable MemberCanBePrivate.Global
        public static void SkipImpl(AbstractBufferedReader reader)
        // ReSharper restore MemberCanBePrivate.Global
        {
            var items = reader.ReadVUInt32();

            while (items-- > 0)
            {
                reader.SkipVUInt64();
            }
        }
예제 #8
0
        public TypeInf(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory)
        {
            _type = null;
            _name = reader.ReadString();
            var methodCount = reader.ReadVUInt32();

            _methodInfs = new MethodInf[methodCount];
            for (int i = 0; i < methodCount; i++)
            {
                _methodInfs[i] = new MethodInf(reader, fieldHandlerFactory);
            }
            var properyCount = reader.ReadVUInt32();

            _propertyInfs = new PropertyInf[properyCount];
            for (int i = 0; i < properyCount; i++)
            {
                PropertyInfs[i] = new PropertyInf(reader, fieldHandlerFactory);
            }
        }
예제 #9
0
 public FileKeyIndex(AbstractBufferedReader reader, Guid?guid, bool withCommitUlong, bool modern, bool withUlongs)
 {
     _guid            = guid;
     _generation      = reader.ReadVInt64();
     _trLogFileId     = reader.ReadVUInt32();
     _trLogOffset     = reader.ReadVUInt32();
     _keyValueCount   = (long)reader.ReadVUInt64();
     _commitUlong     = withCommitUlong ? reader.ReadVUInt64() : 0;
     _compressionType = modern ? (KeyIndexCompression)reader.ReadUInt8() : KeyIndexCompression.Old;
     _ulongs          = null;
     if (withUlongs)
     {
         _ulongs = new ulong[reader.ReadVUInt32()];
         for (var i = 0; i < _ulongs.Length; i++)
         {
             _ulongs[i] = reader.ReadVUInt64();
         }
     }
 }
예제 #10
0
        internal static TableVersionInfo Load(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory, string tableName)
        {
            var fieldCount = reader.ReadVUInt32();
            var fieldInfos = new TableFieldInfo[fieldCount];

            for (int i = 0; i < fieldCount; i++)
            {
                fieldInfos[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, tableName);
            }
            return(new TableVersionInfo(fieldInfos));
        }
예제 #11
0
        public ObjectTypeDescriptor(ITypeDescriptorCallbacks typeSerializers, AbstractBufferedReader reader, Func <AbstractBufferedReader, ITypeDescriptor> nestedDescriptorReader)
        {
            _typeSerializers = typeSerializers;
            Sealed           = false;
            _name            = reader.ReadString();
            var fieldCount = reader.ReadVUInt32();

            while (fieldCount-- > 0)
            {
                _fields.Add(new KeyValuePair <string, ITypeDescriptor>(reader.ReadString(), nestedDescriptorReader(reader)));
            }
        }
예제 #12
0
        public static RelationVersionInfo Load(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory, string relationName)
        {
            var pkCount     = reader.ReadVUInt32();
            var primaryKeys = new List <TableFieldInfo>((int)pkCount);

            for (var i = 0u; i < pkCount; i++)
            {
                primaryKeys.Add(TableFieldInfo.Load(reader, fieldHandlerFactory, relationName, FieldHandlerOptions.Orderable));
            }
            var skFieldCount       = reader.ReadVUInt32();
            var secondaryKeyFields = new TableFieldInfo[skFieldCount];

            for (var i = 0; i < skFieldCount; i++)
            {
                secondaryKeyFields[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, relationName,
                                                            FieldHandlerOptions.Orderable);
            }
            var skCount            = reader.ReadVUInt32();
            var secondaryKeys      = new Dictionary <uint, SecondaryKeyInfo>((int)skCount);
            var secondaryKeysNames = new Dictionary <string, uint>((int)skCount);

            for (var i = 0; i < skCount; i++)
            {
                var skIndex = reader.ReadVUInt32();
                var info    = new SecondaryKeyInfo();
                info.Index = reader.ReadVUInt32();
                info.Name  = reader.ReadString();
                var cnt = reader.ReadVUInt32();
                info.Fields = new List <FieldId>((int)cnt);
                for (var j = 0; j < cnt; j++)
                {
                    var fromPrimary = reader.ReadBool();
                    var index       = reader.ReadVUInt32();
                    info.Fields.Add(new FieldId(fromPrimary, index));
                }
                secondaryKeys.Add(skIndex, info);
                secondaryKeysNames.Add(info.Name, skIndex);
            }

            var fieldCount = reader.ReadVUInt32();
            var fieldInfos = new TableFieldInfo[fieldCount];

            for (int i = 0; i < fieldCount; i++)
            {
                fieldInfos[i] = TableFieldInfo.Load(reader, fieldHandlerFactory, relationName, FieldHandlerOptions.None);
            }

            return(new RelationVersionInfo(primaryKeys, secondaryKeys, secondaryKeysNames, fieldInfos));
        }
예제 #13
0
        public object LoadObject(AbstractBufferedReader reader)
        {
            var typeId = reader.ReadVUInt32();

            if (typeId == 0)
            {
                return(null);
            }
            if (typeId == 1)
            {
                throw new InvalidDataException("Backreference cannot be first object");
            }
            return(Load(typeId, reader, null));
        }
예제 #14
0
        ITypeDescriptor NestedDescriptorReader(AbstractBufferedReader reader)
        {
            var typeId = reader.ReadVUInt32();

            if (typeId < _id2DescriptorMap.Count)
            {
                var infoForType = _id2DescriptorMap[(int)typeId];
                if (infoForType != null)
                {
                    return(infoForType.Descriptor);
                }
            }
            return(new PlaceHolderDescriptor(typeId));
        }
예제 #15
0
        // ReSharper disable UnusedMember.Global
        public static IList <T> LoaderImpl <T>(AbstractBufferedReader reader, IDBObject owner) where T : class
        // ReSharper restore UnusedMember.Global
        {
            var count = reader.ReadVUInt32();

            if (count == 0)
            {
                return(null);
            }
            var oids = new List <ulong>((int)count);

            while (count-- > 0)
            {
                oids.Add(reader.ReadVUInt64());
            }
            return(new ListOfDBObject <T>(owner, oids));
        }
예제 #16
0
        public EnumTypeDescriptor(ITypeDescriptorCallbacks typeSerializers, AbstractBufferedReader reader)
        {
            _typeSerializers = typeSerializers;
            _name            = reader.ReadString();
            var header = reader.ReadVUInt32();

            _signed = (header & 1) != 0;
            _flags  = (header & 2) != 0;
            var count = header >> 2;

            _pairs = new List <KeyValuePair <string, ulong> >((int)count);
            for (int i = 0; i < count; i++)
            {
                _pairs.Add(_signed
                               ? new KeyValuePair <string, ulong>(reader.ReadString(), (ulong)reader.ReadVInt64())
                               : new KeyValuePair <string, ulong>(reader.ReadString(), reader.ReadVUInt64()));
            }
        }
예제 #17
0
파일: MethodInf.cs 프로젝트: keeema/bbcore
        public MethodInf(AbstractBufferedReader reader, IFieldHandlerFactory fieldHandlerFactory)
        {
            _name      = reader.ReadString();
            _ifaceName = reader.ReadString();
            var resultFieldHandlerName = reader.ReadString();

            if (resultFieldHandlerName != null)
            {
                _resultFieldHandler = fieldHandlerFactory.CreateFromName(resultFieldHandlerName, reader.ReadByteArray(), FieldHandlerOptions.None);
            }
            var parameterCount = reader.ReadVUInt32();

            _parameters = new ParameterInf[parameterCount];
            for (int i = 0; i < _parameters.Length; i++)
            {
                _parameters[i] = new ParameterInf(reader, fieldHandlerFactory);
            }
        }
예제 #18
0
        void IterateInlineList(AbstractBufferedReader reader, IFieldHandler itemHandler, bool skipping)
        {
            var skip  = skipping || _visitor != null && !_visitor.StartList();
            var count = reader.ReadVUInt32();

            while (count-- > 0)
            {
                var skipItem = skip || _visitor != null && !_visitor.StartItem();
                IterateHandler(reader, itemHandler, skipItem, null);
                if (!skipItem)
                {
                    _visitor?.EndItem();
                }
            }
            if (!skip)
            {
                _visitor?.EndList();
            }
        }
예제 #19
0
        public void LoadTypeDescriptors(AbstractBufferedReader reader)
        {
            var typeId      = reader.ReadVUInt32();
            var firstTypeId = typeId;

            while (typeId != 0)
            {
                if (typeId < firstTypeId)
                {
                    firstTypeId = typeId;
                }
                var             typeCategory = (TypeCategory)reader.ReadUInt8();
                ITypeDescriptor descriptor;
                switch (typeCategory)
                {
                case TypeCategory.BuildIn:
                    throw new ArgumentOutOfRangeException();

                case TypeCategory.Class:
                    descriptor = new ObjectTypeDescriptor(_typeSerializers, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.List:
                    descriptor = new ListTypeDescriptor(_typeSerializers, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Dictionary:
                    descriptor = new DictionaryTypeDescriptor(_typeSerializers, reader, NestedDescriptorReader);
                    break;

                case TypeCategory.Enum:
                    descriptor = new EnumTypeDescriptor(_typeSerializers, reader);
                    break;

                case TypeCategory.Nullable:
                    descriptor = new NullableTypeDescriptor(_typeSerializers, reader, NestedDescriptorReader);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                while (typeId >= _id2DescriptorMap.Count)
                {
                    _id2DescriptorMap.Add(null);
                }
                if (_id2DescriptorMap[(int)typeId] == null)
                {
                    _id2DescriptorMap[(int)typeId] = new InfoForType {
                        Id = (int)typeId, Descriptor = descriptor
                    }
                }
                ;
                typeId = reader.ReadVUInt32();
            }
            for (var i = firstTypeId; i < _id2DescriptorMap.Count; i++)
            {
                _id2DescriptorMap[(int)i].Descriptor.MapNestedTypes(d =>
                {
                    var placeHolderDescriptor = d as PlaceHolderDescriptor;
                    return(placeHolderDescriptor != null ? _id2DescriptorMap[(int)placeHolderDescriptor.TypeId].Descriptor : d);
                });
            }
            // This additional cycle is needed to fill names of recursive structures
            for (var i = firstTypeId; i < _id2DescriptorMap.Count; i++)
            {
                _id2DescriptorMap[(int)i].Descriptor.MapNestedTypes(d => d);
            }
            for (var i = firstTypeId; i < _id2DescriptorMap.Count; i++)
            {
                var infoForType = _id2DescriptorMap[(int)i];
                var descriptor  = _typeSerializers.MergeDescriptor(infoForType.Descriptor);
                infoForType.Descriptor             = descriptor;
                _typeOrDescriptor2Info[descriptor] = infoForType;
            }
        }

        ITypeDescriptor NestedDescriptorReader(AbstractBufferedReader reader)
        {
            var typeId = reader.ReadVUInt32();

            if (typeId < _id2DescriptorMap.Count)
            {
                var infoForType = _id2DescriptorMap[(int)typeId];
                if (infoForType != null)
                {
                    return(infoForType.Descriptor);
                }
            }
            return(new PlaceHolderDescriptor(typeId));
        }
예제 #20
0
 public FileHashIndex(AbstractBufferedReader reader)
 {
     _generation    = reader.ReadVInt64();
     _keySize       = (int)reader.ReadVUInt32();
     _keyValueCount = (long)reader.ReadVUInt64();
 }
예제 #21
0
 void IterateHandler(AbstractBufferedReader reader, IFieldHandler handler, bool skipping, HashSet <int> knownInlineRefs)
 {
     if (handler is ODBDictionaryFieldHandler)
     {
         var dictId = reader.ReadVUInt64();
         if (!skipping)
         {
             var kvHandlers = ((IFieldHandlerWithNestedFieldHandlers)handler).EnumerateNestedFieldHandlers().ToArray();
             IterateDict(dictId, kvHandlers[0], kvHandlers[1]);
         }
     }
     else if (handler is DBObjectFieldHandler)
     {
         var oid = reader.ReadVInt64();
         if (oid == 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference(0);
             }
         }
         else if (oid <= int.MinValue || oid > 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference((ulong)oid);
                 IterateOid((ulong)oid);
             }
         }
         else
         {
             if (knownInlineRefs != null)
             {
                 if (knownInlineRefs.Contains((int)oid))
                 {
                     if (!skipping)
                     {
                         _visitor?.InlineBackRef((int)oid);
                     }
                     return;
                 }
                 if (!skipping)
                 {
                     _visitor?.InlineRef((int)oid);
                 }
                 knownInlineRefs.Add((int)oid);
             }
             var tableId = reader.ReadVUInt32();
             var version = reader.ReadVUInt32();
             if (!skipping)
             {
                 MarkTableIdVersionFieldInfo(tableId, version);
             }
             string tableName;
             var    skip = skipping ||
                           _visitor != null && !_visitor.StartInlineObject(tableId,
                                                                           _tableId2Name.TryGetValue(tableId, out tableName) ? tableName : null, version);
             var tvi = GetTableVersionInfo(tableId, version);
             for (var i = 0; i < tvi.FieldCount; i++)
             {
                 var fi        = tvi[i];
                 var skipField = skip || _visitor != null && !_visitor.StartField(fi.Name);
                 IterateHandler(reader, fi.Handler, skipField, new HashSet <int>());
                 if (!skipField)
                 {
                     _visitor?.EndField();
                 }
             }
             if (!skip)
             {
                 _visitor?.EndInlineObject();
             }
         }
     }
     else if (handler is ListFieldHandler)
     {
         var oid = reader.ReadVInt64();
         if (oid == 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference(0);
             }
         }
         else if (oid <= int.MinValue || oid > 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference((ulong)oid);
                 IterateOid((ulong)oid);
             }
         }
         else
         {
             var itemHandler = ((IFieldHandlerWithNestedFieldHandlers)handler).EnumerateNestedFieldHandlers().First();
             IterateInlineList(reader, itemHandler, skipping);
         }
     }
     else if (handler is DictionaryFieldHandler)
     {
         var oid = reader.ReadVInt64();
         if (oid == 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference(0);
             }
         }
         else if (oid <= int.MinValue || oid > 0)
         {
             if (!skipping)
             {
                 _visitor?.OidReference((ulong)oid);
                 IterateOid((ulong)oid);
             }
         }
         else
         {
             var kvHandlers = ((IFieldHandlerWithNestedFieldHandlers)handler).EnumerateNestedFieldHandlers().ToArray();
             IterateInlineDict(reader, kvHandlers[0], kvHandlers[1], skipping);
         }
     }
     else if (handler is NullableFieldHandler)
     {
         var hasValue = reader.ReadBool();
         if (hasValue)
         {
             var itemHandler = ((IFieldHandlerWithNestedFieldHandlers)handler).EnumerateNestedFieldHandlers().First();
             IterateHandler(reader, itemHandler, skipping, null);
         }
     }
     else if (handler.NeedsCtx() || handler.HandledType() == null)
     {
         throw new BTDBException("Don't know how to iterate " + handler.Name);
     }
     else
     {
         if (skipping || _visitor == null)
         {
             Action <AbstractBufferedReader> skipper;
             if (!_skippers.TryGetValue(handler, out skipper))
             {
                 var meth =
                     ILBuilder.Instance.NewMethod <Action <AbstractBufferedReader> >("Skip" + handler.Name);
                 var il = meth.Generator;
                 handler.Skip(il, il2 => il2.Ldarg(0));
                 il.Ret();
                 skipper = meth.Create();
                 _skippers.Add(handler, skipper);
             }
             skipper(reader);
         }
         else
         {
             Func <AbstractBufferedReader, object> loader;
             if (!_loaders.TryGetValue(handler, out loader))
             {
                 var meth =
                     ILBuilder.Instance.NewMethod <Func <AbstractBufferedReader, object> >("Load" + handler.Name);
                 var il = meth.Generator;
                 handler.Load(il, il2 => il2.Ldarg(0));
                 il.Box(handler.HandledType()).Ret();
                 loader = meth.Create();
                 _loaders.Add(handler, loader);
             }
             var obj = loader(reader);
             if (_visitor.NeedScalarAsObject())
             {
                 _visitor.ScalarAsObject(obj);
             }
             if (_visitor.NeedScalarAsText())
             {
                 _visitor.ScalarAsText(obj == null
                     ? "null"
                     : string.Format(CultureInfo.InvariantCulture, "{0}", obj));
             }
         }
     }
 }
예제 #22
0
        public void Replay()
        {
            while (!_reader.Eof)
            {
                var operation = (KVReplayOperation)_reader.ReadUInt8();
                Console.WriteLine(operation);
                uint tri;
                IKeyValueDBTransaction tr;
                int    valOfs;
                int    valLen;
                byte[] valBuf;
                int    keyLen;
                int    keyOfs;
                byte[] keyBuf;
                switch (operation)
                {
                case KVReplayOperation.Open:
                    var initialStreamSize = _reader.ReadVUInt64();
                    _dbstream = new MemoryPositionLessStream();
                    var   buf = new byte[4096];
                    ulong pos = 0;
                    while (pos < initialStreamSize)
                    {
                        var r = (int)Math.Min((ulong)buf.Length, initialStreamSize - pos);
                        _reader.ReadBlock(buf, 0, r);
                        _dbstream.Write(buf, 0, r, pos);
                        pos += (ulong)r;
                    }
                    _db.Open(_dbstream, true);
                    break;

                case KVReplayOperation.KeyValueDBDispose:
                    _db.Dispose();
                    break;

                case KVReplayOperation.StartTransaction:
                    tr        = _db.StartTransaction();
                    tri       = _reader.ReadVUInt32();
                    _trs[tri] = tr;
                    break;

                case KVReplayOperation.StartWritingTransaction:
                    tr        = _db.StartWritingTransaction().Result;
                    tri       = _reader.ReadVUInt32();
                    _trs[tri] = tr;
                    break;

                case KVReplayOperation.CalculateStats:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.CalculateStats();
                    break;

                case KVReplayOperation.SetKeyPrefix:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    int prefixLen = _reader.ReadVInt32();
                    int prefixOfs = _reader.ReadVInt32();
                    var prefixBuf = new byte[prefixOfs + prefixLen];
                    _reader.ReadBlock(prefixBuf, prefixOfs, prefixLen);
                    tr.SetKeyPrefix(prefixBuf, prefixOfs, prefixLen);
                    break;

                case KVReplayOperation.FindKey:
                    tri    = _reader.ReadVUInt32();
                    tr     = _trs[tri];
                    keyLen = _reader.ReadVInt32();
                    keyOfs = _reader.ReadVInt32();
                    keyBuf = new byte[keyOfs + keyLen];
                    _reader.ReadBlock(keyBuf, keyOfs, keyLen);
                    var strategy = (FindKeyStrategy)_reader.ReadVUInt32();
                    tr.FindKey(keyBuf, keyOfs, keyLen, strategy);
                    break;

                case KVReplayOperation.GetKeyIndex:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.GetKeyIndex();
                    break;

                case KVReplayOperation.SetValue:
                    tri    = _reader.ReadVUInt32();
                    tr     = _trs[tri];
                    valOfs = _reader.ReadVInt32();
                    valLen = _reader.ReadVInt32();
                    valBuf = new byte[valOfs + valLen];
                    _reader.ReadBlock(valBuf, valOfs, valLen);
                    tr.SetValue(valBuf, valOfs, valLen);
                    break;

                case KVReplayOperation.SetValueSize:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    var valueSize = _reader.ReadVInt64();
                    tr.SetValueSize(valueSize);
                    break;

                case KVReplayOperation.WriteValue:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    var ofs = _reader.ReadVInt64();
                    valOfs = _reader.ReadVInt32();
                    valLen = _reader.ReadVInt32();
                    valBuf = new byte[valOfs + valLen];
                    _reader.ReadBlock(valBuf, valOfs, valLen);
                    tr.WriteValue(ofs, valLen, valBuf, valOfs);
                    break;

                case KVReplayOperation.CreateOrUpdateKeyValue:
                    tri    = _reader.ReadVUInt32();
                    tr     = _trs[tri];
                    keyLen = _reader.ReadVInt32();
                    keyOfs = _reader.ReadVInt32();
                    keyBuf = new byte[keyOfs + keyLen];
                    _reader.ReadBlock(keyBuf, keyOfs, keyLen);
                    valLen = _reader.ReadVInt32();
                    valOfs = _reader.ReadVInt32();
                    valBuf = new byte[valOfs + valLen];
                    _reader.ReadBlock(valBuf, valOfs, valLen);
                    tr.CreateOrUpdateKeyValue(keyBuf, keyOfs, keyLen, valBuf, valOfs, valLen);
                    break;

                case KVReplayOperation.Commit:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.Commit();
                    break;

                case KVReplayOperation.TransactionDispose:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.Dispose();
                    _trs.Remove(tri);
                    break;

                case KVReplayOperation.EraseCurrent:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.EraseCurrent();
                    break;

                case KVReplayOperation.EraseAll:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.EraseAll();
                    break;

                case KVReplayOperation.FindFirstKey:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.FindFirstKey();
                    break;

                case KVReplayOperation.FindPreviousKey:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.FindPreviousKey();
                    break;

                case KVReplayOperation.FindNextKey:
                    tri = _reader.ReadVUInt32();
                    tr  = _trs[tri];
                    tr.FindNextKey();
                    break;

                default:
                    Console.WriteLine(string.Format("Unimplemented operation {0}({1})", operation, (byte)operation));
                    throw new NotSupportedException(string.Format("Unimplemented operation {0}({1})", operation, (byte)operation));
                }
            }
            Console.WriteLine("Finish");
        }