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  }