mirror of https://github.com/k3s-io/k3s
parent
2c933695fa
commit
a2cc1b1a20
|
@ -35,6 +35,9 @@ import (
|
|||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// nodeMap stores a *Cache for each node.
|
||||
type nodeMap map[string]*NodeCache
|
||||
|
||||
// Cache is a thread safe map saves and reuses the output of predicate functions,
|
||||
// it uses node name as key to access those cached results.
|
||||
//
|
||||
|
@ -42,13 +45,17 @@ import (
|
|||
// class". (Equivalence class is defined in the `Class` type.) Saved results
|
||||
// will be reused until an appropriate invalidation function is called.
|
||||
type Cache struct {
|
||||
// i.e. map[string]*NodeCache
|
||||
sync.Map
|
||||
// NOTE(harry): Theoretically sync.Map has better performance in machine with 8+ CPUs, while
|
||||
// the reality is lock contention in first level cache is rare.
|
||||
mu sync.RWMutex
|
||||
nodeToCache nodeMap
|
||||
}
|
||||
|
||||
// NewCache create an empty equiv class cache.
|
||||
func NewCache() *Cache {
|
||||
return new(Cache)
|
||||
return &Cache{
|
||||
nodeToCache: make(nodeMap),
|
||||
}
|
||||
}
|
||||
|
||||
// NodeCache saves and reuses the output of predicate functions. Use RunPredicate to
|
||||
|
@ -76,8 +83,12 @@ func newNodeCache() *NodeCache {
|
|||
// it creates the NodeCache and returns it.
|
||||
// The boolean flag is true if the value was loaded, false if created.
|
||||
func (c *Cache) GetNodeCache(name string) (nodeCache *NodeCache, exists bool) {
|
||||
v, exists := c.LoadOrStore(name, newNodeCache())
|
||||
nodeCache = v.(*NodeCache)
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if nodeCache, exists = c.nodeToCache[name]; !exists {
|
||||
nodeCache = newNodeCache()
|
||||
c.nodeToCache[name] = nodeCache
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -86,13 +97,12 @@ func (c *Cache) InvalidatePredicates(predicateKeys sets.String) {
|
|||
if len(predicateKeys) == 0 {
|
||||
return
|
||||
}
|
||||
c.Range(func(k, v interface{}) bool {
|
||||
n := v.(*NodeCache)
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
for _, n := range c.nodeToCache {
|
||||
n.invalidatePreds(predicateKeys)
|
||||
return true
|
||||
})
|
||||
}
|
||||
glog.V(5).Infof("Cache invalidation: node=*,predicates=%v", predicateKeys)
|
||||
|
||||
}
|
||||
|
||||
// InvalidatePredicatesOnNode clears cached results for the given predicates on one node.
|
||||
|
@ -100,8 +110,9 @@ func (c *Cache) InvalidatePredicatesOnNode(nodeName string, predicateKeys sets.S
|
|||
if len(predicateKeys) == 0 {
|
||||
return
|
||||
}
|
||||
if v, ok := c.Load(nodeName); ok {
|
||||
n := v.(*NodeCache)
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
if n, ok := c.nodeToCache[nodeName]; ok {
|
||||
n.invalidatePreds(predicateKeys)
|
||||
}
|
||||
glog.V(5).Infof("Cache invalidation: node=%s,predicates=%v", nodeName, predicateKeys)
|
||||
|
@ -109,7 +120,9 @@ func (c *Cache) InvalidatePredicatesOnNode(nodeName string, predicateKeys sets.S
|
|||
|
||||
// InvalidateAllPredicatesOnNode clears all cached results for one node.
|
||||
func (c *Cache) InvalidateAllPredicatesOnNode(nodeName string) {
|
||||
c.Delete(nodeName)
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
delete(c.nodeToCache, nodeName)
|
||||
glog.V(5).Infof("Cache invalidation: node=%s,predicates=*", nodeName)
|
||||
}
|
||||
|
||||
|
|
|
@ -731,7 +731,7 @@ func TestInvalidateCachedPredicateItemOfAllNodes(t *testing.T) {
|
|||
// there should be no cached predicate any more
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if nodeCache, exist := ecache.GetNodeCache(test.nodeName); exist {
|
||||
if nodeCache, exist := ecache.nodeToCache[test.nodeName]; exist {
|
||||
if _, exist := nodeCache.cache[testPredicate]; exist {
|
||||
t.Errorf("Failed: cached item for predicate key: %v on node: %v should be invalidated",
|
||||
testPredicate, test.nodeName)
|
||||
|
|
Loading…
Reference in New Issue