Merge pull request #130443 from serathius/watchcache-limit

Remove limit support from btree store
This commit is contained in:
Kubernetes Prow Robot
2025-02-26 05:12:30 -08:00
committed by GitHub
5 changed files with 21 additions and 44 deletions

View File

@@ -73,7 +73,7 @@ type storeIndexer interface {
} }
type orderedLister interface { type orderedLister interface {
ListPrefix(prefix, continueKey string, limit int) (items []interface{}, hasMore bool) ListPrefix(prefix, continueKey string) []interface{}
Count(prefix, continueKey string) (count int) Count(prefix, continueKey string) (count int)
Clone() orderedLister Clone() orderedLister
} }

View File

@@ -18,7 +18,6 @@ package cacher
import ( import (
"fmt" "fmt"
"math"
"strings" "strings"
"sync" "sync"
@@ -100,10 +99,10 @@ func (si *threadedStoreIndexer) List() []interface{} {
return si.store.List() return si.store.List()
} }
func (si *threadedStoreIndexer) ListPrefix(prefix, continueKey string, limit int) ([]interface{}, bool) { func (si *threadedStoreIndexer) ListPrefix(prefix, continueKey string) []interface{} {
si.lock.RLock() si.lock.RLock()
defer si.lock.RUnlock() defer si.lock.RUnlock()
return si.store.ListPrefix(prefix, continueKey, limit) return si.store.ListPrefix(prefix, continueKey)
} }
func (si *threadedStoreIndexer) ListKeys() []string { func (si *threadedStoreIndexer) ListKeys() []string {
@@ -254,31 +253,19 @@ func (s *btreeStore) getByKey(key string) (item interface{}, exists bool, err er
return item, exists, nil return item, exists, nil
} }
func (s *btreeStore) ListPrefix(prefix, continueKey string, limit int) ([]interface{}, bool) { func (s *btreeStore) ListPrefix(prefix, continueKey string) []interface{} {
if limit < 0 {
return nil, false
}
if continueKey == "" { if continueKey == "" {
continueKey = prefix continueKey = prefix
} }
var result []interface{} var result []interface{}
var hasMore bool
if limit == 0 {
limit = math.MaxInt
}
s.tree.AscendGreaterOrEqual(&storeElement{Key: continueKey}, func(item *storeElement) bool { s.tree.AscendGreaterOrEqual(&storeElement{Key: continueKey}, func(item *storeElement) bool {
if !strings.HasPrefix(item.Key, prefix) { if !strings.HasPrefix(item.Key, prefix) {
return false return false
} }
// TODO: Might be worth to lookup one more item to provide more accurate HasMore.
if len(result) >= limit {
hasMore = true
return false
}
result = append(result, item) result = append(result, item)
return true return true
}) })
return result, hasMore return result
} }
func (s *btreeStore) Count(prefix, continueKey string) (count int) { func (s *btreeStore) Count(prefix, continueKey string) (count int) {

View File

@@ -41,40 +41,30 @@ func TestStoreListPrefix(t *testing.T) {
assert.NoError(t, store.Add(testStorageElement("foo2", "bar1", 3))) assert.NoError(t, store.Add(testStorageElement("foo2", "bar1", 3)))
assert.NoError(t, store.Add(testStorageElement("bar", "baz", 4))) assert.NoError(t, store.Add(testStorageElement("bar", "baz", 4)))
items, hasMore := store.ListPrefix("foo", "", 0) items := store.ListPrefix("foo", "")
assert.False(t, hasMore)
assert.Equal(t, []interface{}{ assert.Equal(t, []interface{}{
testStorageElement("foo1", "bar2", 2), testStorageElement("foo1", "bar2", 2),
testStorageElement("foo2", "bar1", 3), testStorageElement("foo2", "bar1", 3),
testStorageElement("foo3", "bar3", 1), testStorageElement("foo3", "bar3", 1),
}, items) }, items)
items, hasMore = store.ListPrefix("foo2", "", 0) items = store.ListPrefix("foo2", "")
assert.False(t, hasMore)
assert.Equal(t, []interface{}{ assert.Equal(t, []interface{}{
testStorageElement("foo2", "bar1", 3), testStorageElement("foo2", "bar1", 3),
}, items) }, items)
items, hasMore = store.ListPrefix("foo", "", 1) items = store.ListPrefix("foo", "foo1\x00")
assert.True(t, hasMore)
assert.Equal(t, []interface{}{
testStorageElement("foo1", "bar2", 2),
}, items)
items, hasMore = store.ListPrefix("foo", "foo1\x00", 1)
assert.True(t, hasMore)
assert.Equal(t, []interface{}{ assert.Equal(t, []interface{}{
testStorageElement("foo2", "bar1", 3), testStorageElement("foo2", "bar1", 3),
testStorageElement("foo3", "bar3", 1),
}, items) }, items)
items, hasMore = store.ListPrefix("foo", "foo2\x00", 1) items = store.ListPrefix("foo", "foo2\x00")
assert.False(t, hasMore)
assert.Equal(t, []interface{}{ assert.Equal(t, []interface{}{
testStorageElement("foo3", "bar3", 1), testStorageElement("foo3", "bar3", 1),
}, items) }, items)
items, hasMore = store.ListPrefix("bar", "", 0) items = store.ListPrefix("bar", "")
assert.False(t, hasMore)
assert.Equal(t, []interface{}{ assert.Equal(t, []interface{}{
testStorageElement("bar", "baz", 4), testStorageElement("bar", "baz", 4),
}, items) }, items)
@@ -143,7 +133,7 @@ func (f fakeOrderedLister) Add(obj interface{}) error { return nil }
func (f fakeOrderedLister) Update(obj interface{}) error { return nil } func (f fakeOrderedLister) Update(obj interface{}) error { return nil }
func (f fakeOrderedLister) Delete(obj interface{}) error { return nil } func (f fakeOrderedLister) Delete(obj interface{}) error { return nil }
func (f fakeOrderedLister) Clone() orderedLister { return f } func (f fakeOrderedLister) Clone() orderedLister { return f }
func (f fakeOrderedLister) ListPrefix(prefixKey, continueKey string, limit int) ([]interface{}, bool) { func (f fakeOrderedLister) ListPrefix(prefixKey, continueKey string) []interface{} {
return nil, false return nil
} }
func (f fakeOrderedLister) Count(prefixKey, continueKey string) int { return 0 } func (f fakeOrderedLister) Count(prefixKey, continueKey string) int { return 0 }

View File

@@ -523,7 +523,7 @@ func (w *watchCache) WaitUntilFreshAndList(ctx context.Context, resourceVersion
} }
} }
if store, ok := w.store.(orderedLister); ok { if store, ok := w.store.(orderedLister); ok {
result, _ := store.ListPrefix(key, "", 0) result := store.ListPrefix(key, "")
return listResp{ return listResp{
Items: result, Items: result,
ResourceVersion: w.resourceVersion, ResourceVersion: w.resourceVersion,

View File

@@ -1318,7 +1318,7 @@ func TestCacheSnapshots(t *testing.T) {
assert.False(t, found, "Expected store to not include rev 99") assert.False(t, found, "Expected store to not include rev 99")
lister, found := store.snapshots.GetLessOrEqual(100) lister, found := store.snapshots.GetLessOrEqual(100)
assert.True(t, found, "Expected store to not include rev 100") assert.True(t, found, "Expected store to not include rev 100")
elements, _ := lister.ListPrefix("", "", 0) elements := lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 100), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 100), elements[0].(*storeElement).Object)
@@ -1330,20 +1330,20 @@ func TestCacheSnapshots(t *testing.T) {
t.Log("Test cache on rev 200") t.Log("Test cache on rev 200")
lister, found = store.snapshots.GetLessOrEqual(200) lister, found = store.snapshots.GetLessOrEqual(200)
assert.True(t, found, "Expected store to still keep rev 200") assert.True(t, found, "Expected store to still keep rev 200")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 200), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 200), elements[0].(*storeElement).Object)
t.Log("Test cache on rev 300") t.Log("Test cache on rev 300")
lister, found = store.snapshots.GetLessOrEqual(300) lister, found = store.snapshots.GetLessOrEqual(300)
assert.True(t, found, "Expected store to still keep rev 300") assert.True(t, found, "Expected store to still keep rev 300")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Empty(t, elements) assert.Empty(t, elements)
t.Log("Test cache on rev 400") t.Log("Test cache on rev 400")
lister, found = store.snapshots.GetLessOrEqual(400) lister, found = store.snapshots.GetLessOrEqual(400)
assert.True(t, found, "Expected store to still keep rev 400") assert.True(t, found, "Expected store to still keep rev 400")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 400), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 400), elements[0].(*storeElement).Object)
@@ -1359,7 +1359,7 @@ func TestCacheSnapshots(t *testing.T) {
t.Log("Test cache on rev 500") t.Log("Test cache on rev 500")
lister, found = store.snapshots.GetLessOrEqual(500) lister, found = store.snapshots.GetLessOrEqual(500)
assert.True(t, found, "Expected store to still keep rev 500") assert.True(t, found, "Expected store to still keep rev 500")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 500), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 500), elements[0].(*storeElement).Object)
@@ -1371,7 +1371,7 @@ func TestCacheSnapshots(t *testing.T) {
t.Log("Test cache on rev 600") t.Log("Test cache on rev 600")
lister, found = store.snapshots.GetLessOrEqual(600) lister, found = store.snapshots.GetLessOrEqual(600)
assert.True(t, found, "Expected replace to be snapshotted") assert.True(t, found, "Expected replace to be snapshotted")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 600), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 600), elements[0].(*storeElement).Object)
@@ -1388,7 +1388,7 @@ func TestCacheSnapshots(t *testing.T) {
t.Log("Test cache on rev 700") t.Log("Test cache on rev 700")
lister, found = store.snapshots.GetLessOrEqual(700) lister, found = store.snapshots.GetLessOrEqual(700)
assert.True(t, found, "Expected replace to be snapshotted") assert.True(t, found, "Expected replace to be snapshotted")
elements, _ = lister.ListPrefix("", "", 0) elements = lister.ListPrefix("", "")
assert.Len(t, elements, 1) assert.Len(t, elements, 1)
assert.Equal(t, makeTestPod("foo", 600), elements[0].(*storeElement).Object) assert.Equal(t, makeTestPod("foo", 600), elements[0].(*storeElement).Object)
} }