code: func (r *Reader) NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator {
  	r.mu.RLock()
  	defer r.mu.RUnlock()
  
  	if r.err != nil {
  		return iterator.NewEmptyIterator(r.err)
  	}
  
  	fillCache := !ro.GetDontFillCache()
  	indexBlock, rel, err := r.getIndexBlock(fillCache)
  	if err != nil {
  		return iterator.NewEmptyIterator(err)
  	}
  	index := &indexIter{
  		blockIter: r.newBlockIter(indexBlock, rel, slice, true),
  		tr:        r,
  		slice:     slice,
  		fillCache: !ro.GetDontFillCache(),
  	}
  	return iterator.NewIndexedIterator(index, opt.GetStrict(r.o, ro, opt.StrictReader))
  }
docs: // NewIterator creates an iterator from the table.
  //
  // Slice allows slicing the iterator to only contains keys in the given
  // range. A nil Range.Start is treated as a key before all keys in the
  // table. And a nil Range.Limit is treated as a key after all keys in
  // the table.
  //
  // WARNING: Any slice returned by interator (e.g. slice returned by calling
  // Iterator.Key() or Iterator.Key() methods), its content should not be modified
  // unless noted otherwise.
  //
  // The returned iterator is not safe for concurrent use and should be released
  // after use.
  //
  // Also read Iterator documentation of the leveldb/iterator package.