ledisdb/store/iterator.go

334 lines
5.6 KiB
Go
Raw Permalink Normal View History

2014-07-25 13:58:00 +04:00
package store
2014-06-19 13:19:40 +04:00
import (
"bytes"
2014-07-25 13:58:00 +04:00
"github.com/siddontang/ledisdb/store/driver"
2014-06-19 13:19:40 +04:00
)
const (
IteratorForward uint8 = 0
IteratorBackward uint8 = 1
)
const (
RangeClose uint8 = 0x00
RangeLOpen uint8 = 0x01
RangeROpen uint8 = 0x10
RangeOpen uint8 = 0x11
)
2014-07-09 05:33:44 +04:00
// min must less or equal than max
2014-07-09 06:26:15 +04:00
//
2014-07-09 05:33:44 +04:00
// range type:
2014-07-09 06:26:15 +04:00
//
2014-07-25 13:58:00 +04:00
// close: [min, max]
// open: (min, max)
// lopen: (min, max]
// ropen: [min, max)
2014-07-09 06:26:15 +04:00
//
2014-06-19 13:19:40 +04:00
type Range struct {
Min []byte
Max []byte
Type uint8
}
type Limit struct {
Offset int
Count int
}
2014-06-19 13:19:40 +04:00
type Iterator struct {
2014-07-25 13:58:00 +04:00
it driver.IIterator
2014-10-15 06:18:20 +04:00
st *Stat
2014-06-19 13:19:40 +04:00
}
2014-07-09 05:33:44 +04:00
// Returns a copy of key.
2014-06-19 13:19:40 +04:00
func (it *Iterator) Key() []byte {
2014-07-25 13:58:00 +04:00
k := it.it.Key()
if k == nil {
2014-06-19 13:19:40 +04:00
return nil
}
2014-07-25 13:58:00 +04:00
return append([]byte{}, k...)
2014-06-19 13:19:40 +04:00
}
2014-07-09 05:33:44 +04:00
// Returns a copy of value.
2014-06-19 13:19:40 +04:00
func (it *Iterator) Value() []byte {
2014-07-25 13:58:00 +04:00
v := it.it.Value()
if v == nil {
2014-06-19 13:19:40 +04:00
return nil
}
2014-07-25 13:58:00 +04:00
return append([]byte{}, v...)
2014-06-19 13:19:40 +04:00
}
2014-07-09 05:33:44 +04:00
// Returns a reference of key.
// you must be careful that it will be changed after next iterate.
func (it *Iterator) RawKey() []byte {
2014-07-25 13:58:00 +04:00
return it.it.Key()
}
2014-07-09 05:33:44 +04:00
// Returns a reference of value.
// you must be careful that it will be changed after next iterate.
func (it *Iterator) RawValue() []byte {
2014-07-25 13:58:00 +04:00
return it.it.Value()
}
2014-07-09 06:26:15 +04:00
// Copy key to b, if b len is small or nil, returns a new one.
func (it *Iterator) BufKey(b []byte) []byte {
k := it.RawKey()
if k == nil {
return nil
}
2014-07-07 11:36:16 +04:00
if b == nil {
b = []byte{}
}
2014-07-07 11:36:16 +04:00
b = b[0:0]
return append(b, k...)
}
2014-07-09 06:26:15 +04:00
// Copy value to b, if b len is small or nil, returns a new one.
func (it *Iterator) BufValue(b []byte) []byte {
v := it.RawValue()
if v == nil {
return nil
}
2014-07-07 11:36:16 +04:00
if b == nil {
b = []byte{}
}
2014-07-07 11:36:16 +04:00
b = b[0:0]
return append(b, v...)
}
2014-06-19 13:19:40 +04:00
func (it *Iterator) Close() {
if it.it != nil {
2014-10-15 06:18:20 +04:00
it.st.IterCloseNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.Close()
it.it = nil
}
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) Valid() bool {
2014-07-25 13:58:00 +04:00
return it.it.Valid()
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) Next() {
2014-10-15 06:18:20 +04:00
it.st.IterSeekNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.Next()
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) Prev() {
2014-10-15 06:18:20 +04:00
it.st.IterSeekNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.Prev()
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) SeekToFirst() {
2014-10-15 06:18:20 +04:00
it.st.IterSeekNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.First()
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) SeekToLast() {
2014-10-15 06:18:20 +04:00
it.st.IterSeekNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.Last()
2014-06-19 13:19:40 +04:00
}
func (it *Iterator) Seek(key []byte) {
2014-10-15 06:18:20 +04:00
it.st.IterSeekNum.Add(1)
2014-07-25 13:58:00 +04:00
it.it.Seek(key)
2014-06-19 13:19:40 +04:00
}
2014-07-09 06:26:15 +04:00
// Finds by key, if not found, nil returns.
2014-06-19 13:19:40 +04:00
func (it *Iterator) Find(key []byte) []byte {
it.Seek(key)
2014-06-19 13:45:52 +04:00
if it.Valid() {
k := it.RawKey()
if k == nil {
2014-06-19 13:45:52 +04:00
return nil
} else if bytes.Equal(k, key) {
2014-06-19 13:45:52 +04:00
return it.Value()
}
2014-06-19 13:19:40 +04:00
}
2014-06-19 13:45:52 +04:00
return nil
2014-06-19 13:19:40 +04:00
}
2014-07-09 06:26:15 +04:00
// Finds by key, if not found, nil returns, else a reference of value returns.
2014-07-09 05:33:44 +04:00
// you must be careful that it will be changed after next iterate.
func (it *Iterator) RawFind(key []byte) []byte {
it.Seek(key)
if it.Valid() {
k := it.RawKey()
if k == nil {
return nil
} else if bytes.Equal(k, key) {
return it.RawValue()
}
}
return nil
}
2014-06-19 13:19:40 +04:00
type RangeLimitIterator struct {
it *Iterator
r *Range
l *Limit
2014-06-19 13:19:40 +04:00
step int
//0 for IteratorForward, 1 for IteratorBackward
direction uint8
}
func (it *RangeLimitIterator) Key() []byte {
return it.it.Key()
}
func (it *RangeLimitIterator) Value() []byte {
return it.it.Value()
}
func (it *RangeLimitIterator) RawKey() []byte {
return it.it.RawKey()
}
func (it *RangeLimitIterator) RawValue() []byte {
return it.it.RawValue()
}
2014-07-07 10:50:58 +04:00
func (it *RangeLimitIterator) BufKey(b []byte) []byte {
return it.it.BufKey(b)
}
func (it *RangeLimitIterator) BufValue(b []byte) []byte {
return it.it.BufValue(b)
}
2014-06-19 13:19:40 +04:00
func (it *RangeLimitIterator) Valid() bool {
if it.l.Offset < 0 {
2014-06-19 13:19:40 +04:00
return false
} else if !it.it.Valid() {
return false
} else if it.l.Count >= 0 && it.step >= it.l.Count {
2014-06-19 13:19:40 +04:00
return false
}
if it.direction == IteratorForward {
if it.r.Max != nil {
r := bytes.Compare(it.it.RawKey(), it.r.Max)
2014-06-19 13:19:40 +04:00
if it.r.Type&RangeROpen > 0 {
return !(r >= 0)
} else {
return !(r > 0)
}
}
} else {
if it.r.Min != nil {
r := bytes.Compare(it.it.RawKey(), it.r.Min)
2014-06-19 13:19:40 +04:00
if it.r.Type&RangeLOpen > 0 {
return !(r <= 0)
} else {
return !(r < 0)
}
}
}
return true
}
func (it *RangeLimitIterator) Next() {
it.step++
if it.direction == IteratorForward {
it.it.Next()
} else {
it.it.Prev()
}
}
func (it *RangeLimitIterator) Close() {
it.it.Close()
}
func NewRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
return rangeLimitIterator(i, r, l, IteratorForward)
}
func NewRevRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
return rangeLimitIterator(i, r, l, IteratorBackward)
}
func NewRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorForward)
}
func NewRevRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorBackward)
}
func rangeLimitIterator(i *Iterator, r *Range, l *Limit, direction uint8) *RangeLimitIterator {
2014-06-19 13:19:40 +04:00
it := new(RangeLimitIterator)
it.it = i
it.r = r
it.l = l
2014-06-19 13:19:40 +04:00
it.direction = direction
it.step = 0
if l.Offset < 0 {
2014-06-19 13:19:40 +04:00
return it
}
if direction == IteratorForward {
if r.Min == nil {
it.it.SeekToFirst()
} else {
it.it.Seek(r.Min)
if r.Type&RangeLOpen > 0 {
if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Min) {
2014-06-19 13:19:40 +04:00
it.it.Next()
}
}
}
} 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.RawKey(), r.Max) {
2014-06-19 13:19:40 +04:00
it.it.Prev()
}
}
if r.Type&RangeROpen > 0 {
if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Max) {
2014-06-19 13:19:40 +04:00
it.it.Prev()
}
}
}
}
for i := 0; i < l.Offset; i++ {
2014-06-19 13:19:40 +04:00
if it.it.Valid() {
if it.direction == IteratorForward {
it.it.Next()
} else {
it.it.Prev()
}
}
}
return it
}