func (it *dbIter) Next(fn kv.FnKeyCmp) (kv.Iterator, error) { encKey := codec.EncodeBytes(nil, it.startKey) // max key encEndKey := codec.EncodeBytes(nil, []byte{0xff, 0xff}) var retErr error var engineIter engine.Iterator for { engineIter, retErr = it.s.db.Seek(encKey) if retErr != nil { return nil, errors.Trace(retErr) } // Check if overflow if !engineIter.Next() { it.valid = false break } metaKey := engineIter.Key() // Check if meet the end of table. if bytes.Compare(metaKey, encEndKey) >= 0 { it.valid = false break } // Get real key from metaKey key, _, err := MvccDecode(metaKey) if err != nil { // It's not a valid metaKey, maybe overflow (other data). it.valid = false break } // Get kv pair. val, err := it.s.MvccGet(key, it.exceptedVersion) if err != nil && !errors2.ErrorEqual(err, kv.ErrNotExist) { // Get this version error it.valid = false retErr = err break } if val != nil { it.k = key it.v = val it.startKey = key.Next() break } // Release the iterator, and update key engineIter.Release() // Current key's all versions are deleted, just go next key. encKey = codec.EncodeBytes(nil, key.Next()) } engineIter.Release() return it, errors.Trace(retErr) }
func (it *dbIter) Next() (kv.Iterator, error) { encKey := codec.EncodeBytes(nil, it.startKey) var retErr error var engineIter engine.Iterator for { var err error engineIter, err = it.s.internalSeek(encKey) if err != nil { it.valid = false retErr = err break } metaKey := engineIter.Key() // Get real key from metaKey key, _, err := MvccDecode(metaKey) if err != nil { // It's not a valid metaKey, maybe overflow (other data). it.valid = false break } // Get kv pair. val, err := it.s.MvccGet(key, it.exceptedVersion) if err != nil && !errors2.ErrorEqual(err, kv.ErrNotExist) { // Get this version error it.valid = false retErr = err break } if val != nil { it.k = bytes.CloneBytes(key) it.v = bytes.CloneBytes(val) it.startKey = key.Next() break } // Current key's all versions are deleted, just go next key. encKey = codec.EncodeBytes(nil, key.Next()) } return it, errors.Trace(retErr) }
func newDBIter(it engine.Iterator) *dbIter { return &dbIter{ Iterator: it, valid: it.Next(), } }