Get

分享到:

Get

github.com/uber/jaeger/pkg/cache/lru.go

Jaeger的lru算法主要由2部分组成

  • byKey:map[string]*list.Element 保存数据用于 key/value 查询
  • byAccess:container/list 双向链表 用于实现懒惰删除

Get

 1func (c *LRU) Get(key string) interface{} {
 2	c.mux.Lock()
 3	defer c.mux.Unlock()
 4
 5	elt := c.byKey[key]
 6	if elt == nil {
 7		return nil
 8	}
 9
10	cacheEntry := elt.Value.(*cacheEntry)
11	if !cacheEntry.expiration.IsZero() && c.TimeNow().After(cacheEntry.expiration) {
12		// Entry has expired
13		if c.onEvict != nil {
14			c.onEvict(cacheEntry.key, cacheEntry.value)
15		}
16		c.byAccess.Remove(elt)
17		delete(c.byKey, cacheEntry.key)
18		return nil
19	}
20
21	c.byAccess.MoveToFront(elt)
22	return cacheEntry.value
23}

通过key从map查询value

  • 如果value过期把byKey和byAccess的数据都删除。
  • 如果value没有过期就把value移到链表的最前面

Put

 1func (c *LRU) putWithMutexHold(key string, value interface{}, elt *list.Element) interface{} {
 2    ......
 3
 4	entry := &cacheEntry{
 5		key:   key,
 6		value: value,
 7	}
 8
 9	if c.ttl != 0 {
10		entry.expiration = c.TimeNow().Add(c.ttl)
11	}
12	c.byKey[key] = c.byAccess.PushFront(entry)
13	for len(c.byKey) > c.maxSize {
14		oldest := c.byAccess.Remove(c.byAccess.Back()).(*cacheEntry)
15		if c.onEvict != nil {
16			c.onEvict(oldest.key, oldest.value)
17		}
18		delete(c.byKey, oldest.key)
19	}
20
21	return nil
22}

把key,value,expiration组成一个元素,并把元素放入链表的最前面

  • 如果链表长度超出限制,则删除链表最后的元素