internal void Load(LogReader reader) { //_resultCache = new Dictionary<byte[], ResultCacheEntry>(); _resultCache = new Dictionary <byte[], ResultCacheEntry>(new ByteArrayComparer()); while (true) { Record record = reader.ReadRecord(); if (record.LogRecordType == LogRecordType.Eof) { if (Log.IsDebugEnabled) { Log.Debug($"Reached end of records: {record.ToString()}"); } break; } if (record.LogRecordType != LogRecordType.Full) { throw new Exception($"Invalid log file. Didn't find any records. Got record of type {record.LogRecordType}"); } if (record.Length != (ulong)record.Data.Length) { throw new Exception($"Invalid record state. Length not matching"); } var entries = DecodeBatch(record.Data); foreach (var entry in entries) { //_resultCache.TryAdd(entry.Key, entry.Value); _resultCache[entry.Key] = entry.Value; } } _resultCache = _resultCache.OrderByDescending(kvp => kvp.Value.Sequence).ToDictionary(k => k.Key, k => k.Value); }
public VersionEdit ReadVersionEdit(LogReader logReader) { string comparator = null; ulong? logNumber = null; ulong? previousLogNumber = null; ulong? nextFileNumber = null; ulong? lastSequenceNumber = null; VersionEdit finalVersion = new VersionEdit(); while (true) { Record record = logReader.ReadRecord(); if (record.LogRecordType != LogRecordType.Full) { break; } var reader = new SpanReader(record.Data); VersionEdit versionEdit = new VersionEdit(); while (!reader.Eof) { LogTagType logTag = (LogTagType)reader.ReadVarLong(); switch (logTag) { case LogTagType.Comparator: { versionEdit.Comparator = reader.ReadLengthPrefixedString(); break; } case LogTagType.LogNumber: { versionEdit.LogNumber = reader.ReadVarLong(); break; } case LogTagType.NextFileNumber: { versionEdit.NextFileNumber = reader.ReadVarLong(); break; } case LogTagType.LastSequence: { versionEdit.LastSequenceNumber = reader.ReadVarLong(); break; } case LogTagType.CompactPointer: { int level = (int)reader.ReadVarLong(); var internalKey = reader.ReadLengthPrefixedBytes(); versionEdit.CompactPointers[level] = internalKey.ToArray(); break; } case LogTagType.DeletedFile: { int level = (int)reader.ReadVarLong(); ulong fileNumber = reader.ReadVarLong(); if (!versionEdit.DeletedFiles.ContainsKey(level)) { versionEdit.DeletedFiles[level] = new List <ulong>(); } versionEdit.DeletedFiles[level].Add(fileNumber); if (!finalVersion.DeletedFiles.ContainsKey(level)) { finalVersion.DeletedFiles[level] = new List <ulong>(); } finalVersion.DeletedFiles[level].Add(fileNumber); break; } case LogTagType.NewFile: { int level = (int)reader.ReadVarLong(); ulong fileNumber = reader.ReadVarLong(); ulong fileSize = reader.ReadVarLong(); var smallest = reader.ReadLengthPrefixedBytes(); var largest = reader.ReadLengthPrefixedBytes(); FileMetadata fileMetadata = new FileMetadata(); fileMetadata.FileNumber = fileNumber; fileMetadata.FileSize = fileSize; fileMetadata.SmallestKey = smallest.ToArray(); fileMetadata.LargestKey = largest.ToArray(); if (!versionEdit.NewFiles.ContainsKey(level)) { versionEdit.NewFiles[level] = new List <FileMetadata>(); } versionEdit.NewFiles[level].Add(fileMetadata); if (!finalVersion.NewFiles.ContainsKey(level)) { finalVersion.NewFiles[level] = new List <FileMetadata>(); } finalVersion.NewFiles[level].Add(fileMetadata); break; } case LogTagType.PrevLogNumber: { versionEdit.PreviousLogNumber = reader.ReadVarLong(); break; } default: { throw new ArgumentOutOfRangeException($"Unknown tag={logTag}"); } } } versionEdit.CompactPointers = versionEdit.CompactPointers.Count == 0 ? null : versionEdit.CompactPointers; versionEdit.DeletedFiles = versionEdit.DeletedFiles.Count == 0 ? null : versionEdit.DeletedFiles; versionEdit.NewFiles = versionEdit.NewFiles.Count == 0 ? null : versionEdit.NewFiles; comparator = versionEdit.Comparator ?? comparator; logNumber = versionEdit.LogNumber ?? logNumber; previousLogNumber = versionEdit.PreviousLogNumber ?? previousLogNumber; nextFileNumber = versionEdit.NextFileNumber ?? nextFileNumber; lastSequenceNumber = versionEdit.LastSequenceNumber ?? lastSequenceNumber; } // Clean files List <ulong> deletedFiles = new List <ulong>(); foreach (var versionDeletedFile in finalVersion.DeletedFiles.Values) { deletedFiles.AddRange(versionDeletedFile); } foreach (var levelKvp in finalVersion.NewFiles) { foreach (var newFile in levelKvp.Value.ToArray()) { if (deletedFiles.Contains(newFile.FileNumber)) { levelKvp.Value.Remove(newFile); } } } finalVersion.NewFiles = finalVersion.NewFiles.OrderBy(kvp => kvp.Key).ToDictionary(pair => pair.Key, pair => pair.Value); finalVersion.Comparator = comparator; finalVersion.LogNumber = logNumber; finalVersion.PreviousLogNumber = previousLogNumber; finalVersion.NextFileNumber = nextFileNumber; finalVersion.LastSequenceNumber = lastSequenceNumber; return(finalVersion); }