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); }
public ResultStatus Get(Span <byte> key) { if (Log.IsDebugEnabled) { Log.Debug($"Get Key from table: {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 Initialize(); BlockHandle handle = FindBlockHandleInBlockIndex(key); if (handle == null) { if (Log.IsDebugEnabled) { Log.Warn($"Key was in range for table, but found no exact match in file {_file.Name}"); } return(ResultStatus.NotFound); } if (_bloomFilterPolicy?.KeyMayMatch(key, handle.Offset) ?? true) { byte[] targetBlock = GetBlock(handle); return(SeekKeyInBlockData(key, targetBlock)); } return(ResultStatus.NotFound); }