Godeps, vendor: convert dependency management to trash (#3198)
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
This commit is contained in:
committed by
Felix Lange
parent
7770304576
commit
289b30715d
184
vendor/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go
generated
vendored
Normal file
184
vendor/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
// 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,
|
||||
}
|
||||
}
|
242
vendor/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go
generated
vendored
Normal file
242
vendor/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go
generated
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
// Copyright (c) 2012, 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/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
// IteratorIndexer is the interface that wraps CommonIterator and basic Get
|
||||
// method. IteratorIndexer provides index for indexed iterator.
|
||||
type IteratorIndexer interface {
|
||||
CommonIterator
|
||||
|
||||
// Get returns a new data iterator for the current position, or nil if
|
||||
// done.
|
||||
Get() Iterator
|
||||
}
|
||||
|
||||
type indexedIterator struct {
|
||||
util.BasicReleaser
|
||||
index IteratorIndexer
|
||||
strict bool
|
||||
|
||||
data Iterator
|
||||
err error
|
||||
errf func(err error)
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (i *indexedIterator) setData() {
|
||||
if i.data != nil {
|
||||
i.data.Release()
|
||||
}
|
||||
i.data = i.index.Get()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) clearData() {
|
||||
if i.data != nil {
|
||||
i.data.Release()
|
||||
}
|
||||
i.data = nil
|
||||
}
|
||||
|
||||
func (i *indexedIterator) indexErr() {
|
||||
if err := i.index.Error(); err != nil {
|
||||
if i.errf != nil {
|
||||
i.errf(err)
|
||||
}
|
||||
i.err = err
|
||||
}
|
||||
}
|
||||
|
||||
func (i *indexedIterator) dataErr() bool {
|
||||
if err := i.data.Error(); err != nil {
|
||||
if i.errf != nil {
|
||||
i.errf(err)
|
||||
}
|
||||
if i.strict || !errors.IsCorrupted(err) {
|
||||
i.err = err
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Valid() bool {
|
||||
return i.data != nil && i.data.Valid()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) First() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
if !i.index.First() {
|
||||
i.indexErr()
|
||||
i.clearData()
|
||||
return false
|
||||
}
|
||||
i.setData()
|
||||
return i.Next()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Last() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
if !i.index.Last() {
|
||||
i.indexErr()
|
||||
i.clearData()
|
||||
return false
|
||||
}
|
||||
i.setData()
|
||||
if !i.data.Last() {
|
||||
if i.dataErr() {
|
||||
return false
|
||||
}
|
||||
i.clearData()
|
||||
return i.Prev()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Seek(key []byte) bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
if !i.index.Seek(key) {
|
||||
i.indexErr()
|
||||
i.clearData()
|
||||
return false
|
||||
}
|
||||
i.setData()
|
||||
if !i.data.Seek(key) {
|
||||
if i.dataErr() {
|
||||
return false
|
||||
}
|
||||
i.clearData()
|
||||
return i.Next()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Next() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
switch {
|
||||
case i.data != nil && !i.data.Next():
|
||||
if i.dataErr() {
|
||||
return false
|
||||
}
|
||||
i.clearData()
|
||||
fallthrough
|
||||
case i.data == nil:
|
||||
if !i.index.Next() {
|
||||
i.indexErr()
|
||||
return false
|
||||
}
|
||||
i.setData()
|
||||
return i.Next()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Prev() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
switch {
|
||||
case i.data != nil && !i.data.Prev():
|
||||
if i.dataErr() {
|
||||
return false
|
||||
}
|
||||
i.clearData()
|
||||
fallthrough
|
||||
case i.data == nil:
|
||||
if !i.index.Prev() {
|
||||
i.indexErr()
|
||||
return false
|
||||
}
|
||||
i.setData()
|
||||
if !i.data.Last() {
|
||||
if i.dataErr() {
|
||||
return false
|
||||
}
|
||||
i.clearData()
|
||||
return i.Prev()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Key() []byte {
|
||||
if i.data == nil {
|
||||
return nil
|
||||
}
|
||||
return i.data.Key()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Value() []byte {
|
||||
if i.data == nil {
|
||||
return nil
|
||||
}
|
||||
return i.data.Value()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Release() {
|
||||
i.clearData()
|
||||
i.index.Release()
|
||||
i.BasicReleaser.Release()
|
||||
}
|
||||
|
||||
func (i *indexedIterator) Error() error {
|
||||
if i.err != nil {
|
||||
return i.err
|
||||
}
|
||||
if err := i.index.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *indexedIterator) SetErrorCallback(f func(err error)) {
|
||||
i.errf = f
|
||||
}
|
||||
|
||||
// NewIndexedIterator returns an 'indexed iterator'. An index is iterator
|
||||
// that returns another iterator, a 'data iterator'. A 'data iterator' is the
|
||||
// iterator that contains actual key/value pairs.
|
||||
//
|
||||
// If strict is true the any 'corruption errors' (i.e errors.IsCorrupted(err) == true)
|
||||
// won't be ignored and will halt 'indexed iterator', otherwise the iterator will
|
||||
// continue to the next 'data iterator'. Corruption on 'index iterator' will not be
|
||||
// ignored and will halt the iterator.
|
||||
func NewIndexedIterator(index IteratorIndexer, strict bool) Iterator {
|
||||
return &indexedIterator{index: index, strict: strict}
|
||||
}
|
132
vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go
generated
vendored
Normal file
132
vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2012, 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 provides interface and implementation to traverse over
|
||||
// contents of a database.
|
||||
package iterator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrIterReleased = errors.New("leveldb/iterator: iterator released")
|
||||
)
|
||||
|
||||
// IteratorSeeker is the interface that wraps the 'seeks method'.
|
||||
type IteratorSeeker interface {
|
||||
// First moves the iterator to the first key/value pair. If the iterator
|
||||
// only contains one key/value pair then First and Last would moves
|
||||
// to the same key/value pair.
|
||||
// It returns whether such pair exist.
|
||||
First() bool
|
||||
|
||||
// Last moves the iterator to the last key/value pair. If the iterator
|
||||
// only contains one key/value pair then First and Last would moves
|
||||
// to the same key/value pair.
|
||||
// It returns whether such pair exist.
|
||||
Last() bool
|
||||
|
||||
// Seek moves the iterator to the first key/value pair whose key is greater
|
||||
// than or equal to the given key.
|
||||
// It returns whether such pair exist.
|
||||
//
|
||||
// It is safe to modify the contents of the argument after Seek returns.
|
||||
Seek(key []byte) bool
|
||||
|
||||
// Next moves the iterator to the next key/value pair.
|
||||
// It returns whether the iterator is exhausted.
|
||||
Next() bool
|
||||
|
||||
// Prev moves the iterator to the previous key/value pair.
|
||||
// It returns whether the iterator is exhausted.
|
||||
Prev() bool
|
||||
}
|
||||
|
||||
// CommonIterator is the interface that wraps common iterator methods.
|
||||
type CommonIterator interface {
|
||||
IteratorSeeker
|
||||
|
||||
// util.Releaser is the interface that wraps basic Release method.
|
||||
// When called Release will releases any resources associated with the
|
||||
// iterator.
|
||||
util.Releaser
|
||||
|
||||
// util.ReleaseSetter is the interface that wraps the basic SetReleaser
|
||||
// method.
|
||||
util.ReleaseSetter
|
||||
|
||||
// TODO: Remove this when ready.
|
||||
Valid() bool
|
||||
|
||||
// Error returns any accumulated error. Exhausting all the key/value pairs
|
||||
// is not considered to be an error.
|
||||
Error() error
|
||||
}
|
||||
|
||||
// Iterator iterates over a DB's key/value pairs in key order.
|
||||
//
|
||||
// When encounter an error any 'seeks method' will return false and will
|
||||
// yield no key/value pairs. The error can be queried by calling the Error
|
||||
// method. Calling Release is still necessary.
|
||||
//
|
||||
// An iterator must be released after use, but it is not necessary to read
|
||||
// an iterator until exhaustion.
|
||||
// Also, an iterator is not necessarily safe for concurrent use, but it is
|
||||
// safe to use multiple iterators concurrently, with each in a dedicated
|
||||
// goroutine.
|
||||
type Iterator interface {
|
||||
CommonIterator
|
||||
|
||||
// Key returns the key of the current key/value pair, or nil if done.
|
||||
// The caller should not modify the contents of the returned slice, and
|
||||
// its contents may change on the next call to any 'seeks method'.
|
||||
Key() []byte
|
||||
|
||||
// Value returns the key of the current key/value pair, or nil if done.
|
||||
// The caller should not modify the contents of the returned slice, and
|
||||
// its contents may change on the next call to any 'seeks method'.
|
||||
Value() []byte
|
||||
}
|
||||
|
||||
// ErrorCallbackSetter is the interface that wraps basic SetErrorCallback
|
||||
// method.
|
||||
//
|
||||
// ErrorCallbackSetter implemented by indexed and merged iterator.
|
||||
type ErrorCallbackSetter interface {
|
||||
// SetErrorCallback allows set an error callback of the corresponding
|
||||
// iterator. Use nil to clear the callback.
|
||||
SetErrorCallback(f func(err error))
|
||||
}
|
||||
|
||||
type emptyIterator struct {
|
||||
util.BasicReleaser
|
||||
err error
|
||||
}
|
||||
|
||||
func (i *emptyIterator) rErr() {
|
||||
if i.err == nil && i.Released() {
|
||||
i.err = ErrIterReleased
|
||||
}
|
||||
}
|
||||
|
||||
func (*emptyIterator) Valid() bool { return false }
|
||||
func (i *emptyIterator) First() bool { i.rErr(); return false }
|
||||
func (i *emptyIterator) Last() bool { i.rErr(); return false }
|
||||
func (i *emptyIterator) Seek(key []byte) bool { i.rErr(); return false }
|
||||
func (i *emptyIterator) Next() bool { i.rErr(); return false }
|
||||
func (i *emptyIterator) Prev() bool { i.rErr(); return false }
|
||||
func (*emptyIterator) Key() []byte { return nil }
|
||||
func (*emptyIterator) Value() []byte { return nil }
|
||||
func (i *emptyIterator) Error() error { return i.err }
|
||||
|
||||
// NewEmptyIterator creates an empty iterator. The err parameter can be
|
||||
// nil, but if not nil the given err will be returned by Error method.
|
||||
func NewEmptyIterator(err error) Iterator {
|
||||
return &emptyIterator{err: err}
|
||||
}
|
304
vendor/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go
generated
vendored
Normal file
304
vendor/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go
generated
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
// Copyright (c) 2012, 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/comparer"
|
||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
type dir int
|
||||
|
||||
const (
|
||||
dirReleased dir = iota - 1
|
||||
dirSOI
|
||||
dirEOI
|
||||
dirBackward
|
||||
dirForward
|
||||
)
|
||||
|
||||
type mergedIterator struct {
|
||||
cmp comparer.Comparer
|
||||
iters []Iterator
|
||||
strict bool
|
||||
|
||||
keys [][]byte
|
||||
index int
|
||||
dir dir
|
||||
err error
|
||||
errf func(err error)
|
||||
releaser util.Releaser
|
||||
}
|
||||
|
||||
func assertKey(key []byte) []byte {
|
||||
if key == nil {
|
||||
panic("leveldb/iterator: nil key")
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func (i *mergedIterator) iterErr(iter Iterator) bool {
|
||||
if err := iter.Error(); err != nil {
|
||||
if i.errf != nil {
|
||||
i.errf(err)
|
||||
}
|
||||
if i.strict || !errors.IsCorrupted(err) {
|
||||
i.err = err
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Valid() bool {
|
||||
return i.err == nil && i.dir > dirEOI
|
||||
}
|
||||
|
||||
func (i *mergedIterator) First() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.dir == dirReleased {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
for x, iter := range i.iters {
|
||||
switch {
|
||||
case iter.First():
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
}
|
||||
i.dir = dirSOI
|
||||
return i.next()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Last() bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.dir == dirReleased {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
for x, iter := range i.iters {
|
||||
switch {
|
||||
case iter.Last():
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
}
|
||||
i.dir = dirEOI
|
||||
return i.prev()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Seek(key []byte) bool {
|
||||
if i.err != nil {
|
||||
return false
|
||||
} else if i.dir == dirReleased {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
for x, iter := range i.iters {
|
||||
switch {
|
||||
case iter.Seek(key):
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
}
|
||||
i.dir = dirSOI
|
||||
return i.next()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) next() bool {
|
||||
var key []byte
|
||||
if i.dir == dirForward {
|
||||
key = i.keys[i.index]
|
||||
}
|
||||
for x, tkey := range i.keys {
|
||||
if tkey != nil && (key == nil || i.cmp.Compare(tkey, key) < 0) {
|
||||
key = tkey
|
||||
i.index = x
|
||||
}
|
||||
}
|
||||
if key == nil {
|
||||
i.dir = dirEOI
|
||||
return false
|
||||
}
|
||||
i.dir = dirForward
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Next() bool {
|
||||
if i.dir == dirEOI || i.err != nil {
|
||||
return false
|
||||
} else if i.dir == dirReleased {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
switch i.dir {
|
||||
case dirSOI:
|
||||
return i.First()
|
||||
case dirBackward:
|
||||
key := append([]byte{}, i.keys[i.index]...)
|
||||
if !i.Seek(key) {
|
||||
return false
|
||||
}
|
||||
return i.Next()
|
||||
}
|
||||
|
||||
x := i.index
|
||||
iter := i.iters[x]
|
||||
switch {
|
||||
case iter.Next():
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
return i.next()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) prev() bool {
|
||||
var key []byte
|
||||
if i.dir == dirBackward {
|
||||
key = i.keys[i.index]
|
||||
}
|
||||
for x, tkey := range i.keys {
|
||||
if tkey != nil && (key == nil || i.cmp.Compare(tkey, key) > 0) {
|
||||
key = tkey
|
||||
i.index = x
|
||||
}
|
||||
}
|
||||
if key == nil {
|
||||
i.dir = dirSOI
|
||||
return false
|
||||
}
|
||||
i.dir = dirBackward
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Prev() bool {
|
||||
if i.dir == dirSOI || i.err != nil {
|
||||
return false
|
||||
} else if i.dir == dirReleased {
|
||||
i.err = ErrIterReleased
|
||||
return false
|
||||
}
|
||||
|
||||
switch i.dir {
|
||||
case dirEOI:
|
||||
return i.Last()
|
||||
case dirForward:
|
||||
key := append([]byte{}, i.keys[i.index]...)
|
||||
for x, iter := range i.iters {
|
||||
if x == i.index {
|
||||
continue
|
||||
}
|
||||
seek := iter.Seek(key)
|
||||
switch {
|
||||
case seek && iter.Prev(), !seek && iter.Last():
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x := i.index
|
||||
iter := i.iters[x]
|
||||
switch {
|
||||
case iter.Prev():
|
||||
i.keys[x] = assertKey(iter.Key())
|
||||
case i.iterErr(iter):
|
||||
return false
|
||||
default:
|
||||
i.keys[x] = nil
|
||||
}
|
||||
return i.prev()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Key() []byte {
|
||||
if i.err != nil || i.dir <= dirEOI {
|
||||
return nil
|
||||
}
|
||||
return i.keys[i.index]
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Value() []byte {
|
||||
if i.err != nil || i.dir <= dirEOI {
|
||||
return nil
|
||||
}
|
||||
return i.iters[i.index].Value()
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Release() {
|
||||
if i.dir != dirReleased {
|
||||
i.dir = dirReleased
|
||||
for _, iter := range i.iters {
|
||||
iter.Release()
|
||||
}
|
||||
i.iters = nil
|
||||
i.keys = nil
|
||||
if i.releaser != nil {
|
||||
i.releaser.Release()
|
||||
i.releaser = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (i *mergedIterator) SetReleaser(releaser util.Releaser) {
|
||||
if i.dir == dirReleased {
|
||||
panic(util.ErrReleased)
|
||||
}
|
||||
if i.releaser != nil && releaser != nil {
|
||||
panic(util.ErrHasReleaser)
|
||||
}
|
||||
i.releaser = releaser
|
||||
}
|
||||
|
||||
func (i *mergedIterator) Error() error {
|
||||
return i.err
|
||||
}
|
||||
|
||||
func (i *mergedIterator) SetErrorCallback(f func(err error)) {
|
||||
i.errf = f
|
||||
}
|
||||
|
||||
// NewMergedIterator returns an iterator that merges its input. Walking the
|
||||
// resultant iterator will return all key/value pairs of all input iterators
|
||||
// in strictly increasing key order, as defined by cmp.
|
||||
// The input's key ranges may overlap, but there are assumed to be no duplicate
|
||||
// keys: if iters[i] contains a key k then iters[j] will not contain that key k.
|
||||
// None of the iters may be nil.
|
||||
//
|
||||
// If strict is true the any 'corruption errors' (i.e errors.IsCorrupted(err) == true)
|
||||
// won't be ignored and will halt 'merged iterator', otherwise the iterator will
|
||||
// continue to the next 'input iterator'.
|
||||
func NewMergedIterator(iters []Iterator, cmp comparer.Comparer, strict bool) Iterator {
|
||||
return &mergedIterator{
|
||||
iters: iters,
|
||||
cmp: cmp,
|
||||
strict: strict,
|
||||
keys: make([][]byte, len(iters)),
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user