Skip to content

Commit d65878b

Browse files
Merge pull request #64 from stevekuznetsov/skuznets/add-filter-funcs
🐛 pkg/cache: make index accessors similar to upstream
2 parents 9e1e139 + f809b80 commit d65878b

File tree

1 file changed

+64
-42
lines changed

1 file changed

+64
-42
lines changed

pkg/cache/listers.go

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ package cache
1818

1919
import (
2020
"github.com/kcp-dev/logicalcluster/v2"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
"k8s.io/apimachinery/pkg/util/sets"
23+
"k8s.io/klog/v2"
2124

2225
"k8s.io/apimachinery/pkg/api/errors"
2326
"k8s.io/apimachinery/pkg/api/meta"
@@ -27,6 +30,61 @@ import (
2730
"k8s.io/client-go/tools/cache"
2831
)
2932

33+
// ListAllByCluster used to list items belongs to a cluster from Indexer.
34+
func ListAllByCluster(indexer cache.Indexer, cluster logicalcluster.Name, selector labels.Selector, appendFn cache.AppendFunc) error {
35+
return listAllByIndexWithBackup(indexer, ClusterIndexName, ClusterIndexKey(cluster), ClusterIndexFunc, selector, appendFn)
36+
}
37+
38+
// ListAllByClusterAndNamespace used to list items belongs to a cluster and namespace from Indexer.
39+
func ListAllByClusterAndNamespace(indexer cache.Indexer, cluster logicalcluster.Name, namespace string, selector labels.Selector, appendFn cache.AppendFunc) error {
40+
if namespace == metav1.NamespaceAll {
41+
return ListAllByCluster(indexer, cluster, selector, appendFn)
42+
}
43+
return listAllByIndexWithBackup(indexer, ClusterAndNamespaceIndexName, ClusterAndNamespaceIndexKey(cluster, namespace), ClusterAndNamespaceIndexFunc, selector, appendFn)
44+
}
45+
46+
// listAllByIndexWithBackup used to list items from the Indexer using an index, or falling back to a func if no index is registered.
47+
func listAllByIndexWithBackup(indexer cache.Indexer, indexName, indexKey string, indexFunc cache.IndexFunc, selector labels.Selector, appendFn cache.AppendFunc) error {
48+
var items []interface{}
49+
var err error
50+
items, err = indexer.ByIndex(indexName, indexKey)
51+
if err != nil {
52+
// Ignore error; do slow search without index.
53+
klog.Warningf("can not retrieve list of objects using index : %v", err)
54+
for _, item := range indexer.List() {
55+
keys, err := indexFunc(item)
56+
if err != nil {
57+
return err
58+
}
59+
if sets.NewString(keys...).Has(indexKey) {
60+
items = append(items, item)
61+
}
62+
}
63+
}
64+
return appendMatchingObjects(items, selector, appendFn)
65+
}
66+
67+
func appendMatchingObjects(items []interface{}, selector labels.Selector, appendFn cache.AppendFunc) error {
68+
selectAll := selector == nil || selector.Empty()
69+
for _, item := range items {
70+
if selectAll {
71+
// Avoid computing labels of the objects to speed up common flows
72+
// of listing all objects.
73+
appendFn(item)
74+
continue
75+
}
76+
metadata, err := meta.Accessor(item)
77+
if err != nil {
78+
return err
79+
}
80+
if selector.Matches(labels.Set(metadata.GetLabels())) {
81+
appendFn(item)
82+
}
83+
}
84+
85+
return nil
86+
}
87+
3088
// NewGenericClusterLister creates a new instance for the ClusterLister.
3189
func NewGenericClusterLister(indexer cache.Indexer, resource schema.GroupResource) *ClusterLister {
3290
return &ClusterLister{
@@ -75,27 +133,9 @@ type genericLister struct {
75133
}
76134

77135
func (s *genericLister) List(selector labels.Selector) (ret []runtime.Object, err error) {
78-
selectAll := selector == nil || selector.Empty()
79-
list, err := s.indexer.ByIndex(ClusterIndexName, ClusterIndexKey(s.cluster))
80-
if err != nil {
81-
return nil, err
82-
}
83-
84-
for i := range list {
85-
item := list[i].(runtime.Object)
86-
if selectAll {
87-
ret = append(ret, item)
88-
} else {
89-
metadata, err := meta.Accessor(item)
90-
if err != nil {
91-
return nil, err
92-
}
93-
if selector.Matches(labels.Set(metadata.GetLabels())) {
94-
ret = append(ret, item)
95-
}
96-
}
97-
}
98-
136+
err = ListAllByCluster(s.indexer, s.cluster, selector, func(i interface{}) {
137+
ret = append(ret, i.(runtime.Object))
138+
})
99139
return ret, err
100140
}
101141

@@ -128,27 +168,9 @@ type genericNamespaceLister struct {
128168
}
129169

130170
func (s *genericNamespaceLister) List(selector labels.Selector) (ret []runtime.Object, err error) {
131-
selectAll := selector == nil || selector.Empty()
132-
133-
list, err := s.indexer.ByIndex(ClusterAndNamespaceIndexName, ClusterAndNamespaceIndexKey(s.cluster, s.namespace))
134-
if err != nil {
135-
return nil, err
136-
}
137-
138-
for i := range list {
139-
item := list[i].(runtime.Object)
140-
if selectAll {
141-
ret = append(ret, item)
142-
} else {
143-
metadata, err := meta.Accessor(item)
144-
if err != nil {
145-
return nil, err
146-
}
147-
if selector.Matches(labels.Set(metadata.GetLabels())) {
148-
ret = append(ret, item)
149-
}
150-
}
151-
}
171+
err = ListAllByClusterAndNamespace(s.indexer, s.cluster, s.namespace, selector, func(i interface{}) {
172+
ret = append(ret, i.(runtime.Object))
173+
})
152174
return ret, err
153175
}
154176

0 commit comments

Comments
 (0)