mirror of
https://github.com/PeernetOfficial/Abstraction.git
synced 2026-07-19 11:57:50 +01:00
76 lines
1.7 KiB
Go
76 lines
1.7 KiB
Go
package pogreb
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
)
|
|
|
|
// ErrIterationDone is returned by ItemIterator.Next calls when there are no more items to return.
|
|
var ErrIterationDone = errors.New("no more items in iterator")
|
|
|
|
type item struct {
|
|
key []byte
|
|
value []byte
|
|
}
|
|
|
|
// ItemIterator is an iterator over DB key-value pairs. It iterates the items in an unspecified order.
|
|
type ItemIterator struct {
|
|
db *DB
|
|
nextBucketIdx uint32
|
|
queue []item
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// fetchItems adds items to the iterator queue from a bucket located at nextBucketIdx.
|
|
func (it *ItemIterator) fetchItems(nextBucketIdx uint32) error {
|
|
bit := it.db.index.newBucketIterator(nextBucketIdx)
|
|
for {
|
|
b, err := bit.next()
|
|
if err == ErrIterationDone {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for i := 0; i < slotsPerBucket; i++ {
|
|
sl := b.slots[i]
|
|
if sl.offset == 0 {
|
|
// No more items in the bucket.
|
|
break
|
|
}
|
|
key, value, err := it.db.datalog.readKeyValue(sl)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
key = cloneBytes(key)
|
|
value = cloneBytes(value)
|
|
it.queue = append(it.queue, item{key: key, value: value})
|
|
}
|
|
}
|
|
}
|
|
|
|
// Next returns the next key-value pair if available, otherwise it returns ErrIterationDone error.
|
|
func (it *ItemIterator) Next() ([]byte, []byte, error) {
|
|
it.mu.Lock()
|
|
defer it.mu.Unlock()
|
|
|
|
it.db.mu.RLock()
|
|
defer it.db.mu.RUnlock()
|
|
|
|
// The iterator queue is empty and we have more buckets to check.
|
|
for len(it.queue) == 0 && it.nextBucketIdx < it.db.index.numBuckets {
|
|
if err := it.fetchItems(it.nextBucketIdx); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
it.nextBucketIdx++
|
|
}
|
|
|
|
if len(it.queue) > 0 {
|
|
item := it.queue[0]
|
|
it.queue = it.queue[1:]
|
|
return item.key, item.value, nil
|
|
}
|
|
|
|
return nil, nil, ErrIterationDone
|
|
}
|