123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
- // All rights reserved.
- //
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- package iterator
- import (
- "github.com/syndtr/goleveldb/leveldb/util"
- )
- // BasicArray is the interface that wraps basic Len and Search method.
- type BasicArray interface {
- // Len returns length of the array.
- Len() int
- // Search finds smallest index that point to a key that is greater
- // than or equal to the given key.
- Search(key []byte) int
- }
- // Array is the interface that wraps BasicArray and basic Index method.
- type Array interface {
- BasicArray
- // Index returns key/value pair with index of i.
- Index(i int) (key, value []byte)
- }
- // Array is the interface that wraps BasicArray and basic Get method.
- type ArrayIndexer interface {
- BasicArray
- // Get returns a new data iterator with index of i.
- Get(i int) Iterator
- }
- type basicArrayIterator struct {
- util.BasicReleaser
- array BasicArray
- pos int
- err error
- }
- func (i *basicArrayIterator) Valid() bool {
- return i.pos >= 0 && i.pos < i.array.Len() && !i.Released()
- }
- func (i *basicArrayIterator) First() bool {
- if i.Released() {
- i.err = ErrIterReleased
- return false
- }
- if i.array.Len() == 0 {
- i.pos = -1
- return false
- }
- i.pos = 0
- return true
- }
- func (i *basicArrayIterator) Last() bool {
- if i.Released() {
- i.err = ErrIterReleased
- return false
- }
- n := i.array.Len()
- if n == 0 {
- i.pos = 0
- return false
- }
- i.pos = n - 1
- return true
- }
- func (i *basicArrayIterator) Seek(key []byte) bool {
- if i.Released() {
- i.err = ErrIterReleased
- return false
- }
- n := i.array.Len()
- if n == 0 {
- i.pos = 0
- return false
- }
- i.pos = i.array.Search(key)
- if i.pos >= n {
- return false
- }
- return true
- }
- func (i *basicArrayIterator) Next() bool {
- if i.Released() {
- i.err = ErrIterReleased
- return false
- }
- i.pos++
- if n := i.array.Len(); i.pos >= n {
- i.pos = n
- return false
- }
- return true
- }
- func (i *basicArrayIterator) Prev() bool {
- if i.Released() {
- i.err = ErrIterReleased
- return false
- }
- i.pos--
- if i.pos < 0 {
- i.pos = -1
- return false
- }
- return true
- }
- func (i *basicArrayIterator) Error() error { return i.err }
- type arrayIterator struct {
- basicArrayIterator
- array Array
- pos int
- key, value []byte
- }
- func (i *arrayIterator) updateKV() {
- if i.pos == i.basicArrayIterator.pos {
- return
- }
- i.pos = i.basicArrayIterator.pos
- if i.Valid() {
- i.key, i.value = i.array.Index(i.pos)
- } else {
- i.key = nil
- i.value = nil
- }
- }
- func (i *arrayIterator) Key() []byte {
- i.updateKV()
- return i.key
- }
- func (i *arrayIterator) Value() []byte {
- i.updateKV()
- return i.value
- }
- type arrayIteratorIndexer struct {
- basicArrayIterator
- array ArrayIndexer
- }
- func (i *arrayIteratorIndexer) Get() Iterator {
- if i.Valid() {
- return i.array.Get(i.basicArrayIterator.pos)
- }
- return nil
- }
- // NewArrayIterator returns an iterator from the given array.
- func NewArrayIterator(array Array) Iterator {
- return &arrayIterator{
- basicArrayIterator: basicArrayIterator{array: array, pos: -1},
- array: array,
- pos: -1,
- }
- }
- // NewArrayIndexer returns an index iterator from the given array.
- func NewArrayIndexer(array ArrayIndexer) IteratorIndexer {
- return &arrayIteratorIndexer{
- basicArrayIterator: basicArrayIterator{array: array, pos: -1},
- array: array,
- }
- }
|