internal void Load(LogReader reader) { _resultCache = new Dictionary <byte[], ResultCacheEntry>(new ByteArrayComparer()); int entriesCount = 0; while (true) { ReadOnlySpan <byte> data = reader.ReadData(); if (reader.Eof) { if (Log.IsDebugEnabled) { Log.Debug($"Reached end of stream. No more records to read."); } break; } var entries = DecodeBatch(data); entriesCount += entries.Count; foreach (KeyValuePair <byte[], ResultCacheEntry> entry in entries.OrderBy(kvp => kvp.Value.Sequence)) { // This should overwrite older entries and only the latest operation should be saved _resultCache[entry.Key] = entry.Value; _estimatedSize += (ulong)(entry.Key.Length + 8 + entry.Key.Length + 10 /* varlong * 2 */); } } Log.Debug($"Total count of entries read: {entriesCount}"); Log.Debug($"Total count after filtering entries: {_resultCache.Count}"); }
public static Version ReadVersionEdit(LogReader logReader) { var version = new Version(); while (true) { ReadOnlySpan <byte> data = logReader.ReadData(); if (logReader.Eof) { break; } var reader = new SpanReader(data); //var versionEdit = new VersionEdit(); while (!reader.Eof) { var logTag = (LogTagType)reader.ReadVarLong(); switch (logTag) { case LogTagType.Comparator: { version.Comparator = reader.ReadLengthPrefixedString(); break; } case LogTagType.LogNumber: { version.LogNumber = reader.ReadVarLong(); break; } case LogTagType.NextFileNumber: { version.NextFileNumber = reader.ReadVarLong(); break; } case LogTagType.LastSequence: { version.LastSequenceNumber = reader.ReadVarLong(); break; } case LogTagType.CompactPointer: { int level = (int)reader.ReadVarLong(); var internalKey = reader.ReadLengthPrefixedBytes(); version.CompactPointers[level] = internalKey.ToArray(); break; } case LogTagType.DeletedFile: { int level = (int)reader.ReadVarLong(); ulong fileNumber = reader.ReadVarLong(); if (!version.DeletedFiles.ContainsKey(level)) { version.DeletedFiles[level] = new List <ulong>(); } version.DeletedFiles[level].Add(fileNumber); break; } case LogTagType.NewFile: { int level = (int)reader.ReadVarLong(); ulong fileNumber = reader.ReadVarLong(); ulong fileSize = reader.ReadVarLong(); ReadOnlySpan <byte> smallest = reader.ReadLengthPrefixedBytes(); ReadOnlySpan <byte> largest = reader.ReadLengthPrefixedBytes(); var fileMetadata = new FileMetadata(); fileMetadata.FileNumber = fileNumber; fileMetadata.FileSize = fileSize; fileMetadata.SmallestKey = smallest.ToArray(); fileMetadata.LargestKey = largest.ToArray(); if (!version.Levels.ContainsKey(level)) { version.Levels[level] = new List <FileMetadata>(); } version.Levels[level].Add(fileMetadata); break; } case LogTagType.PrevLogNumber: { version.PreviousLogNumber = reader.ReadVarLong(); break; } default: { throw new ArgumentOutOfRangeException($"Unknown tag={logTag}"); } } } } // Clean files var deletedFiles = new List <ulong>(); foreach (List <ulong> versionDeletedFile in version.DeletedFiles.Values) { deletedFiles.AddRange(versionDeletedFile); } foreach (KeyValuePair <int, List <FileMetadata> > levelKvp in version.Levels) { foreach (FileMetadata newFile in levelKvp.Value.ToArray()) { if (deletedFiles.Contains(newFile.FileNumber)) { levelKvp.Value.Remove(newFile); } } } version.Levels = version.Levels.OrderBy(kvp => kvp.Key).ToDictionary(pair => pair.Key, pair => pair.Value); version.Comparator ??= "leveldb.BytewiseComparator"; return(version); }