go/leveldb/iterator.go

122 lines
2.0 KiB
Go

package leveldb
import (
"bytes"
"github.com/jmhodges/levigo"
)
const forward uint8 = 0
const backward uint8 = 1
type Iterator struct {
it *levigo.Iterator
start []byte
stop []byte
limit int
step int
//0 for forward, 1 for backward
direction uint8
}
func newIterator(db *DB, opts *levigo.ReadOptions, start []byte, stop []byte, limit int, direction uint8) *Iterator {
it := new(Iterator)
it.it = db.db.NewIterator(opts)
it.start = start
it.stop = stop
it.limit = limit
it.direction = direction
it.step = 0
if start == nil {
if direction == forward {
it.it.SeekToFirst()
} else {
it.it.SeekToLast()
}
} else {
it.it.Seek(start)
if it.Valid() && !bytes.Equal(it.Key(), start) {
//for forward, key is the next bigger than start
//for backward, key is the next bigger than start, so must go prev
if direction == backward {
it.it.Prev()
}
}
}
return it
}
func (it *Iterator) Valid() bool {
if !it.it.Valid() {
return false
}
if it.limit > 0 && it.step >= it.limit {
return false
}
if it.direction == forward {
if it.stop != nil && bytes.Compare(it.Key(), it.stop) > 0 {
return false
}
} else {
if it.stop != nil && bytes.Compare(it.Key(), it.stop) < 0 {
return false
}
}
return true
}
func (it *Iterator) GetError() error {
return it.it.GetError()
}
func (it *Iterator) Next() {
it.step++
if it.direction == forward {
it.it.Next()
} else {
it.it.Prev()
}
}
func (it *Iterator) Key() []byte {
return it.it.Key()
}
func (it *Iterator) Value() []byte {
return it.it.Value()
}
func (it *Iterator) Close() {
it.it.Close()
}
func (it *Iterator) IntValue() (int64, error) {
return Int(it.Value(), nil)
}
func (it *Iterator) UintValue() (uint64, error) {
return Uint(it.Value(), nil)
}
func (it *Iterator) FloatValue() (float64, error) {
return Float(it.Value(), nil)
}
func (it *Iterator) StringValue() (string, error) {
return String(it.Value(), nil)
}
func (it *Iterator) SliceValue() ([]byte, error) {
return Slice(it.Value(), nil)
}