aboutsummaryrefslogtreecommitdiffstats
path: root/store.go
diff options
context:
space:
mode:
Diffstat (limited to 'store.go')
-rw-r--r--store.go66
1 files changed, 40 insertions, 26 deletions
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()