github.com/upcmd/up@v0.8.1-0.20230108151705-ad8b797bf04f/model/core/cache.go (about) 1 // Ultimate Provisioner: UP cmd 2 // Copyright (c) 2019 Stephen Cheng and contributors 3 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 7 8 package core 9 10 import ( 11 u "github.com/upcmd/up/utils" 12 "strings" 13 "sync" 14 ) 15 16 type Cache map[string]interface{} 17 18 var ( 19 cacheMap *Cache 20 Mutex = &sync.Mutex{} 21 ) 22 23 func GetCache() *Cache { 24 if cacheMap == nil { 25 cacheMap = NewCache() 26 } 27 return cacheMap 28 } 29 30 func NewCache() *Cache { 31 cache := Cache{} 32 return &cache 33 } 34 35 func (c *Cache) Put(key string, obj interface{}) { 36 (*c)[key] = obj 37 } 38 39 func (c *Cache) List() { 40 for k, v := range *c { 41 u.Pfvvvv(" %s: %+v \n", k, v) 42 } 43 } 44 45 func (c *Cache) Len() int { 46 return len(*c) 47 } 48 49 func (c *Cache) GetPrefixMatched(prefix string) *Cache { 50 valueMap := NewCache() 51 for k, v := range *c { 52 if strings.HasPrefix(k, prefix) { 53 varname := strings.Trim(k, prefix) 54 valueMap.Put(varname, v) 55 } 56 } 57 return valueMap 58 } 59 60 func (c *Cache) Get(key string) interface{} { 61 return (*c)[key] 62 } 63 64 func (c *Cache) Update(key string, obj interface{}) { 65 Mutex.Lock() 66 defer Mutex.Unlock() 67 (*c)[key] = obj 68 (*c)[key+"_new?"] = true 69 } 70 71 func (c *Cache) Delete(key string) { 72 Mutex.Lock() 73 defer Mutex.Unlock() 74 75 if _, exists := (*c)[key]; exists { 76 isNewKey := key + "_new?" 77 v := c.Get(isNewKey) 78 if v != nil { 79 delete((*c), isNewKey) 80 } 81 82 delete((*c), key) 83 } 84 } 85 86 //get a cached item, return a bool flag to indicate if it is an latest updated 87 func (c *Cache) SafeGet(key string) (interface{}, bool) { 88 Mutex.Lock() 89 defer Mutex.Unlock() 90 isNewEle := c.Get(key + "_new?") 91 isNew := func() (isnew bool) { 92 if isNewEle == nil { 93 isnew = true 94 } else { 95 isnew = isNewEle.(bool) 96 } 97 return 98 }() 99 100 if isNew { 101 return c.Get(key), true 102 } else { 103 return c.Get(key), false 104 } 105 } 106 107 //mark the obj is a obsolete item due to failed get call to get latest value 108 func (c *Cache) Obsolete(key string) { 109 Mutex.Lock() 110 defer Mutex.Unlock() 111 if _, ok := (*c)[key]; ok { 112 c.Put(key+"_new?", false) 113 } else { 114 c.Put(key+"_new?", true) 115 } 116 }