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