package util import ( "errors" "sync" ) // Cache is a data store type Cache struct { sync.Mutex val map[string]Param } // NewCache creates cache func NewCache() *Cache { return &Cache{ val: make(map[string]Param), } } // Run adds input channel's values to cache func (c *Cache) Run(in <-chan Param) { log := NewLogger("cache") for p := range in { log.TRACE.Printf("%s: %v", p.Key, p.Val) c.Add(p.UniqueID(), p) } } // State provides a structured copy of the cached values // Loadpoints are aggregated as loadpoints array func (c *Cache) State() map[string]interface{} { c.Lock() defer c.Unlock() res := map[string]interface{}{} lps := make(map[int]map[string]interface{}) for _, param := range c.val { if param.LoadPoint == nil { res[param.Key] = param.Val } else { lp, ok := lps[*param.LoadPoint] if !ok { lp = make(map[string]interface{}) lps[*param.LoadPoint] = lp } lp[param.Key] = param.Val } } // convert map to array loadpoints := make([]map[string]interface{}, len(lps)) for id, lp := range lps { loadpoints[id] = lp } res["loadpoints"] = loadpoints return res } // All provides a copy of the cached values func (c *Cache) All() []Param { c.Lock() defer c.Unlock() copy := make([]Param, 0, len(c.val)) for _, val := range c.val { copy = append(copy, val) } return copy } // Add entry to cache func (c *Cache) Add(key string, param Param) { c.Lock() defer c.Unlock() c.val[key] = param } // Get entry from cache func (c *Cache) Get(key string) Param { c.Lock() defer c.Unlock() if val, ok := c.val[key]; ok { return val } return Param{} } // GetChecked returns checked value from cache func (c *Cache) GetChecked(id int, key string) (res Param, err error) { pid := Param{LoadPoint: &id, Key: key} res = c.Get(pid.UniqueID()) if res.Key == "" { err = errors.New("not found") } return res, err }