@@ -18,6 +18,9 @@ package cache
18
18
19
19
import (
20
20
"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"
21
24
22
25
"k8s.io/apimachinery/pkg/api/errors"
23
26
"k8s.io/apimachinery/pkg/api/meta"
@@ -27,6 +30,61 @@ import (
27
30
"k8s.io/client-go/tools/cache"
28
31
)
29
32
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
+
30
88
// NewGenericClusterLister creates a new instance for the ClusterLister.
31
89
func NewGenericClusterLister (indexer cache.Indexer , resource schema.GroupResource ) * ClusterLister {
32
90
return & ClusterLister {
@@ -75,27 +133,9 @@ type genericLister struct {
75
133
}
76
134
77
135
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
+ })
99
139
return ret , err
100
140
}
101
141
@@ -128,27 +168,9 @@ type genericNamespaceLister struct {
128
168
}
129
169
130
170
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
+ })
152
174
return ret , err
153
175
}
154
176
0 commit comments