Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }