aboutsummaryrefslogtreecommitdiffstats
path: root/map.go
diff options
context:
space:
mode:
authorMarc Pervaz Boocha <marcpervaz@qburst.com>2025-02-17 18:39:54 +0530
committerMarc Pervaz Boocha <marcpervaz@qburst.com>2025-02-17 18:39:54 +0530
commit6c6535120ca43a57d31b60ae386c34339b44fa10 (patch)
treeb3387a3ed7d096ec0eef60941293397e4201dced /map.go
parentFirst Commit (diff)
downloadcache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar.gz
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar.bz2
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar.lz
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar.xz
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.tar.zst
cache-6c6535120ca43a57d31b60ae386c34339b44fa10.zip
Bootstraped code for housekeeping operations
Diffstat (limited to '')
-rw-r--r--map.go95
1 files changed, 62 insertions, 33 deletions
diff --git a/map.go b/map.go
index 71bc16b..cc55272 100644
--- a/map.go
+++ b/map.go
@@ -2,17 +2,11 @@ package cache
import (
"bytes"
- "hash/fnv"
"iter"
"sync"
"time"
)
-func zero[T any]() T {
- var ret T
- return ret
-}
-
type Map[K any, V any] interface {
Set(key K, value V, ttl time.Duration) error
Get(key K) (V, time.Duration, error)
@@ -32,16 +26,29 @@ type Node struct {
EvictPrev *Node
}
+func (n *Node) IsValid() bool {
+ return n.Expiration.IsZero() || n.Expiration.After(time.Now())
+}
+
+func (n *Node) Detach() {
+}
+
type Store struct {
bucket []Node
lenght uint64
cost uint64
evict Node
- max_cost uint64
- strategy EvictionStrategies
+ maxCost uint64
+ strategy EvictionPolicy
mu sync.RWMutex
}
+func (s *Store) Init() {
+ s.Clear()
+ s.strategy.evict = &s.evict
+ s.strategy.SetPolicy(StrategyNone)
+}
+
func (s *Store) Clear() {
s.mu.Lock()
defer s.mu.Unlock()
@@ -54,14 +61,6 @@ func (s *Store) Clear() {
s.evict.EvictPrev = &s.evict
}
-func hash(data []byte) uint64 {
- hasher := fnv.New64()
- if _, err := hasher.Write(data); err != nil {
- panic(err)
- }
- return hasher.Sum64()
-}
-
func lookup(s *Store, key []byte) (uint64, uint64) {
hash := hash(key)
return hash % uint64(len(s.bucket)), hash
@@ -86,8 +85,11 @@ func (s *Store) Get(key []byte) ([]byte, time.Duration, bool) {
for v := bucket.HashNext; v != bucket; v = v.HashNext {
if bytes.Equal(key, v.Key) {
+ if !v.IsValid() {
+ return nil, 0, false
+ }
s.strategy.OnAccess(v)
- return v.Value, 0, true
+ return v.Value, time.Until(v.Expiration), true
}
}
@@ -98,6 +100,9 @@ func resize(s *Store) {
bucket := make([]Node, 2*len(s.bucket))
for v := s.evict.EvictNext; v != &s.evict; v = v.EvictNext {
+ if !v.IsValid() {
+ continue
+ }
idx := v.Hash % uint64(len(bucket))
n := &bucket[idx]
@@ -112,6 +117,23 @@ func resize(s *Store) {
s.bucket = bucket
}
+func cleanup(s *Store) {
+ for v := s.evict.EvictNext; v != &s.evict; v = v.EvictNext {
+ if !v.IsValid() {
+ deleteNode(s, v)
+ }
+ }
+}
+
+func evict(s *Store) bool {
+ n := s.strategy.Evict()
+ if n == nil {
+ return false
+ }
+ deleteNode(s, n)
+ return true
+}
+
func (s *Store) Set(key []byte, value []byte, ttl time.Duration) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -138,10 +160,13 @@ func (s *Store) Set(key []byte, value []byte, ttl time.Duration) {
}
node := &Node{
- Hash: hash,
- Key: key,
- Value: value,
- Expiration: time.Now().Add(ttl),
+ Hash: hash,
+ Key: key,
+ Value: value,
+ }
+
+ if ttl != 0 {
+ node.Expiration = time.Now().Add(ttl)
}
node.HashPrev = bucket
@@ -156,6 +181,21 @@ func (s *Store) Set(key []byte, value []byte, ttl time.Duration) {
s.lenght = s.lenght + 1
}
+func deleteNode(s *Store, v *Node) {
+ v.HashNext.HashPrev = v.HashPrev
+ v.HashPrev.HashNext = v.HashNext
+ v.HashNext = nil
+ v.HashPrev = nil
+
+ v.EvictNext.EvictPrev = v.EvictPrev
+ v.EvictPrev.EvictNext = v.EvictNext
+ v.EvictNext = nil
+ v.EvictPrev = nil
+
+ s.cost = s.cost - (uint64(len(v.Key)) + uint64(len(v.Value)))
+ s.lenght = s.lenght - 1
+}
+
func (s *Store) Delete(key []byte) bool {
s.mu.Lock()
defer s.mu.Unlock()
@@ -168,18 +208,7 @@ func (s *Store) Delete(key []byte) bool {
for v := bucket.HashNext; v != bucket; v = v.HashNext {
if bytes.Equal(key, v.Key) {
- v.HashNext.HashPrev = v.HashPrev
- v.HashPrev.HashNext = v.HashNext
- v.HashNext = nil
- v.HashPrev = nil
-
- v.EvictNext.EvictPrev = v.EvictPrev
- v.EvictPrev.EvictNext = v.EvictNext
- v.EvictNext = nil
- v.EvictPrev = nil
-
- s.cost = s.cost - (uint64(len(v.Key)) + uint64(len(v.Value)))
- s.lenght = s.lenght - 1
+ deleteNode(s, v)
return true
}
}