@@ -24,25 +24,21 @@ package cache
2424import (
2525 "container/list"
2626 "errors"
27- "fmt"
28- "strconv"
2927 "sync"
30-
31- "github.com/upper/db/v4/internal/cache/hashstructure"
3228)
3329
3430const defaultCapacity = 128
3531
3632// Cache holds a map of volatile key -> values.
3733type Cache struct {
38- cache map [string ]* list.Element
39- li * list.List
40- capacity int
34+ keys * list.List
35+ items map [uint64 ]* list.Element
4136 mu sync.RWMutex
37+ capacity int
4238}
4339
44- type item struct {
45- key string
40+ type cacheItem struct {
41+ key uint64
4642 value interface {}
4743}
4844
@@ -52,11 +48,11 @@ func NewCacheWithCapacity(capacity int) (*Cache, error) {
5248 if capacity < 1 {
5349 return nil , errors .New ("Capacity must be greater than zero." )
5450 }
55- return & Cache {
56- cache : make (map [string ]* list.Element ),
57- li : list .New (),
51+ c := & Cache {
5852 capacity : capacity ,
59- }, nil
53+ }
54+ c .init ()
55+ return c , nil
6056}
6157
6258// NewCache initializes a new caching space with default settings.
@@ -68,6 +64,11 @@ func NewCache() *Cache {
6864 return c
6965}
7066
67+ func (c * Cache ) init () {
68+ c .items = make (map [uint64 ]* list.Element )
69+ c .keys = list .New ()
70+ }
71+
7172// Read attempts to retrieve a cached value as a string, if the value does not
7273// exists returns an empty string and false.
7374func (c * Cache ) Read (h Hashable ) (string , bool ) {
@@ -84,33 +85,35 @@ func (c *Cache) Read(h Hashable) (string, bool) {
8485func (c * Cache ) ReadRaw (h Hashable ) (interface {}, bool ) {
8586 c .mu .RLock ()
8687 defer c .mu .RUnlock ()
87- data , ok := c .cache [h .Hash ()]
88+
89+ item , ok := c .items [h .Hash ()]
8890 if ok {
89- return data .Value .(* item ).value , true
91+ return item .Value .(* cacheItem ).value , true
9092 }
93+
9194 return nil , false
9295}
9396
9497// Write stores a value in memory. If the value already exists its overwritten.
9598func (c * Cache ) Write (h Hashable , value interface {}) {
96- key := h .Hash ()
97-
9899 c .mu .Lock ()
99100 defer c .mu .Unlock ()
100101
101- if el , ok := c .cache [key ]; ok {
102- el .Value .(* item ).value = value
103- c .li .MoveToFront (el )
102+ key := h .Hash ()
103+
104+ if item , ok := c .items [key ]; ok {
105+ item .Value .(* cacheItem ).value = value
106+ c .keys .MoveToFront (item )
104107 return
105108 }
106109
107- c .cache [key ] = c .li .PushFront (& item {key , value })
110+ c .items [key ] = c .keys .PushFront (& cacheItem {key , value })
108111
109- for c .li .Len () > c .capacity {
110- el := c .li .Remove (c .li .Back ())
111- delete (c .cache , el .( * item ) .key )
112- if p , ok := el .( * item ) .value .(HasOnPurge ); ok {
113- p .OnPurge ()
112+ for c .keys .Len () > c .capacity {
113+ item := c .keys .Remove (c .keys .Back ()).( * cacheItem )
114+ delete (c .items , item .key )
115+ if p , ok := item .value .(HasOnEvict ); ok {
116+ p .OnEvict ()
114117 }
115118 }
116119}
@@ -120,33 +123,12 @@ func (c *Cache) Write(h Hashable, value interface{}) {
120123func (c * Cache ) Clear () {
121124 c .mu .Lock ()
122125 defer c .mu .Unlock ()
123- for _ , el := range c .cache {
124- if p , ok := el .Value .(* item ).value .(HasOnPurge ); ok {
125- p .OnPurge ()
126- }
127- }
128- c .cache = make (map [string ]* list.Element )
129- c .li .Init ()
130- }
131126
132- // Hash returns a hash of the given struct.
133- func Hash (v interface {}) string {
134- q , err := hashstructure .Hash (v , nil )
135- if err != nil {
136- panic (fmt .Sprintf ("Could not hash struct: %v" , err .Error ()))
127+ for _ , item := range c .items {
128+ if p , ok := item .Value .(* cacheItem ).value .(HasOnEvict ); ok {
129+ p .OnEvict ()
130+ }
137131 }
138- return strconv .FormatUint (q , 10 )
139- }
140-
141- type hash struct {
142- name string
143- }
144-
145- func (h * hash ) Hash () string {
146- return h .name
147- }
148132
149- // String returns a Hashable that produces a hash equal to the given string.
150- func String (s string ) Hashable {
151- return & hash {s }
133+ c .init ()
152134}
0 commit comments