예제 #1
0
        public ResultStatus Get(Span <byte> key)
        {
            if (Log.IsDebugEnabled)
            {
                Log.Debug($"\nSearch Key={key.ToHexString()}");
            }

            // To find a key in the table you:
            // 1) Read the block index. This index have one entry for each block in the file. For each entry it holds the
            //    last index and a block handle for the block. Binary search this and find the correct block.
            // 2) Search either each entry in the block (brute force) OR use the restart index at the end of the block to find an entry
            //    closer to the index you looking for. The restart index contain a subset of the keys with an offset of where it is located.
            //    Use this offset to start closer to the key (entry) you looking for.
            // 3) Match the key and return the data

            // Search block index
            if (_blockIndex == null || _metaIndex == null)
            {
                Footer footer;
                using (MemoryMappedViewStream stream = _memFile.CreateViewStream(_file.Length - Footer.FooterLength, Footer.FooterLength, MemoryMappedFileAccess.Read))
                {
                    footer = Footer.Read(stream);
                }
                _blockIndex = footer.BlockIndexBlockHandle.ReadBlock(_memFile);
                _metaIndex  = footer.MetaindexBlockHandle.ReadBlock(_memFile);
            }

            BlockHandle handle = FindBlockHandleInBlockIndex(key);

            if (handle == null)
            {
                Log.Error($"Expected to find block, but did not");
                return(ResultStatus.NotFound);
            }

            if (_bloomFilterPolicy == null)
            {
                var filters = GetFilters();
                if (filters.TryGetValue("filter.leveldb.BuiltinBloomFilter2", out BlockHandle filterHandle))
                {
                    //var filterBlock = filterHandle.ReadBlock(_memViewStream);
                    var filterBlock = filterHandle.ReadBlock(_memFile);
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("\n" + filterBlock.HexDump(cutAfterFive: true));
                    }

                    _bloomFilterPolicy = new BloomFilterPolicy();
                    _bloomFilterPolicy.Parse(filterBlock);
                }
            }
            if (_bloomFilterPolicy?.KeyMayMatch(key, handle.Offset) ?? true)
            {
                var targetBlock = GetBlock(handle);

                return(SeekKeyInBlockData(key, targetBlock));
            }

            return(ResultStatus.NotFound);
        }
예제 #2
0
        internal void Initialize()
        {
            if (_initialized)
            {
                return;
            }

            if (_blockIndex == null || _metaIndex == null)
            {
                Log.Debug($"Initialize table {_file.Name}");

                Footer footer;
                using (MemoryMappedViewStream stream = _memFile.CreateViewStream(_file.Length - Footer.FooterLength, Footer.FooterLength, MemoryMappedFileAccess.Read))
                {
                    footer = Footer.Read(stream);
                }
                _blockIndex = footer.BlockIndexBlockHandle.ReadBlock(_memFile);
                _metaIndex  = footer.MetaIndexBlockHandle.ReadBlock(_memFile);

                Log.Debug($"initialized table index len {_blockIndex?.Length}");

                Dictionary <string, BlockHandle> filters = GetFilters();
                if (filters.TryGetValue("filter.leveldb.BuiltinBloomFilter2", out BlockHandle filterHandle))
                {
                    byte[] filterBlock = filterHandle.ReadBlock(_memFile);
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug("Found filter block:\n" + filterBlock.HexDump(cutAfterFive: true));
                    }

                    _bloomFilterPolicy = new BloomFilterPolicy();
                    _bloomFilterPolicy.Parse(filterBlock);
                }

                _initialized = true;
            }
        }