void LoadContent() { SpanReader reader; foreach (var collectionFile in _fileCollection.Enumerate()) { reader = new SpanReader(collectionFile.GetExclusiveReader()); if (!reader.CheckMagic(MagicStartOfFile)) { continue; // Don't touch files alien files } var fileType = (DiskChunkFileType)reader.ReadUInt8(); var fileInfo = fileType switch { DiskChunkFileType.HashIndex => new FileHashIndex(ref reader), DiskChunkFileType.PureValues => new FilePureValues(ref reader), _ => UnknownFile.Instance }; if (_fileGeneration < fileInfo.Generation) { _fileGeneration = fileInfo.Generation; } _fileInfos.TryAdd(collectionFile.Index, fileInfo); } var hashFilePair = _fileInfos.Where(f => f.Value.FileType == DiskChunkFileType.HashIndex).OrderByDescending( f => f.Value.Generation).FirstOrDefault(); if (hashFilePair.Value == null) { return; } reader = new SpanReader(_fileCollection.GetFile(hashFilePair.Key).GetExclusiveReader()); FileHashIndex.SkipHeader(ref reader); if (((FileHashIndex)hashFilePair.Value).KeySize != _keySize) { return; } var keyBuf = ByteBuffer.NewSync(new byte[_keySize]); while (true) { var cacheValue = new CacheValue(); cacheValue.FileOfs = reader.ReadVUInt32(); if (cacheValue.FileOfs == 0) { break; } cacheValue.FileId = reader.ReadVUInt32(); cacheValue.AccessRate = reader.ReadVUInt32(); cacheValue.ContentLength = reader.ReadVUInt32(); reader.ReadBlock(keyBuf); _cache.TryAdd(new ByteStructs.Key20(keyBuf), cacheValue); } }
void LoadHashKeyIndex(uint hashKeyIndexFileId) { var reader = new SpanReader(_fileCollection.GetFile(hashKeyIndexFileId).GetExclusiveReader()); _keyLen = (int)((IHashKeyIndex)_fileCollection.FileInfoByIdx(hashKeyIndexFileId)).KeyLen; HashKeyIndex.SkipHeader(ref reader); var keyBuf = ByteBuffer.NewSync(new byte[_keyLen]); while (!reader.Eof) { var value = new StorageValue(); value.FileId = reader.ReadVUInt32(); value.FileOfs = reader.ReadVUInt32(); value.ContentLengthCompressedIsLeaf = reader.ReadVUInt32(); reader.ReadBlock(keyBuf); _dict20.TryAdd(new ByteStructs.Key20(keyBuf), value); } }
public void Iterate(ITrlVisitor visitor) { bool afterTemporaryEnd = false; Span <byte> trueValue = stackalloc byte[12]; var reader = new SpanReader(_readerController); SkipUntilNextTransaction(ref reader); while (!reader.Eof) { var command = (KVCommandType)reader.ReadUInt8(); if (command == 0 && afterTemporaryEnd) { return; } afterTemporaryEnd = false; visitor.StartOperation(command & KVCommandType.CommandMask); switch (command & KVCommandType.CommandMask) { case KVCommandType.CreateOrUpdateDeprecated: case KVCommandType.CreateOrUpdate: { 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); } trueValue.Clear(); if (valueLen <= MaxValueSizeInlineInMemory && (command & KVCommandType.SecondParamCompressed) == 0) { reader.ReadBlock(ref MemoryMarshal.GetReference(trueValue), (uint)valueLen); } else { var partLen = Math.Min(12, valueLen); reader.ReadBlock(ref MemoryMarshal.GetReference(trueValue), (uint)partLen); reader.SkipBlock(valueLen - partLen); } ExplainCreateOrUpdate(visitor, keyBuf.AsSyncReadOnlySpan(), valueLen, trueValue); } break; case KVCommandType.EraseOne: { var keyLen = reader.ReadVInt32(); reader.SkipBlock(keyLen); } break; case KVCommandType.EraseRange: { var keyLen1 = reader.ReadVInt32(); var keyLen2 = reader.ReadVInt32(); reader.SkipBlock(keyLen1); reader.SkipBlock(keyLen2); } break; case KVCommandType.DeltaUlongs: { reader.SkipVUInt32(); reader.SkipVUInt64(); } break; case KVCommandType.TransactionStart: if (!reader.CheckMagic(MagicStartOfTransaction)) { throw new Exception("Invalid transaction magic"); } visitor.OperationDetail($"file pos: {_readerController.GetCurrentPosition(reader)}"); break; case KVCommandType.CommitWithDeltaUlong: var delta = reader.ReadVUInt64(); visitor.OperationDetail($"delta: {delta}"); break; case KVCommandType.EndOfFile: visitor.OperationDetail($"position: {reader!.Controller!.GetCurrentPosition(reader)}"); return; case KVCommandType.TemporaryEndOfFile: afterTemporaryEnd = true; break; } visitor.EndOperation(); } }