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
|
||||
// already exists, it will overwrite the previoous value
|
||||
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)
|
||||
}
|
||||
|
||||
// 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
|
||||
func (l *LRU) Get(key string, value interface{}) error {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
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.
|
||||
if ent, ok := l.items[key]; ok {
|
||||
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 {
|
||||
if ent, ok := l.items[key]; ok {
|
||||
e := ent.Value.(*entry)
|
||||
|
||||
if e.generation != l.currentGeneration || (!e.expires.IsZero() && time.Now().After(e.expires)) {
|
||||
l.removeElement(ent)
|
||||
return ErrKeyNotFound
|
||||
e, err := l.getItem(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.evictList.MoveToFront(ent)
|
||||
|
||||
// We use a fast path for hot structs.
|
||||
if msgpVal, ok := value.(msgp.Unmarshaler); ok {
|
||||
_, err := msgpVal.UnmarshalMsg(e.value)
|
||||
@@ -231,7 +225,22 @@ func (l *LRU) get(key string, value interface{}) error {
|
||||
// Slow path for other structs.
|
||||
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) {
|
||||
|
||||
Ссылка в новой задаче
Block a user