func (r *Reader) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator { if r.err != nil { return iterator.NewEmptyIterator(r.err) } index := &indexIter{ blockIter: *r.indexBlock.newIterator(slice, true, nil), tableReader: r, slice: slice, checksum: ro.GetStrict(opt.StrictBlockChecksum), fillCache: !ro.GetDontFillCache(), } return iterator.NewIndexedIterator(index, r.strictIter || ro.GetStrict(opt.StrictIterator), false) }
// Find finds key/value pair whose key is greater than or equal to the // given key. It returns ErrNotFound if the table doesn't contain // such pair. // // The caller should not modify the contents of the returned slice, but // it is safe to modify the contents of the argument after Find returns. func (r *Reader) Find(key []byte, ro *opt.ReadOptions) (rkey, value []byte, err error) { if r.err != nil { err = r.err return } index := r.indexBlock.newIterator(nil, true, nil) defer index.Release() if !index.Seek(key) { err = index.Error() if err == nil { err = ErrNotFound } return } dataBH, n := decodeBlockHandle(index.Value()) if n == 0 { err = errors.New("leveldb/table: Reader: invalid table (bad data block handle)") return } if r.filterBlock != nil && !r.filterBlock.contains(dataBH.offset, key) { err = ErrNotFound return } data := r.getDataIter(dataBH, nil, ro.GetStrict(opt.StrictBlockChecksum), !ro.GetDontFillCache()) defer data.Release() if !data.Seek(key) { err = data.Error() if err == nil { err = ErrNotFound } return } // Don't use block buffer, no need to copy the buffer. rkey = data.Key() // Use block buffer, and since the buffer will be recycled, the buffer // need to be copied. value = append([]byte{}, data.Value()...) return }