92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
/*
|
|
Copyright 2024 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package cacher
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"k8s.io/apimachinery/pkg/fields"
|
|
"k8s.io/apimachinery/pkg/labels"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
type storeIndexer interface {
|
|
Add(obj interface{}) error
|
|
Update(obj interface{}) error
|
|
Delete(obj interface{}) error
|
|
List() []interface{}
|
|
ListKeys() []string
|
|
Get(obj interface{}) (item interface{}, exists bool, err error)
|
|
GetByKey(key string) (item interface{}, exists bool, err error)
|
|
Replace([]interface{}, string) error
|
|
ByIndex(indexName, indexedValue string) ([]interface{}, error)
|
|
}
|
|
|
|
func newStoreIndexer(indexers *cache.Indexers) storeIndexer {
|
|
return cache.NewIndexer(storeElementKey, storeElementIndexers(indexers))
|
|
}
|
|
|
|
// Computing a key of an object is generally non-trivial (it performs
|
|
// e.g. validation underneath). Similarly computing object fields and
|
|
// labels. To avoid computing them multiple times (to serve the event
|
|
// in different List/Watch requests), in the underlying store we are
|
|
// keeping structs (key, object, labels, fields).
|
|
type storeElement struct {
|
|
Key string
|
|
Object runtime.Object
|
|
Labels labels.Set
|
|
Fields fields.Set
|
|
}
|
|
|
|
func storeElementKey(obj interface{}) (string, error) {
|
|
elem, ok := obj.(*storeElement)
|
|
if !ok {
|
|
return "", fmt.Errorf("not a storeElement: %v", obj)
|
|
}
|
|
return elem.Key, nil
|
|
}
|
|
|
|
func storeElementObject(obj interface{}) (runtime.Object, error) {
|
|
elem, ok := obj.(*storeElement)
|
|
if !ok {
|
|
return nil, fmt.Errorf("not a storeElement: %v", obj)
|
|
}
|
|
return elem.Object, nil
|
|
}
|
|
|
|
func storeElementIndexFunc(objIndexFunc cache.IndexFunc) cache.IndexFunc {
|
|
return func(obj interface{}) (strings []string, e error) {
|
|
seo, err := storeElementObject(obj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return objIndexFunc(seo)
|
|
}
|
|
}
|
|
|
|
func storeElementIndexers(indexers *cache.Indexers) cache.Indexers {
|
|
if indexers == nil {
|
|
return cache.Indexers{}
|
|
}
|
|
ret := cache.Indexers{}
|
|
for indexName, indexFunc := range *indexers {
|
|
ret[indexName] = storeElementIndexFunc(indexFunc)
|
|
}
|
|
return ret
|
|
}
|