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  }