go/leveldb/iterator.go

186 lines
2.9 KiB
Go
Raw Normal View History

2014-04-18 10:50:29 +04:00
package leveldb
import (
"bytes"
"github.com/jmhodges/levigo"
)
2014-05-07 10:18:11 +04:00
const (
IteratorForward uint8 = 0
IteratorBackward uint8 = 1
)
const (
RangeClose uint8 = 0x00
RangeLOpen uint8 = 0x01
RangeROpen uint8 = 0x10
RangeOpen uint8 = 0x11
)
2014-04-18 10:50:29 +04:00
//min must less or equal than max
2014-05-07 10:18:11 +04:00
//range type:
//close: [min, max]
//open: (min, max)
//lopen: (min, max]
//ropen: [min, max)
type Range struct {
Min []byte
Max []byte
2014-05-07 10:18:11 +04:00
Type uint8
}
2014-05-07 10:18:11 +04:00
func NewRange(min []byte, max []byte, tp uint8) *Range {
return &Range{min, max, tp}
}
2014-04-18 10:50:29 +04:00
type Iterator struct {
it *levigo.Iterator
r *Range
offset int
limit int
2014-04-18 10:50:29 +04:00
step int
2014-05-07 10:18:11 +04:00
//0 for IteratorForward, 1 for IteratorBackward
2014-04-18 10:50:29 +04:00
direction uint8
}
func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, offset int, limit int, direction uint8) *Iterator {
2014-04-18 10:50:29 +04:00
it := new(Iterator)
it.it = db.db.NewIterator(opts)
it.r = r
it.offset = offset
2014-04-18 10:50:29 +04:00
it.limit = limit
it.direction = direction
2014-05-07 10:18:11 +04:00
2014-04-18 10:50:29 +04:00
it.step = 0
if offset < 0 {
return it
}
2014-05-07 10:18:11 +04:00
if direction == IteratorForward {
if r.Min == nil {
2014-04-18 10:50:29 +04:00
it.it.SeekToFirst()
} else {
it.it.Seek(r.Min)
2014-05-07 10:18:11 +04:00
if r.Type&RangeLOpen > 0 {
if it.it.Valid() && bytes.Equal(it.it.Key(), r.Min) {
it.it.Next()
}
}
2014-04-18 10:50:29 +04:00
}
} else {
if r.Max == nil {
it.it.SeekToLast()
} else {
it.it.Seek(r.Max)
if !it.it.Valid() {
it.it.SeekToLast()
} else {
if !bytes.Equal(it.it.Key(), r.Max) {
it.it.Prev()
}
2014-04-18 10:50:29 +04:00
}
2014-05-07 10:18:11 +04:00
if r.Type&RangeROpen > 0 {
if it.Valid() && bytes.Equal(it.Key(), r.Max) {
it.it.Prev()
}
}
2014-04-18 10:50:29 +04:00
}
}
for i := 0; i < offset; i++ {
if it.Valid() {
it.Next()
}
}
2014-04-18 10:50:29 +04:00
return it
}
func (it *Iterator) Valid() bool {
if it.offset < 0 {
2014-04-18 10:50:29 +04:00
return false
} else if !it.it.Valid() {
return false
} else if it.limit >= 0 && it.step >= it.limit {
2014-04-18 10:50:29 +04:00
return false
}
2014-05-07 10:18:11 +04:00
if it.direction == IteratorForward {
if it.r.Max != nil {
r := bytes.Compare(it.Key(), it.r.Max)
2014-05-07 10:18:11 +04:00
if it.r.Type&RangeROpen > 0 {
return !(r >= 0)
2014-05-07 10:18:11 +04:00
} else {
return !(r > 0)
}
2014-04-18 10:50:29 +04:00
}
} else {
if it.r.Min != nil {
r := bytes.Compare(it.Key(), it.r.Min)
2014-05-07 10:18:11 +04:00
if it.r.Type&RangeLOpen > 0 {
return !(r <= 0)
2014-05-07 10:18:11 +04:00
} else {
return !(r < 0)
}
2014-04-18 10:50:29 +04:00
}
}
return true
}
func (it *Iterator) GetError() error {
return it.it.GetError()
}
func (it *Iterator) Next() {
it.step++
2014-05-07 10:18:11 +04:00
if it.direction == IteratorForward {
2014-04-18 10:50:29 +04:00
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()
}
2014-05-05 13:09:05 +04:00
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)
}