mirror of
https://github.com/go-gitea/gitea
synced 2024-09-19 18:26:04 +00:00
185 lines
3.3 KiB
Go
185 lines
3.3 KiB
Go
|
// 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,
|
||
|
}
|
||
|
}
|