public void EraseCurrent() { EnsureValidKey(); var keyIndex = _keyIndex; MakeWritable(); InvalidateCurrentKey(); _prefixKeyCount--; BtreeRoot.EraseRange(keyIndex, keyIndex); }
public void EraseCurrent() { EnsureValidKey(); var keyIndex = _keyIndex; MakeWrittable(); InvalidateCurrentKey(); _prefixKeyCount--; BtreeRoot.FillStackByIndex(_stack, keyIndex); _keyValueDB.WriteEraseOneCommand(GetCurrentKeyFromStack()); BtreeRoot.EraseRange(keyIndex, keyIndex); }
public void EraseRange(long firstKeyIndex, long lastKeyIndex) { if (firstKeyIndex < 0) { firstKeyIndex = 0; } if (lastKeyIndex >= GetKeyValueCount()) { lastKeyIndex = _prefixKeyCount - 1; } if (lastKeyIndex < firstKeyIndex) { return; } MakeWrittable(); firstKeyIndex += _prefixKeyStart; lastKeyIndex += _prefixKeyStart; InvalidateCurrentKey(); _prefixKeyCount -= lastKeyIndex - firstKeyIndex + 1; BtreeRoot.FillStackByIndex(_stack, firstKeyIndex); if (firstKeyIndex == lastKeyIndex) { _keyValueDB.WriteEraseOneCommand(GetCurrentKeyFromStack()); } else { var firstKey = GetCurrentKeyFromStack(); BtreeRoot.FillStackByIndex(_stack, lastKeyIndex); _keyValueDB.WriteEraseRangeCommand(firstKey, GetCurrentKeyFromStack()); } BtreeRoot.EraseRange(firstKeyIndex, lastKeyIndex); }
public void EraseRange(long firstKeyIndex, long lastKeyIndex) { if (firstKeyIndex < 0) { firstKeyIndex = 0; } if (lastKeyIndex >= GetKeyValueCount()) { lastKeyIndex = _prefixKeyCount - 1; } if (lastKeyIndex < firstKeyIndex) { return; } MakeWrittable(); firstKeyIndex += _prefixKeyStart; lastKeyIndex += _prefixKeyStart; InvalidateCurrentKey(); _prefixKeyCount -= lastKeyIndex - firstKeyIndex + 1; BtreeRoot.EraseRange(firstKeyIndex, lastKeyIndex); }
// Return true if it is suitable for continuing writing new transactions bool LoadTransactionLog(uint fileId, uint logOffset) { var inlineValueBuf = new byte[MaxValueSizeInlineInMemory]; var stack = new List <NodeIdxPair>(); var collectionFile = FileCollection.GetFile(fileId); var reader = collectionFile.GetExclusiveReader(); try { if (logOffset == 0) { FileTransactionLog.SkipHeader(reader); } else { reader.SkipBlock(logOffset); } if (reader.Eof) { return(true); } var afterTemporaryEnd = false; while (!reader.Eof) { var command = (KVCommandType)reader.ReadUInt8(); if (command == 0 && afterTemporaryEnd) { collectionFile.SetSize(reader.GetCurrentPosition() - 1); return(true); } afterTemporaryEnd = false; switch (command & KVCommandType.CommandMask) { case KVCommandType.CreateOrUpdateDeprecated: case KVCommandType.CreateOrUpdate: { if (_nextRoot == null) { return(false); } var keyLen = reader.ReadVInt32(); var valueLen = reader.ReadVInt32(); var key = new byte[keyLen]; reader.ReadBlock(key); var keyBuf = ByteBuffer.NewAsync(key); if ((command & KVCommandType.FirstParamCompressed) != 0) { _compression.DecompressKey(ref keyBuf); } var ctx = new CreateOrUpdateCtx { KeyPrefix = BitArrayManipulation.EmptyByteArray, Key = keyBuf, ValueFileId = fileId, ValueOfs = (uint)reader.GetCurrentPosition(), ValueSize = (command & KVCommandType.SecondParamCompressed) != 0 ? -valueLen : valueLen }; if (valueLen <= MaxValueSizeInlineInMemory && (command & KVCommandType.SecondParamCompressed) == 0) { reader.ReadBlock(inlineValueBuf, 0, valueLen); StoreValueInlineInMemory(ByteBuffer.NewSync(inlineValueBuf, 0, valueLen), out ctx.ValueOfs, out ctx.ValueSize); ctx.ValueFileId = 0; } else { reader.SkipBlock(valueLen); } _nextRoot.CreateOrUpdate(ctx); } break; case KVCommandType.EraseOne: { if (_nextRoot == null) { return(false); } var keyLen = reader.ReadVInt32(); var key = new byte[keyLen]; reader.ReadBlock(key); var keyBuf = ByteBuffer.NewAsync(key); if ((command & KVCommandType.FirstParamCompressed) != 0) { _compression.DecompressKey(ref keyBuf); } long keyIndex; var findResult = _nextRoot.FindKey(stack, out keyIndex, BitArrayManipulation.EmptyByteArray, keyBuf); if (findResult == FindResult.Exact) { _nextRoot.EraseRange(keyIndex, keyIndex); } } break; case KVCommandType.EraseRange: { if (_nextRoot == null) { return(false); } var keyLen1 = reader.ReadVInt32(); var keyLen2 = reader.ReadVInt32(); var key = new byte[keyLen1]; reader.ReadBlock(key); var keyBuf = ByteBuffer.NewAsync(key); if ((command & KVCommandType.FirstParamCompressed) != 0) { _compression.DecompressKey(ref keyBuf); } long keyIndex1; var findResult = _nextRoot.FindKey(stack, out keyIndex1, BitArrayManipulation.EmptyByteArray, keyBuf); if (findResult == FindResult.Previous) { keyIndex1++; } key = new byte[keyLen2]; reader.ReadBlock(key); keyBuf = ByteBuffer.NewAsync(key); if ((command & KVCommandType.SecondParamCompressed) != 0) { _compression.DecompressKey(ref keyBuf); } long keyIndex2; findResult = _nextRoot.FindKey(stack, out keyIndex2, BitArrayManipulation.EmptyByteArray, keyBuf); if (findResult == FindResult.Next) { keyIndex2--; } _nextRoot.EraseRange(keyIndex1, keyIndex2); } break; case KVCommandType.TransactionStart: if (!reader.CheckMagic(MagicStartOfTransaction)) { return(false); } _nextRoot = LastCommited.NewTransactionRoot(); break; case KVCommandType.CommitWithDeltaUlong: unchecked // overflow is expected in case commitUlong is decreasing but that should be rare { _nextRoot.CommitUlong += reader.ReadVUInt64(); } goto case KVCommandType.Commit; case KVCommandType.Commit: _nextRoot.TrLogFileId = fileId; _nextRoot.TrLogOffset = (uint)reader.GetCurrentPosition(); _lastCommited = _nextRoot; _nextRoot = null; break; case KVCommandType.Rollback: _nextRoot = null; break; case KVCommandType.EndOfFile: return(false); case KVCommandType.TemporaryEndOfFile: _lastCommited.TrLogFileId = fileId; _lastCommited.TrLogOffset = (uint)reader.GetCurrentPosition(); afterTemporaryEnd = true; break; default: _nextRoot = null; return(false); } } return(afterTemporaryEnd); } catch (EndOfStreamException) { _nextRoot = null; return(false); } }