-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
remove cache dependency and fixup comments
- Loading branch information
Showing
5 changed files
with
126 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
module github.com/chirst/cdb | ||
|
||
go 1.22 | ||
|
||
require github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package cache | ||
|
||
import "slices" | ||
|
||
// lruPageCache implements pageCache | ||
type lruPageCache struct { | ||
cache map[int][]byte | ||
// evictList maintains an ordered list of keys currently in the cache. The | ||
// list is ordered by the least recently used item at the 0th index of the | ||
// list. | ||
evictList []int | ||
maxSize int | ||
} | ||
|
||
// NewLRU creates a LRU (least recently used) cache. This cache takes a maxSize | ||
// which determines how many items can be cached. When the maximum size of the | ||
// cache is exceeded, the least recently used item will be evicted. | ||
func NewLRU(maxSize int) *lruPageCache { | ||
return &lruPageCache{ | ||
cache: map[int][]byte{}, | ||
evictList: []int{}, | ||
maxSize: maxSize, | ||
} | ||
} | ||
|
||
// Get returns a bool indicating if the key was found and the value for the key. | ||
func (c *lruPageCache) Get(key int) (value []byte, hit bool) { | ||
v, ok := c.cache[key] | ||
if !ok { | ||
return nil, false | ||
} | ||
c.prioritize(key) | ||
return v, true | ||
} | ||
|
||
// Add adds the key to the cache and prioritizes it. If a collision occurs, the | ||
// key will be prioritized and the value will be updated. | ||
func (c *lruPageCache) Add(key int, value []byte) { | ||
if _, ok := c.cache[key]; ok { | ||
c.prioritize(key) | ||
c.cache[key] = value | ||
return | ||
} | ||
if c.maxSize == len(c.cache) { | ||
c.evict() | ||
} | ||
c.cache[key] = value | ||
c.evictList = append(c.evictList, key) | ||
} | ||
|
||
// Remove removes the key from the cache. If the key is not found it will be | ||
// ignored. | ||
func (c *lruPageCache) Remove(key int) { | ||
if _, ok := c.cache[key]; ok { | ||
delete(c.cache, key) | ||
i := slices.Index(c.evictList, key) | ||
c.evictList = slices.Delete(c.evictList, i, i+1) | ||
} | ||
} | ||
|
||
func (c *lruPageCache) prioritize(key int) { | ||
i := slices.Index(c.evictList, key) | ||
c.evictList = append(slices.Delete(c.evictList, i, i+1), key) | ||
} | ||
|
||
func (c *lruPageCache) evict() { | ||
evictKey := c.evictList[0] | ||
c.evictList = c.evictList[1:] | ||
delete(c.cache, evictKey) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package cache | ||
|
||
import "testing" | ||
|
||
func TestCache(t *testing.T) { | ||
c := NewLRU(5) | ||
c.Add(5, []byte{5}) | ||
c.Add(8, []byte{8}) | ||
c.Add(12, []byte{12}) | ||
c.Add(21, []byte{21}) | ||
c.Add(240, []byte{240}) | ||
|
||
c.Get(5) | ||
c.Get(12) | ||
c.Get(8) | ||
c.Get(240) | ||
|
||
c.Add(241, []byte{241}) | ||
|
||
if cl := len(c.cache); cl != 5 { | ||
t.Fatalf("expected cache size 5 got %d", cl) | ||
} | ||
if _, ok := c.cache[5]; !ok { | ||
t.Fatal("expected cache[5] to be ok") | ||
} | ||
if _, ok := c.cache[12]; !ok { | ||
t.Fatal("expected cache[12] to be ok") | ||
} | ||
if _, ok := c.cache[8]; !ok { | ||
t.Fatal("expected cache[8] to be ok") | ||
} | ||
if _, ok := c.cache[240]; !ok { | ||
t.Fatal("expected cache[240] to be ok") | ||
} | ||
if _, ok := c.cache[241]; !ok { | ||
t.Fatal("expected cache[241] to be ok") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters