internal bool Seek(Span <byte> key)
        {
            if (_restartCount == 0)
            {
                return(false);
            }

            // binary search for key

            int left  = 0;
            int right = _restartCount - 1;

            while (left < right)
            {
                int mid = (left + right + 1) / 2;
                SeekToRestartPoint(mid);
                if (_comparator.Compare(Key, key) < 0)
                {
                    left = mid;
                }
                else
                {
                    right = mid - 1;
                }
            }

            // linear search in current restart index

            for (SeekToRestartPoint(left); HasNext(); Next())
            {
                if (_comparator.Compare(Key, key) >= 0)
                {
                    return(true);
                }
            }

            for (int i = left - 1; i >= 0; i--)
            {
                for (SeekToRestartPoint(i); HasNext(); Next())
                {
                    if (_comparator.Compare(Key, key) >= 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #2
0
        public ResultStatus Get(Span <byte> key)
        {
            if (!"leveldb.BytewiseComparator".Equals(CurrentVersion.Comparator, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new Exception($"Found record, but contains invalid or unsupported comparator: {CurrentVersion.Comparator}");
            }

            foreach (var level in CurrentVersion.NewFiles)             // Search all levels for file with matching index
            {
                foreach (FileMetadata tbl in level.Value)
                {
                    var smallestKey = tbl.SmallestKey.AsSpan().UserKey();
                    var largestKey  = tbl.LargestKey.AsSpan().UserKey();
                    //if (smallestKey.Length == 0 || largestKey.Length == 0) continue;

                    if (_comparator.Compare(key, smallestKey) >= 0 && _comparator.Compare(key, largestKey) <= 0)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Found table file for key in level {level.Key} in file={tbl.FileNumber}");
                        }

                        Table tableReader = tbl.Table;
                        if (tableReader == null)
                        {
                            FileInfo f = new FileInfo(Path.Combine(_baseDirectory.FullName, $"{tbl.FileNumber:000000}.ldb"));
                            if (!f.Exists)
                            {
                                throw new Exception($"Could not find table {f.FullName}");
                            }
                            tableReader = new Table(f);
                            tbl.Table   = tableReader;
                        }

                        var result = tableReader.Get(key);
                        if (result.State == ResultState.Exist || result.State == ResultState.Deleted)
                        {
                            return(result);
                        }
                    }
                }
            }

            return(ResultStatus.NotFound);
        }
Beispiel #3
0
        public ResultStatus Get(Span <byte> key)
        {
            foreach (var level in CurrentVersion.Levels)             // Search all levels for file with matching index
            {
                foreach (FileMetadata tbl in level.Value)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Checking table {tbl.FileNumber} for key: {key.ToHexString()}");
                    }
                    Span <byte> smallestKey = tbl.SmallestKey.AsSpan().UserKey();
                    Span <byte> largestKey  = tbl.LargestKey.AsSpan().UserKey();

                    if (_comparator.Compare(key, smallestKey) >= 0 && _comparator.Compare(key, largestKey) <= 0)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Found table file for key in level {level.Key} in file={tbl.FileNumber}, Smallest:{tbl.SmallestKey.ToHexString()}, Largest:{tbl.LargestKey.ToHexString()}");
                        }

                        Table tableReader = tbl.Table;
                        if (tableReader == null)
                        {
                            tableReader = GetTable(tbl.FileNumber);
                            tableReader.Initialize();
                            tbl.Table = tableReader;
                        }

                        ResultStatus result = tableReader.Get(key);
                        if (result.State == ResultState.Exist || result.State == ResultState.Deleted)
                        {
                            return(result);
                        }
                    }
                }
            }

            if (Log.IsDebugEnabled)
            {
                Log.Debug($"Found no table for key: {key.ToHexString()}");
            }

            return(ResultStatus.NotFound);
        }
Beispiel #4
0
        public List <FileMetadata> GetOverlappingFiles(int level, byte[] smallestKey, byte[] largestKey)
        {
            if (!Levels.ContainsKey(level))
            {
                return(new List <FileMetadata>());
            }

            var overlappingFiles = new List <FileMetadata>();
            var comparator       = new BytewiseComparator();

            foreach (FileMetadata metadata in GetFiles(level))
            {
                if (comparator.Compare(metadata.SmallestKey, largestKey) <= 0 && comparator.Compare(metadata.LargestKey, smallestKey) >= 0)
                {
                    overlappingFiles.Add(metadata);
                }
            }

            return(overlappingFiles);
        }
Beispiel #5
0
        internal bool Seek(Span <byte> key)
        {
            // binary search for key

            int left  = 0;
            int right = _restartCount - 1;

            while (left < right)
            {
                var mid = (left + right + 1) / 2;
                SeekToRestartPoint(mid);
                if (_comparator.Compare(Key, key) < 0)
                {
                    left = mid;
                }
                else
                {
                    right = mid - 1;
                }
            }

            // linear search in current restart index

            SeekToRestartPoint(left);
            do
            {
                if (Key == null || Key.IsEmpty)
                {
                    return(false);
                }

                if (_comparator.Compare(Key, key) >= 0)
                {
                    return(true);
                }
            } while (TryParseCurrentEntry());

            return(false);
        }
Beispiel #6
0
        public ResultStatus Get(Span <byte> key)
        {
            if (_resultCache == null)
            {
                throw new InvalidOperationException("Log not prepared for queries. Did you forget to call Open()?");
            }

            foreach (var entry in _resultCache.OrderByDescending(kvp => kvp.Value.Sequence))
            {
                if (_comparator.Compare(key, entry.Key) == 0)
                {
                    return(new ResultStatus(entry.Value.ResultState, entry.Value.Data));
                }
            }

            return(ResultStatus.NotFound);
        }
