MM-30140 LRU critical section optimization (#16184)
* MM-30140 LRU critical section optimization * Remove empty line * Renamed lru function
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d274cf8afa
Коммит
26676953a4
35
services/cache/lru.go
поставляемый
35
services/cache/lru.go
поставляемый
@@ -79,16 +79,12 @@ func (l *LRU) SetWithDefaultExpiry(key string, value interface{}) error {
|
|||||||
// SetWithExpiry adds the given key and value to the cache with the given expiry. If the key
|
// SetWithExpiry adds the given key and value to the cache with the given expiry. If the key
|
||||||
// already exists, it will overwrite the previoous value
|
// already exists, it will overwrite the previoous value
|
||||||
func (l *LRU) SetWithExpiry(key string, value interface{}, ttl time.Duration) error {
|
func (l *LRU) SetWithExpiry(key string, value interface{}, ttl time.Duration) error {
|
||||||
l.lock.Lock()
|
|
||||||
defer l.lock.Unlock()
|
|
||||||
return l.set(key, value, ttl)
|
return l.set(key, value, ttl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the content stored in the cache for the given key, and decode it into the value interface.
|
// Get the content stored in the cache for the given key, and decode it into the value interface.
|
||||||
// return ErrKeyNotFound if the key is missing from the cache
|
// return ErrKeyNotFound if the key is missing from the cache
|
||||||
func (l *LRU) Get(key string, value interface{}) error {
|
func (l *LRU) Get(key string, value interface{}) error {
|
||||||
l.lock.Lock()
|
|
||||||
defer l.lock.Unlock()
|
|
||||||
return l.get(key, value)
|
return l.get(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +156,9 @@ func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l.lock.Lock()
|
||||||
|
defer l.lock.Unlock()
|
||||||
|
|
||||||
// Check for existing item, ignoring expiry since we'd update anyway.
|
// Check for existing item, ignoring expiry since we'd update anyway.
|
||||||
if ent, ok := l.items[key]; ok {
|
if ent, ok := l.items[key]; ok {
|
||||||
l.evictList.MoveToFront(ent)
|
l.evictList.MoveToFront(ent)
|
||||||
@@ -186,16 +185,11 @@ func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *LRU) get(key string, value interface{}) error {
|
func (l *LRU) get(key string, value interface{}) error {
|
||||||
if ent, ok := l.items[key]; ok {
|
e, err := l.getItem(key)
|
||||||
e := ent.Value.(*entry)
|
if err != nil {
|
||||||
|
return err
|
||||||
if e.generation != l.currentGeneration || (!e.expires.IsZero() && time.Now().After(e.expires)) {
|
|
||||||
l.removeElement(ent)
|
|
||||||
return ErrKeyNotFound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.evictList.MoveToFront(ent)
|
|
||||||
|
|
||||||
// We use a fast path for hot structs.
|
// We use a fast path for hot structs.
|
||||||
if msgpVal, ok := value.(msgp.Unmarshaler); ok {
|
if msgpVal, ok := value.(msgp.Unmarshaler); ok {
|
||||||
_, err := msgpVal.UnmarshalMsg(e.value)
|
_, err := msgpVal.UnmarshalMsg(e.value)
|
||||||
@@ -231,7 +225,22 @@ func (l *LRU) get(key string, value interface{}) error {
|
|||||||
// Slow path for other structs.
|
// Slow path for other structs.
|
||||||
return msgpack.Unmarshal(e.value, value)
|
return msgpack.Unmarshal(e.value, value)
|
||||||
}
|
}
|
||||||
return ErrKeyNotFound
|
|
||||||
|
func (l *LRU) getItem(key string) (*entry, error) {
|
||||||
|
l.lock.Lock()
|
||||||
|
defer l.lock.Unlock()
|
||||||
|
|
||||||
|
ent, ok := l.items[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrKeyNotFound
|
||||||
|
}
|
||||||
|
e := ent.Value.(*entry)
|
||||||
|
if e.generation != l.currentGeneration || (!e.expires.IsZero() && time.Now().After(e.expires)) {
|
||||||
|
l.removeElement(ent)
|
||||||
|
return nil, ErrKeyNotFound
|
||||||
|
}
|
||||||
|
l.evictList.MoveToFront(ent)
|
||||||
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LRU) removeElement(e *list.Element) {
|
func (l *LRU) removeElement(e *list.Element) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user