Skip to content

Commit

Permalink
Remove the Keys() method
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnsk committed Sep 17, 2024
1 parent 8d856f7 commit cdc21b8
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 118 deletions.
5 changes: 0 additions & 5 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ func (c *Cache[K, V]) Load(key K) (value V, loaded bool) {
return c.backend.Load(key)
}

// Keys returns keys for initialized cache elements in the sort order specified by policy.
func (c *Cache[K, V]) Keys() []K {
return c.backend.Keys()
}

// Range iterates over initialized cache elements in no particular order or consistency.
// If f returns false, range stops the iteration.
//
Expand Down
32 changes: 10 additions & 22 deletions internal/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,34 +87,22 @@ func (b *Backend[K, V]) Load(key K) (value V, ok bool) {
return zero, false
}

// Keys returns keys for initialized cache elements in the sort order specified by policy.
func (b *Backend[K, V]) Keys() []K {
b.mu.Lock()
defer b.mu.Unlock()

keys := make([]K, 0, b.list.Len())
b.list.Do(func(elem *ringlist.Element[Record[K, V]]) bool {
keys = append(keys, elem.Value.Key)
return true
})

return keys
}

// Range iterates over initialized cache elements in no particular order or consistency.
// If f returns false, range stops the iteration.
//
// f may modify the cache.
func (b *Backend[K, V]) Range(f func(key K, value V) bool) {
keys := b.Keys()

for _, key := range keys {
b.mu.Lock()
elem, ok := b.xmap[key]
initialized := ok && elem.Value.state == stateInitialized
b.mu.Unlock()
b.mu.Lock()
elems := make([]*ringlist.Element[Record[K, V]], 0, len(b.xmap))
for _, elem := range b.xmap {
if elem.Value.state == stateInitialized {
elems = append(elems, elem)
}
}
b.mu.Unlock()

if initialized && !f(key, elem.Value.Value) {
for _, elem := range elems {
if !f(elem.Value.Key, elem.Value.Value) {
return
}
}
Expand Down
20 changes: 6 additions & 14 deletions internal/backend/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,6 @@ func TestFetchCallbackBlocks(t *testing.T) {
Equal(t, b.Has("key1"), true)
})

t.Run("non-blocking Keys", func(t *testing.T) {
b.Fetch("key1", func() (string, error) {
return "value1", nil
})

keys := b.Keys()
Equal(t, len(keys), 1)
Equal(t, keys[0], "key1")
})

t.Run("non-blocking Range", func(t *testing.T) {
b.Fetch("key1", func() (string, error) {
return "value1", nil
Expand Down Expand Up @@ -433,9 +423,10 @@ func overflowAndCollectKeys(t *testing.T, b *backend.Backend[int, int], capacity
// Collect all cache keys, then overflow the cache and observe which key disappears.
t.Log("collecting current cache state")
oldKeys := map[int]struct{}{}
for _, key := range b.Keys() {
b.Range(func(key int, value int) bool {
oldKeys[key] = struct{}{}
}
return true
})
Equal(t, len(oldKeys), capacity)

t.Logf("store: %v", i)
Expand All @@ -446,9 +437,10 @@ func overflowAndCollectKeys(t *testing.T, b *backend.Backend[int, int], capacity

t.Log("collecting new cache state")
newKeys := map[int]struct{}{}
for _, key := range b.Keys() {
b.Range(func(key int, value int) bool {
newKeys[key] = struct{}{}
}
return true
})
Equal(t, len(oldKeys), capacity)

t.Log("determining the evicted key")
Expand Down
77 changes: 0 additions & 77 deletions internal/backend/benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,83 +131,6 @@ func BenchmarkSliceSort(b *testing.B) {
})
}

func BenchmarkBackendGC(b *testing.B) {
for _, n := range []int{
1e3,
1e4,
1e5,
1e6,
} {
b.Run(fmt.Sprint(n), newTimePerElementBench(
func() (*backend.Backend[int, int], int) {
var be backend.Backend[int, int]
be.Init(n, "", 0, 0)
for i := 0; i < n; i++ {
be.Store(i, 0)
}

return &be, be.Len()
},
func(be *backend.Backend[int, int]) {
keys := be.Keys()
runtime.KeepAlive(keys)
},
))
}
}

func BenchmarkBackendGCLFU(b *testing.B) {
for _, n := range []int{
1e3,
1e4,
1e5,
1e6,
} {
b.Run(fmt.Sprint(n), newTimePerElementBench(
func() (*backend.Backend[int, int], int) {
var be backend.Backend[int, int]
be.Init(n, backend.LFU, 0, 0)

for i := 0; i < n; i++ {
be.Store(i, 0)
}

return &be, be.Len()
},
func(be *backend.Backend[int, int]) {
keys := be.Keys()
runtime.KeepAlive(keys)
},
))
}
}

func BenchmarkBackendGCLRU(b *testing.B) {
for _, n := range []int{
1e3,
1e4,
1e5,
1e6,
} {
b.Run(fmt.Sprint(n), newTimePerElementBench(
func() (*backend.Backend[int, int], int) {
var be backend.Backend[int, int]
be.Init(n, backend.LRU, 0, 0)

for i := 0; i < n; i++ {
be.Store(i, 0)
}

return &be, be.Len()
},
func(be *backend.Backend[int, int]) {
keys := be.Keys()
runtime.KeepAlive(keys)
},
))
}
}

func createSlice[K comparable, V any](n int, valueFn func(*K, *V)) []*backend.Record[K, V] {
items := make([]*backend.Record[K, V], n)
for i := 0; i < len(items); i++ {
Expand Down

0 comments on commit cdc21b8

Please sign in to comment.