From a5194b3be4768d42b27ef9e2d0d52479e0436758 Mon Sep 17 00:00:00 2001 From: Marc Pervaz Boocha Date: Tue, 25 Feb 2025 09:47:02 +0530 Subject: Removed testify and improved tests --- store.go | 66 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'store.go') diff --git a/store.go b/store.go index 8747cd2..4fcd60d 100644 --- a/store.go +++ b/store.go @@ -10,25 +10,27 @@ import ( const initialBucketSize uint64 = 8 - // node represents an entry in the cache with metadata for eviction and expiration. +// node represents an entry in the cache with metadata for eviction and expiration. type node struct { Hash uint64 Expiration time.Time Access uint64 Key []byte Value []byte - HashNext *node - HashPrev *node - EvictNext *node - EvictPrev *node + mu sync.Mutex + + HashNext *node + HashPrev *node + EvictNext *node + EvictPrev *node } - // IsValid checks if the node is still valid based on its expiration time. +// IsValid checks if the node is still valid based on its expiration time. func (n *node) IsValid() bool { return n.Expiration.IsZero() || n.Expiration.After(time.Now()) } - // TTL returns the time-to-live of the node. +// TTL returns the time-to-live of the node. func (n *node) TTL() time.Duration { if n.Expiration.IsZero() { return 0 @@ -37,7 +39,7 @@ func (n *node) TTL() time.Duration { } } - // store represents the in-memory cache with eviction policies and periodic tasks. +// store represents the in-memory cache with eviction policies and periodic tasks. type store struct { Bucket []node Length uint64 @@ -47,19 +49,23 @@ type store struct { SnapshotTicker *pausedtimer.PauseTimer CleanupTicker *pausedtimer.PauseTimer Policy evictionPolicy - mu sync.Mutex + + mu sync.Mutex } - // Init initializes the store with default settings. +// Init initializes the store with default settings. func (s *store) Init() { s.Clear() s.Policy.evict = &s.Evict s.SnapshotTicker = pausedtimer.NewStopped(0) s.CleanupTicker = pausedtimer.NewStopped(10 * time.Second) - s.Policy.SetPolicy(PolicyNone) + + if err := s.Policy.SetPolicy(PolicyNone); err != nil { + panic(err) + } } - // Clear removes all entries from the store. +// Clear removes all entries from the store. func (s *store) Clear() { s.mu.Lock() defer s.mu.Unlock() @@ -72,13 +78,14 @@ func (s *store) Clear() { s.Evict.EvictPrev = &s.Evict } - // lookup calculates the hash and index for a given key. +// lookup calculates the hash and index for a given key. func lookup(s *store, key []byte) (uint64, uint64) { hash := hash(key) + return hash % uint64(len(s.Bucket)), hash } - // lazyInitBucket initializes the hash bucket if it hasn't been initialized yet. +// lazyInitBucket initializes the hash bucket if it hasn't been initialized yet. func lazyInitBucket(n *node) { if n.HashNext == nil { n.HashNext = n @@ -86,7 +93,7 @@ func lazyInitBucket(n *node) { } } - // lookup finds a node in the store by key. +// lookup finds a node in the store by key. func (s *store) lookup(key []byte) (*node, uint64, uint64) { idx, hash := lookup(s, key) @@ -103,22 +110,25 @@ func (s *store) lookup(key []byte) (*node, uint64, uint64) { return nil, idx, hash } - // get retrieves a value from the store by key. +// get retrieves a value from the store by key. func (s *store) get(key []byte) ([]byte, time.Duration, bool) { v, _, _ := s.lookup(key) if v != nil { if !v.IsValid() { deleteNode(s, v) + return nil, 0, false } + s.Policy.OnAccess(v) + return v.Value, v.TTL(), true } return nil, 0, false } - // Get retrieves a value from the store by key with locking. +// Get retrieves a value from the store by key with locking. func (s *store) Get(key []byte) ([]byte, time.Duration, bool) { s.mu.Lock() defer s.mu.Unlock() @@ -126,7 +136,7 @@ func (s *store) Get(key []byte) ([]byte, time.Duration, bool) { return s.get(key) } - // resize doubles the size of the hash table and rehashes all entries. +// resize doubles the size of the hash table and rehashes all entries. func resize(s *store) { bucket := make([]node, 2*len(s.Bucket)) @@ -149,7 +159,7 @@ func resize(s *store) { s.Bucket = bucket } - // cleanup removes expired entries from the store. +// cleanup removes expired entries from the store. func cleanup(s *store) { for v := s.Evict.EvictNext; v != &s.Evict; v = v.EvictNext { if !v.IsValid() { @@ -158,19 +168,21 @@ func cleanup(s *store) { } } - // evict removes entries from the store based on the eviction policy. +// evict removes entries from the store based on the eviction policy. func evict(s *store) bool { for s.MaxCost != 0 && s.MaxCost < s.Cost { n := s.Policy.Evict() if n == nil { break } + deleteNode(s, n) } + return true } - // set adds or updates a key-value pair in the store. +// set adds or updates a key-value pair in the store. func (s *store) set(key []byte, value []byte, ttl time.Duration) { v, idx, hash := s.lookup(key) if v != nil { @@ -181,9 +193,10 @@ func (s *store) set(key []byte, value []byte, ttl time.Duration) { } bucket := &s.Bucket[idx] + if float64(s.Length)/float64(len(s.Bucket)) > 0.75 { resize(s) - //resize may invidate pointer to bucket + // resize may invidate pointer to bucket _, idx, _ := s.lookup(key) bucket = &s.Bucket[idx] lazyInitBucket(bucket) @@ -210,7 +223,7 @@ func (s *store) set(key []byte, value []byte, ttl time.Duration) { s.Length = s.Length + 1 } - // Set adds or updates a key-value pair in the store with locking. +// Set adds or updates a key-value pair in the store with locking. func (s *store) Set(key []byte, value []byte, ttl time.Duration) { s.mu.Lock() defer s.mu.Unlock() @@ -218,7 +231,7 @@ func (s *store) Set(key []byte, value []byte, ttl time.Duration) { s.set(key, value, ttl) } - // deleteNode removes a node from the store. +// deleteNode removes a node from the store. func deleteNode(s *store, v *node) { v.HashNext.HashPrev = v.HashPrev v.HashPrev.HashNext = v.HashNext @@ -234,18 +247,19 @@ func deleteNode(s *store, v *node) { s.Length = s.Length - 1 } - // delete removes a key-value pair from the store. +// delete removes a key-value pair from the store. func (s *store) delete(key []byte) bool { v, _, _ := s.lookup(key) if v != nil { deleteNode(s, v) + return true } return false } - // Delete removes a key-value pair from the store with locking. +// Delete removes a key-value pair from the store with locking. func (s *store) Delete(key []byte) bool { s.mu.Lock() defer s.mu.Unlock() -- cgit v1.2.3-70-g09d2