Index是索引,为了使通过各种方法找到存储的数据。ThreadSafeStore是存储,放数据的。
只需要看懂一个函数就可以了
// client-go/tools/cache/thread_safe_store.go/142---1.15
// Index() 方法的作用是给定一个 obj 和 indexName,
// 比如 pod1和 “namespace”,然后返回 pod_1 所在 namespace 下的所有 pod(pod_1 和pod_2),以下以这个为例
// 比如 pod1和 “kind”,然后返回 pod_1一致的kind的所有 obj
func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, error) {
c.lock.RLock()
defer c.lock.RUnlock()
indexFunc := c.indexers[indexName]
// c.indexers可以存多个函数,想用那个的话直接传indexName
// 比如通过 "namespace" 提取到 MetaNamespaceIndexFunc -> default
// 比如通过 "kind" 提取到 MetaKindIndexFunc -> pod
if indexFunc == nil {
return nil, fmt.Errorf("Index with name %s does not exist", indexName)
}
indexedValues, err := indexFunc(obj) // 对象丢进去拿到索引值,比如 "default"
if err != nil {
return nil, err
}
index := c.indices[indexName] // indexName 例如 "default",这里可以查到 Index
var storeKeySet sets.String
if len(indexedValues) == 1 {
// 多数情况对应索引值为1到场景,比如用 namespace 时,值就是唯一的
// In majority of cases, there is exactly one value matching.
// Optimize the most common path - deduping is not needed here.
storeKeySet = index[indexedValues[0]] // 拿到所有default下的key
} else {
// 对应不为1场景
// Need to de-dupe the return list.
// Since multiple keys are allowed, this can happen.
storeKeySet = sets.String{}
for _, indexedValue := range indexedValues {
for key := range index[indexedValue] {
storeKeySet.Insert(key)
}
}
}
list := make([]interface{}, 0, storeKeySet.Len())
// storeKey 也就是 "default/pod_1" 这种字符串,通过其就可以到 items map 里提取需要的 obj 了
for storeKey := range storeKeySet {
list = append(list, c.items[storeKey])
}
return list, nil
}