public bool TryGet(Slice key, ulong seq, ReadOptions readOptions, out Stream stream, out GetStats stats) { stats = new GetStats { SeekFile = null, SeekFileLevel = -1 }; FileMetadata lastFileRead = null; int lastFileReadLevel = -1; var internalKey = new InternalKey(key, seq, ItemType.ValueForSeek); // We can search level-by-level since entries never hop across // levels. Therefore we are guaranteed that if we find data // in an smaller level, later levels are irrelevant. for (var level = 0; level < Config.NumberOfLevels; level++) { if (Files[level].Count == 0) { continue; } // Get the list of files to search in this level var files = GetRelevantFilesForLevel(level, internalKey); if (files == null || files.Count == 0) continue; foreach (var f in files) { if (lastFileRead != null && stats.SeekFile == null) { // We have had more than one seek for this read. Charge the 1st file. stats.SeekFile = lastFileRead; stats.SeekFileLevel = lastFileReadLevel; } lastFileRead = f; lastFileReadLevel = level; var state = storageContext.TableCache.Get( internalKey, f.FileNumber, f.FileSize, readOptions, storageContext.InternalKeyComparator.UserComparator, out stream); switch (state) { case ItemState.Found: return true; case ItemState.NotFound: break; case ItemState.Deleted: return false; case ItemState.Corrupt: return false; default: throw new NotSupportedException(state.ToString()); } } } stream = null; return false; }
public bool UpdateStats(GetStats stats) { var file = stats.SeekFile; if (file != null) { file.AllowedSeeks--; if (file.AllowedSeeks <= 0 && FileToCompact == null) { FileToCompact = file; FileToCompactLevel = stats.SeekFileLevel; } } return false; }