1/* 2Copyright 2014 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package cache 18 19import ( 20 "fmt" 21 22 "k8s.io/apimachinery/pkg/api/meta" 23 "k8s.io/apimachinery/pkg/util/sets" 24) 25 26// Indexer is a storage interface that lets you list objects using multiple indexing functions. 27// There are three kinds of strings here. 28// One is a storage key, as defined in the Store interface. 29// Another kind is a name of an index. 30// The third kind of string is an "indexed value", which is produced by an 31// IndexFunc and can be a field value or any other string computed from the object. 32type Indexer interface { 33 Store 34 // Index returns the stored objects whose set of indexed values 35 // intersects the set of indexed values of the given object, for 36 // the named index 37 Index(indexName string, obj interface{}) ([]interface{}, error) 38 // IndexKeys returns the storage keys of the stored objects whose 39 // set of indexed values for the named index includes the given 40 // indexed value 41 IndexKeys(indexName, indexedValue string) ([]string, error) 42 // ListIndexFuncValues returns all the indexed values of the given index 43 ListIndexFuncValues(indexName string) []string 44 // ByIndex returns the stored objects whose set of indexed values 45 // for the named index includes the given indexed value 46 ByIndex(indexName, indexedValue string) ([]interface{}, error) 47 // GetIndexer return the indexers 48 GetIndexers() Indexers 49 50 // AddIndexers adds more indexers to this store. If you call this after you already have data 51 // in the store, the results are undefined. 52 AddIndexers(newIndexers Indexers) error 53} 54 55// IndexFunc knows how to compute the set of indexed values for an object. 56type IndexFunc func(obj interface{}) ([]string, error) 57 58// IndexFuncToKeyFuncAdapter adapts an indexFunc to a keyFunc. This is only useful if your index function returns 59// unique values for every object. This is conversion can create errors when more than one key is found. You 60// should prefer to make proper key and index functions. 61func IndexFuncToKeyFuncAdapter(indexFunc IndexFunc) KeyFunc { 62 return func(obj interface{}) (string, error) { 63 indexKeys, err := indexFunc(obj) 64 if err != nil { 65 return "", err 66 } 67 if len(indexKeys) > 1 { 68 return "", fmt.Errorf("too many keys: %v", indexKeys) 69 } 70 if len(indexKeys) == 0 { 71 return "", fmt.Errorf("unexpected empty indexKeys") 72 } 73 return indexKeys[0], nil 74 } 75} 76 77const ( 78 // NamespaceIndex is the lookup name for the most comment index function, which is to index by the namespace field. 79 NamespaceIndex string = "namespace" 80) 81 82// MetaNamespaceIndexFunc is a default index function that indexes based on an object's namespace 83func MetaNamespaceIndexFunc(obj interface{}) ([]string, error) { 84 meta, err := meta.Accessor(obj) 85 if err != nil { 86 return []string{""}, fmt.Errorf("object has no meta: %v", err) 87 } 88 return []string{meta.GetNamespace()}, nil 89} 90 91// Index maps the indexed value to a set of keys in the store that match on that value 92type Index map[string]sets.String 93 94// Indexers maps a name to a IndexFunc 95type Indexers map[string]IndexFunc 96 97// Indices maps a name to an Index 98type Indices map[string]Index 99