// Copyright 2019 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // See the License for the specific language governing permissions and // limitations under the License. package memdb import "unsafe" // Iterator iterates the entries in the DB. type Iterator struct { db *DB curr *node key []byte val []byte } // NewIterator returns a new Iterator for the lock store. func (db *DB) NewIterator() Iterator { return Iterator{ db: db, } } // Valid returns true if the iterator is positioned at a valid node. func (it *Iterator) Valid() bool { return it.curr != nil } // Key returns the key at the current position. func (it *Iterator) Key() []byte { return it.key } // Value returns value. func (it *Iterator) Value() []byte { return it.val } // Next moves the iterator to the next entry. func (it *Iterator) Next() { it.changeToAddr(it.curr.nexts[0]) } // Prev moves the iterator to the previous entry. func (it *Iterator) Prev() { it.changeToAddr(it.curr.prev) } // Seek locates the iterator to the first entry with a key >= seekKey. func (it *Iterator) Seek(seekKey []byte) { node, nodeData, _ := it.db.findGreaterEqual(seekKey) // find >=. it.updateState(node, nodeData) } // SeekForPrev locates the iterator to the last entry with key <= target. func (it *Iterator) SeekForPrev(target []byte) { node, nodeData, _ := it.db.findLess(target, true) // find <=. it.updateState(node, nodeData) } // SeekForExclusivePrev locates the iterator to the last entry with key < target. func (it *Iterator) SeekForExclusivePrev(target []byte) { node, nodeData, _ := it.db.findLess(target, false) it.updateState(node, nodeData) } // SeekToFirst locates the iterator to the first entry. func (it *Iterator) SeekToFirst() { node, nodeData := it.db.getNext(it.db.head.node, 0) it.updateState(node, nodeData) } // SeekToLast locates the iterator to the last entry. func (it *Iterator) SeekToLast() { node, nodeData := it.db.findLast() it.updateState(node, nodeData) } func (it *Iterator) updateState(node *node, nodeData []byte) { it.curr = node if node != nil { it.key = node.getKey(nodeData) it.val = node.getValue(nodeData) } } func (it *Iterator) changeToAddr(addr arenaAddr) { var data []byte var n *node if !addr.isNull() { data = it.db.arena.getFrom(addr) n = (*node)(unsafe.Pointer(&data[0])) } it.updateState(n, data) }