public IEnumerable <InternalIByteArrayKeyValuePair> Seek(InternalKey target) { var left = 0; var right = _numRestarts - 1; var value = default(ArraySegment <byte>); // not used var keybuf = new AppendableByteArraySegment(DefaultRestartInterval); while (left < right) { var mid = (left + right + 1) / 2; keybuf.TrimToLength(0); ParseEntry(GetRestartPointOffset(mid), ref keybuf, ref value); var midKey = InternalKey.FromUnsafe(keybuf.ToByteArray()); if (_comparer.Compare(midKey, target) < 0) { // Key at "mid" is smaller than "target". Therefore all // blocks before "mid" are uninteresting. left = mid; } else { // Key at "mid" is >= "target". Therefore all blocks at or // after "mid" are uninteresting. right = mid - 1; } } // Linear search (within restart block) for first key >= target return(SeekToRestartPoint(left).SkipWhile(kv => _comparer.Compare(kv.InternalKey, target) < 0)); }
// ref key current not use private void ParseEntry(int offset, ref AppendableByteArraySegment key, ref ArraySegment <byte> value) { var pb = new CodedInputStream(_data, offset, _restartOffset - offset); var shared = pb.ReadInt32(); var nonShared = pb.ReadInt32(); var valueLength = pb.ReadInt32(); if (key.Length < shared) { throw new InvalidDataException("bad entry in block - shared > _key.length"); } var p = (int)pb.Position; key.TrimToLength(shared); key.Append(new ArraySegment <byte>(_data, p, nonShared)); value = new ArraySegment <byte>(_data, p + nonShared, valueLength); }