private void ReadInstallSnapshotAndIgnoreContent(CancellationToken token) { var reader = _connection.CreateReader(); while (true) { token.ThrowIfCancellationRequested(); var type = reader.ReadInt32(); if (type == -1) { return; } int size; long entries; switch ((RootObjectType)type) { case RootObjectType.None: return; case RootObjectType.VariableSizeTree: size = reader.ReadInt32(); reader.ReadExactly(size); entries = reader.ReadInt64(); for (long i = 0; i < entries; i++) { token.ThrowIfCancellationRequested(); size = reader.ReadInt32(); reader.ReadExactly(size); size = reader.ReadInt32(); reader.ReadExactly(size); } break; case RootObjectType.Table: size = reader.ReadInt32(); reader.ReadExactly(size); entries = reader.ReadInt64(); for (long i = 0; i < entries; i++) { token.ThrowIfCancellationRequested(); size = reader.ReadInt32(); reader.ReadExactly(size); } break; default: throw new ArgumentOutOfRangeException(nameof(type), type.ToString()); } } }
private unsafe bool InstallSnapshot(TransactionOperationContext context) { var txw = context.Transaction.InnerTransaction; var sp = Stopwatch.StartNew(); var reader = _connection.CreateReader(); while (true) { var type = reader.ReadInt32(); if (type == -1) { return(false); } int size; long entries; switch ((RootObjectType)type) { case RootObjectType.None: return(true); case RootObjectType.VariableSizeTree: size = reader.ReadInt32(); reader.ReadExactly(size); Slice treeName; // will be freed on context close Slice.From(context.Allocator, reader.Buffer, 0, size, ByteStringType.Immutable, out treeName); txw.DeleteTree(treeName); var tree = txw.CreateTree(treeName); entries = reader.ReadInt64(); for (long i = 0; i < entries; i++) { MaybeNotifyLeaderThatWeAreStillAlive(context, sp); size = reader.ReadInt32(); reader.ReadExactly(size); using (Slice.From(context.Allocator, reader.Buffer, 0, size, ByteStringType.Immutable, out Slice valKey)) { size = reader.ReadInt32(); reader.ReadExactly(size); using (tree.DirectAdd(valKey, size, out byte *ptr)) { fixed(byte *pBuffer = reader.Buffer) { Memory.Copy(ptr, pBuffer, size); } } } } break; case RootObjectType.Table: size = reader.ReadInt32(); reader.ReadExactly(size); Slice tableName; // will be freed on context close Slice.From(context.Allocator, reader.Buffer, 0, size, ByteStringType.Immutable, out tableName); var tableTree = txw.ReadTree(tableName, RootObjectType.Table); // Get the table schema var schemaSize = tableTree.GetDataSize(TableSchema.SchemasSlice); var schemaPtr = tableTree.DirectRead(TableSchema.SchemasSlice); if (schemaPtr == null) { throw new InvalidOperationException( "When trying to install snapshot, found missing table " + tableName); } var schema = TableSchema.ReadFrom(txw.Allocator, schemaPtr, schemaSize); var table = txw.OpenTable(schema, tableName); // delete the table TableValueReader tvr; while (true) { if (table.SeekOnePrimaryKey(Slices.AfterAllKeys, out tvr) == false) { break; } table.Delete(tvr.Id); MaybeNotifyLeaderThatWeAreStillAlive(context, sp); } entries = reader.ReadInt64(); for (long i = 0; i < entries; i++) { MaybeNotifyLeaderThatWeAreStillAlive(context, sp); size = reader.ReadInt32(); reader.ReadExactly(size); fixed(byte *pBuffer = reader.Buffer) { tvr = new TableValueReader(pBuffer, size); table.Insert(ref tvr); } } break; default: throw new ArgumentOutOfRangeException(nameof(type), type.ToString()); } } }