Beispiel #7
0
        public int Compare(KeyValuePair <byte[], MemCache.ResultCacheEntry> a, KeyValuePair <byte[], MemCache.ResultCacheEntry> b)
        {
            var comp = _comparator.Compare(a.Key, b.Key);

            if (comp != 0)
            {
                return(comp);
            }

            var aseq = a.Value.Sequence;
            var bseq = b.Value.Sequence;

            if (aseq > bseq)
            {
                return(-1);
            }

            if (aseq < bseq)
            {
                return(1);
            }

            return(0);
        }
Beispiel #8
0
        public void LevelDbReadLogTest()
        {
            // https://github.com/google/leveldb/blob/master/doc/log_format.md

            DirectoryInfo directory = TestUtils.GetTestDirectory();

            LogReader logReader = new LogReader(new FileInfo(Path.Combine(directory.FullName, "000047.log")));

            BytewiseComparator comparator = new BytewiseComparator();

            bool found = false;

            while (true)
            {
                ReadOnlySpan <byte> data = logReader.ReadData();

                if (logReader.Eof)
                {
                    break;
                }

                var dataReader = new SpanReader(data);

                long sequenceNumber = dataReader.ReadInt64();
                long size           = dataReader.ReadInt32();

                while (!dataReader.Eof)
                {
                    byte recType = dataReader.ReadByte();

                    ulong v1         = dataReader.ReadVarLong();
                    var   currentKey = dataReader.Read(v1);

                    //CurrentKey = f5 ff ff ff eb ff ff ff 36

                    if (comparator.Compare(new byte[] { 0xf5, 0xff, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xff, 0x36 }, currentKey) == 0)
                    {
                        Assert.False(found);
                        found = true;
                    }

                    ulong v2 = 0;
                    ReadOnlySpan <byte> currentVal = ReadOnlySpan <byte> .Empty;
                    switch (recType)
                    {
                    case 1:                             // value
                    {
                        if (recType == 1)
                        {
                            v2         = dataReader.ReadVarLong();
                            currentVal = dataReader.Read(v2);
                        }
                        break;
                    }

                    case 0:                             // delete
                    {
                        //Assert.Fail("Unexpected delete key");
                        break;
                    }

                    default:
                        throw new Exception("Unknown record format");
                    }

                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"RecType={recType}, Sequence={sequenceNumber}, Size={size}, v1={v1}, v2={v2}\nCurrentKey={currentKey.HexDump(currentKey.Length, false, false)}\nCurrentVal=\n{currentVal.HexDump(cutAfterFive: true)} ");
                    }
                }
            }

            Assert.True(found);
        }
Beispiel #9
0
        public void BytewiseComparatorTest()
        {
            var comparator = new BytewiseComparator();

            // Basic
            Assert.AreEqual(Equal, comparator.Compare(new Span <byte>(), new Span <byte>()));
            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 0 }), new Span <byte>()));
            Assert.AreEqual(Less, comparator.Compare(new Span <byte>(), new Span <byte>(new byte[] { 0 })));

            Assert.AreEqual(Equal, comparator.Compare(new Span <byte>(new byte[] { 0 }), new Span <byte>(new byte[] { 0 })));
            Assert.AreEqual(Equal, comparator.Compare(new Span <byte>(new byte[] { 0, 1, 2 }), new Span <byte>(new byte[] { 0, 1, 2 })));

            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 1 }), new Span <byte>(new byte[] { 0 })));
            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 1, 1 }), new Span <byte>(new byte[] { 1, 0 })));
            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 1, 1 }), new Span <byte>(new byte[] { 1, 0, 1 })));
            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 1, 1, 1 }), new Span <byte>(new byte[] { 1, 1 })));

            Assert.AreEqual(Less, comparator.Compare(new Span <byte>(new byte[] { 0 }), new Span <byte>(new byte[] { 1 })));
            Assert.AreEqual(Less, comparator.Compare(new Span <byte>(new byte[] { 1, 0 }), new Span <byte>(new byte[] { 1, 1 })));
            Assert.AreEqual(Less, comparator.Compare(new Span <byte>(new byte[] { 1, 0, 1 }), new Span <byte>(new byte[] { 1, 1 })));
            Assert.AreEqual(Less, comparator.Compare(new Span <byte>(new byte[] { 1, 1 }), new Span <byte>(new byte[] { 1, 1, 1 })));

            Assert.AreEqual(Greater, comparator.Compare(new Span <byte>(new byte[] { 1, 0, 2 }), new Span <byte>(new byte[] { 1, 0, 1, 2, 3 })));

            //"SmallestKey": {
            //	"Key": "00 00 00 00 10 00 00 00 31 01 1f 34 00 00 00 00 00  ........1..4....."
            //},
            //"LargestKey": {
            //	"Key": "ff ff ff ff fc ff ff ff 76 01 a7 42 00 00 00 00 00  ÿÿÿÿüÿÿÿv.§B....."
            //}

            Assert.AreEqual(Less, comparator.Compare(
                                new byte[] { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 },
                                new byte[] { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x31, 0x01, 0x1f, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, }));

            Assert.AreEqual(Greater, comparator.Compare(
                                new byte[] { 0x00, 0x00, 0x00, 0x00, 0x10, 0x01 },
                                new byte[] { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x31, 0x01, 0x1f, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, }));
        }