mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-05 04:29:19 +02:00
Co-authored-by: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com>
This commit is contained in:
parent
500c6de359
commit
d77be80b40
|
@ -2,7 +2,7 @@ package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
sync "sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lru simple, fast lru cache implementation
|
// Lru simple, fast lru cache implementation
|
||||||
|
@ -28,7 +28,7 @@ type lruElement struct {
|
||||||
|
|
||||||
// NewLru init a lru cache
|
// NewLru init a lru cache
|
||||||
func NewLru(cap int) Lru {
|
func NewLru(cap int) Lru {
|
||||||
return lru{
|
return &lru{
|
||||||
capacity: cap,
|
capacity: cap,
|
||||||
doubleLinkedlist: list.New(),
|
doubleLinkedlist: list.New(),
|
||||||
keyToElement: new(sync.Map),
|
keyToElement: new(sync.Map),
|
||||||
|
@ -37,49 +37,53 @@ func NewLru(cap int) Lru {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l lru) Get(key interface{}) (value interface{}, ok bool) {
|
func (l *lru) Get(key interface{}) (value interface{}, ok bool) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
if v, ok := l.keyToElement.Load(key); ok {
|
if v, ok := l.keyToElement.Load(key); ok {
|
||||||
element := v.(*list.Element)
|
element := v.(*list.Element)
|
||||||
l.doubleLinkedlist.MoveBefore(element, l.doubleLinkedlist.Front())
|
l.doubleLinkedlist.MoveToFront(element)
|
||||||
return element.Value.(lruElement).value, true
|
return element.Value.(*lruElement).value, true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l lru) GetKeyFromValue(value interface{}) (key interface{}, ok bool) {
|
func (l *lru) GetKeyFromValue(value interface{}) (key interface{}, ok bool) {
|
||||||
|
l.mu.Lock()
|
||||||
|
defer l.mu.Unlock()
|
||||||
if k, ok := l.valueToElement.Load(value); ok {
|
if k, ok := l.valueToElement.Load(value); ok {
|
||||||
element := k.(*list.Element)
|
element := k.(*list.Element)
|
||||||
l.doubleLinkedlist.MoveBefore(element, l.doubleLinkedlist.Front())
|
l.doubleLinkedlist.MoveToFront(element)
|
||||||
return element.Value.(lruElement).key, true
|
return element.Value.(*lruElement).key, true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l lru) PeekKeyFromValue(value interface{}) (key interface{}, ok bool) {
|
func (l *lru) PeekKeyFromValue(value interface{}) (key interface{}, ok bool) {
|
||||||
if k, ok := l.valueToElement.Load(value); ok {
|
if k, ok := l.valueToElement.Load(value); ok {
|
||||||
element := k.(*list.Element)
|
element := k.(*list.Element)
|
||||||
return element.Value.(lruElement).key, true
|
return element.Value.(*lruElement).key, true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l lru) Put(key, value interface{}) {
|
func (l *lru) Put(key, value interface{}) {
|
||||||
e := lruElement{key, value}
|
l.mu.Lock()
|
||||||
|
e := &lruElement{key, value}
|
||||||
if v, ok := l.keyToElement.Load(key); ok {
|
if v, ok := l.keyToElement.Load(key); ok {
|
||||||
element := v.(*list.Element)
|
element := v.(*list.Element)
|
||||||
element.Value = e
|
element.Value = e
|
||||||
l.doubleLinkedlist.MoveBefore(element, l.doubleLinkedlist.Front())
|
l.doubleLinkedlist.MoveToFront(element)
|
||||||
} else {
|
} else {
|
||||||
l.mu.Lock()
|
|
||||||
element := l.doubleLinkedlist.PushFront(e)
|
element := l.doubleLinkedlist.PushFront(e)
|
||||||
l.keyToElement.Store(key, element)
|
l.keyToElement.Store(key, element)
|
||||||
l.valueToElement.Store(value, element)
|
l.valueToElement.Store(value, element)
|
||||||
if l.doubleLinkedlist.Len() > l.capacity {
|
if l.doubleLinkedlist.Len() > l.capacity {
|
||||||
toBeRemove := l.doubleLinkedlist.Back()
|
toBeRemove := l.doubleLinkedlist.Back()
|
||||||
l.doubleLinkedlist.Remove(toBeRemove)
|
l.doubleLinkedlist.Remove(toBeRemove)
|
||||||
l.keyToElement.Delete(toBeRemove.Value.(lruElement).key)
|
l.keyToElement.Delete(toBeRemove.Value.(*lruElement).key)
|
||||||
l.valueToElement.Delete(toBeRemove.Value.(lruElement).value)
|
l.valueToElement.Delete(toBeRemove.Value.(*lruElement).value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
l.mu.Unlock()
|
l.mu.Unlock()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue