You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			89 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
		
		
			
		
	
	
			89 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
| 
											2 years ago
										 | package lru | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"container/list" | ||
|  | 	"sync" | ||
|  | ) | ||
|  | 
 | ||
|  | type node struct { | ||
|  | 	k interface{} | ||
|  | 	v interface{} | ||
|  | } | ||
|  | 
 | ||
|  | type LRU struct { | ||
|  | 	mutex   sync.RWMutex | ||
|  | 	maxLen  int // if maxLen<=0 then no limit
 | ||
|  | 	lruList *list.List | ||
|  | 	datas   map[interface{}]*list.Element | ||
|  | } | ||
|  | 
 | ||
|  | func New(maxLen int) *LRU { | ||
|  | 	return &LRU{ | ||
|  | 		maxLen:  maxLen, | ||
|  | 		lruList: list.New(), | ||
|  | 		datas:   make(map[interface{}]*list.Element), | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) PushFront(k, v interface{}) { | ||
|  | 	lc.mutex.Lock() | ||
|  | 	defer lc.mutex.Unlock() | ||
|  | 
 | ||
|  | 	if e, ok := lc.datas[k]; ok { | ||
|  | 		e.Value.(*node).v = v | ||
|  | 		lc.lruList.MoveToFront(e) | ||
|  | 	} else { | ||
|  | 		e := lc.lruList.PushFront(&node{k, v}) | ||
|  | 		lc.datas[k] = e | ||
|  | 	} | ||
|  | 	if lc.maxLen > 0 && lc.lruList.Len() > lc.maxLen { | ||
|  | 		lc.popTail() | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) PopTail() (interface{}, bool) { | ||
|  | 	lc.mutex.Lock() | ||
|  | 	defer lc.mutex.Unlock() | ||
|  | 
 | ||
|  | 	return lc.popTail() | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) Get(k interface{}) (interface{}, bool) { | ||
|  | 	lc.mutex.Lock() | ||
|  | 	defer lc.mutex.Unlock() | ||
|  | 
 | ||
|  | 	if e, ok := lc.datas[k]; ok { | ||
|  | 		lc.lruList.MoveToFront(e) | ||
|  | 		return e.Value.(*node).v, ok | ||
|  | 	} | ||
|  | 	return nil, false | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) Del(k interface{}) { | ||
|  | 	lc.mutex.Lock() | ||
|  | 	defer lc.mutex.Unlock() | ||
|  | 	lc.del(k) | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) Len() int { | ||
|  | 	lc.mutex.RLock() | ||
|  | 	defer lc.mutex.RUnlock() | ||
|  | 	return lc.lruList.Len() | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) popTail() (interface{}, bool) { | ||
|  | 	e := lc.lruList.Back() | ||
|  | 	if e != nil { | ||
|  | 		lc.del(e.Value.(*node).k) | ||
|  | 		return e.Value.(*node).v, true | ||
|  | 	} | ||
|  | 	return nil, false | ||
|  | } | ||
|  | 
 | ||
|  | func (lc *LRU) del(k interface{}) { | ||
|  | 	if e, ok := lc.datas[k]; ok { | ||
|  | 		delete(lc.datas, k) | ||
|  | 		lc.lruList.Remove(e) | ||
|  | 	} | ||
|  | } |