62 lines
1.5 KiB
Go
62 lines
1.5 KiB
Go
package types
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// KVStorePrefixIteratorPaginated returns iterator over items in the selected page.
|
|
// Items iterated and skipped in ascending order.
|
|
func KVStorePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator {
|
|
pi := &PaginatedIterator{
|
|
Iterator: KVStorePrefixIterator(kvs, prefix),
|
|
page: page,
|
|
limit: limit,
|
|
}
|
|
pi.skip()
|
|
return pi
|
|
}
|
|
|
|
// KVStoreReversePrefixIteratorPaginated returns iterator over items in the selected page.
|
|
// Items iterated and skipped in descending order.
|
|
func KVStoreReversePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator {
|
|
pi := &PaginatedIterator{
|
|
Iterator: KVStoreReversePrefixIterator(kvs, prefix),
|
|
page: page,
|
|
limit: limit,
|
|
}
|
|
pi.skip()
|
|
return pi
|
|
}
|
|
|
|
// PaginatedIterator is a wrapper around Iterator that iterates over values starting for given page and limit.
|
|
type PaginatedIterator struct {
|
|
Iterator
|
|
|
|
page, limit uint // provided during initialization
|
|
iterated uint // incremented in a call to Next
|
|
|
|
}
|
|
|
|
func (pi *PaginatedIterator) skip() {
|
|
for i := (pi.page - 1) * pi.limit; i > 0 && pi.Iterator.Valid(); i-- {
|
|
pi.Iterator.Next()
|
|
}
|
|
}
|
|
|
|
// Next will panic after limit is reached.
|
|
func (pi *PaginatedIterator) Next() {
|
|
if !pi.Valid() {
|
|
panic(fmt.Sprintf("PaginatedIterator reached limit %d", pi.limit))
|
|
}
|
|
pi.Iterator.Next()
|
|
pi.iterated++
|
|
}
|
|
|
|
// Valid if below limit and underlying iterator is valid.
|
|
func (pi *PaginatedIterator) Valid() bool {
|
|
if pi.iterated >= pi.limit {
|
|
return false
|
|
}
|
|
return pi.Iterator.Valid()
|
|
}
|