github.com/Finschia/finschia-sdk@v0.48.1/store/types/iterator.go (about) 1 package types 2 3 import ( 4 "fmt" 5 ) 6 7 // KVStorePrefixIteratorPaginated returns iterator over items in the selected page. 8 // Items iterated and skipped in ascending order. 9 func KVStorePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { 10 pi := &PaginatedIterator{ 11 Iterator: KVStorePrefixIterator(kvs, prefix), 12 page: page, 13 limit: limit, 14 } 15 pi.skip() 16 return pi 17 } 18 19 // KVStoreReversePrefixIteratorPaginated returns iterator over items in the selected page. 20 // Items iterated and skipped in descending order. 21 func KVStoreReversePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator { 22 pi := &PaginatedIterator{ 23 Iterator: KVStoreReversePrefixIterator(kvs, prefix), 24 page: page, 25 limit: limit, 26 } 27 pi.skip() 28 return pi 29 } 30 31 // PaginatedIterator is a wrapper around Iterator that iterates over values starting for given page and limit. 32 type PaginatedIterator struct { 33 Iterator 34 35 page, limit uint // provided during initialization 36 iterated uint // incremented in a call to Next 37 } 38 39 func (pi *PaginatedIterator) skip() { 40 for i := (pi.page - 1) * pi.limit; i > 0 && pi.Iterator.Valid(); i-- { 41 pi.Iterator.Next() 42 } 43 } 44 45 // Next will panic after limit is reached. 46 func (pi *PaginatedIterator) Next() { 47 if !pi.Valid() { 48 panic(fmt.Sprintf("PaginatedIterator reached limit %d", pi.limit)) 49 } 50 pi.Iterator.Next() 51 pi.iterated++ 52 } 53 54 // Valid if below limit and underlying iterator is valid. 55 func (pi *PaginatedIterator) Valid() bool { 56 if pi.iterated >= pi.limit { 57 return false 58 } 59 return pi.Iterator.Valid() 60 }