github.com/khulnasoft-lab/gopkg@v0.0.0-20240121181808-81b44d894093/cache/memory.go (about) 1 package cache 2 3 import ( 4 "sync" 5 6 "github.com/Khulnasoft-lab/gopkg/msg" 7 ) 8 9 // Provide an in memory cache of imported project information. 10 11 var defaultMemCache = newMemCache() 12 13 // MemPut put a version into the in memory cache for a name. 14 // This will silently ignore non-semver and make sure the latest 15 // is stored. 16 func MemPut(name, version string) { 17 defaultMemCache.put(name, version) 18 } 19 20 // MemTouched returns true if the cache was touched for a name. 21 func MemTouched(name string) bool { 22 return defaultMemCache.touched(name) 23 } 24 25 // MemTouch notes if a name has been looked at. 26 func MemTouch(name string) { 27 defaultMemCache.touch(name) 28 } 29 30 // MemLatest returns the latest, that is most recent, semver release. This 31 // may be a blank string if no put value 32 func MemLatest(name string) string { 33 return defaultMemCache.getLatest(name) 34 } 35 36 // MemSetCurrent is used to set the current version in use. 37 func MemSetCurrent(name, version string) { 38 defaultMemCache.setCurrent(name, version) 39 } 40 41 // MemCurrent is used to get the current version in use. 42 func MemCurrent(name string) string { 43 return defaultMemCache.current(name) 44 } 45 46 // An in memory cache. 47 type memCache struct { 48 sync.RWMutex 49 latest map[string]string 50 t map[string]bool 51 versions map[string][]string 52 c map[string]string 53 } 54 55 func newMemCache() *memCache { 56 return &memCache{ 57 latest: make(map[string]string), 58 t: make(map[string]bool), 59 versions: make(map[string][]string), 60 c: make(map[string]string), 61 } 62 } 63 64 func (m *memCache) setCurrent(name, version string) { 65 m.Lock() 66 defer m.Unlock() 67 68 if m.c[name] == "" { 69 m.c[name] = version 70 } else { 71 // If we already have a version try to see if the new or old one is 72 // semver and use that one. 73 _, err := semver.NewVersion(m.c[name]) 74 if err != nil { 75 _, err2 := semver.NewVersion(version) 76 if err2 == nil { 77 m.c[name] = version 78 } 79 } 80 } 81 } 82 83 func (m *memCache) current(name string) string { 84 m.RLock() 85 defer m.RUnlock() 86 return m.c[name] 87 } 88 89 func (m *memCache) put(name, version string) { 90 m.Lock() 91 defer m.Unlock() 92 m.t[name] = true 93 sv, err := semver.NewVersion(version) 94 if err != nil { 95 msg.Debug("Ignoring %s version %s: %s", name, version, err) 96 return 97 } 98 99 latest, found := m.latest[name] 100 if found { 101 lv, err := semver.NewVersion(latest) 102 if err == nil { 103 if sv.GreaterThan(lv) { 104 m.latest[name] = version 105 } 106 } 107 } else { 108 m.latest[name] = version 109 } 110 111 found = false 112 for _, v := range m.versions[name] { 113 if v == version { 114 found = true 115 } 116 } 117 if !found { 118 m.versions[name] = append(m.versions[name], version) 119 } 120 } 121 122 func (m *memCache) touch(name string) { 123 m.Lock() 124 defer m.Unlock() 125 m.t[name] = true 126 } 127 128 func (m *memCache) touched(name string) bool { 129 m.RLock() 130 defer m.RUnlock() 131 return m.t[name] 132 } 133 134 func (m *memCache) getLatest(name string) string { 135 m.RLock() 136 defer m.RUnlock() 137 return m.latest[name] 138 }