| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package bigcache
- import "sync"
- type iteratorError string
- func (e iteratorError) Error() string {
- return string(e)
- }
- // ErrInvalidIteratorState is reported when iterator is in invalid state
- const ErrInvalidIteratorState = iteratorError("Iterator is in invalid state. Use SetNext() to move to next position")
- // ErrCannotRetrieveEntry is reported when entry cannot be retrieved from underlying
- const ErrCannotRetrieveEntry = iteratorError("Could not retrieve entry from cache")
- var emptyEntryInfo = EntryInfo{}
- // EntryInfo holds informations about entry in the cache
- type EntryInfo struct {
- timestamp uint64
- hash uint64
- key string
- value []byte
- }
- // Key returns entry's underlying key
- func (e EntryInfo) Key() string {
- return e.key
- }
- // Hash returns entry's hash value
- func (e EntryInfo) Hash() uint64 {
- return e.hash
- }
- // Timestamp returns entry's timestamp (time of insertion)
- func (e EntryInfo) Timestamp() uint64 {
- return e.timestamp
- }
- // Value returns entry's underlying value
- func (e EntryInfo) Value() []byte {
- return e.value
- }
- // EntryInfoIterator allows to iterate over entries in the cache
- type EntryInfoIterator struct {
- mutex sync.Mutex
- cache *BigCache
- currentShard int
- currentIndex int
- elements []uint32
- elementsCount int
- valid bool
- }
- // SetNext moves to next element and returns true if it exists.
- func (it *EntryInfoIterator) SetNext() bool {
- it.mutex.Lock()
- it.valid = false
- it.currentIndex++
- if it.elementsCount > it.currentIndex {
- it.valid = true
- it.mutex.Unlock()
- return true
- }
- for i := it.currentShard + 1; i < it.cache.config.Shards; i++ {
- it.elements, it.elementsCount = it.cache.shards[i].copyKeys()
- // Non empty shard - stick with it
- if it.elementsCount > 0 {
- it.currentIndex = 0
- it.currentShard = i
- it.valid = true
- it.mutex.Unlock()
- return true
- }
- }
- it.mutex.Unlock()
- return false
- }
- func newIterator(cache *BigCache) *EntryInfoIterator {
- elements, count := cache.shards[0].copyKeys()
- return &EntryInfoIterator{
- cache: cache,
- currentShard: 0,
- currentIndex: -1,
- elements: elements,
- elementsCount: count,
- }
- }
- // Value returns current value from the iterator
- func (it *EntryInfoIterator) Value() (EntryInfo, error) {
- it.mutex.Lock()
- if !it.valid {
- it.mutex.Unlock()
- return emptyEntryInfo, ErrInvalidIteratorState
- }
- entry, err := it.cache.shards[it.currentShard].getEntry(int(it.elements[it.currentIndex]))
- if err != nil {
- it.mutex.Unlock()
- return emptyEntryInfo, ErrCannotRetrieveEntry
- }
- it.mutex.Unlock()
- return EntryInfo{
- timestamp: readTimestampFromEntry(entry),
- hash: readHashFromEntry(entry),
- key: readKeyFromEntry(entry),
- value: readEntry(entry),
- }, nil
- }
|