Bump github.com/hashicorp/golang-lru from 0.5.4 to 1.0.2 (#2804)

* Bump github.com/hashicorp/golang-lru from 0.5.4 to 1.0.2

Bumps [github.com/hashicorp/golang-lru](https://github.com/hashicorp/golang-lru) from 0.5.4 to 1.0.2.
- [Release notes](https://github.com/hashicorp/golang-lru/releases)
- [Commits](https://github.com/hashicorp/golang-lru/compare/v0.5.4...v1.0.2)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/golang-lru
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Run ./hack/update-codegen.sh

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2023-08-21 08:46:28 +00:00 committed by GitHub
parent d36cc5925a
commit 2ad39e9393
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 322 additions and 102 deletions

2
go.mod
View File

@ -21,7 +21,7 @@ require (
github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3 github.com/google/mako v0.0.0-20190821191249-122f8dcef9e3
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/golang-lru v1.0.2
github.com/kelseyhightower/envconfig v1.4.0 github.com/kelseyhightower/envconfig v1.4.0
github.com/openzipkin/zipkin-go v0.4.1 github.com/openzipkin/zipkin-go v0.4.1
github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_golang v1.16.0

4
go.sum
View File

@ -238,8 +238,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjd
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=

View File

@ -0,0 +1,30 @@
linters:
enable:
- megacheck
- revive
- govet
- unconvert
- megacheck
- gas
- gocyclo
- dupl
- misspell
- unparam
- unused
- typecheck
- ineffassign
- stylecheck
- exportloopref
- gocritic
- nakedret
- gosimple
- prealloc
fast: false
disable-all: true
issues:
exclude-rules:
- path: _test\.go
linters:
- dupl
exclude-use-default: false

View File

@ -44,7 +44,7 @@ func New2Q(size int) (*TwoQueueCache, error) {
// New2QParams creates a new TwoQueueCache using the provided // New2QParams creates a new TwoQueueCache using the provided
// parameter values. // parameter values.
func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) { func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, error) {
if size <= 0 { if size <= 0 {
return nil, fmt.Errorf("invalid size") return nil, fmt.Errorf("invalid size")
} }
@ -138,7 +138,6 @@ func (c *TwoQueueCache) Add(key, value interface{}) {
// Add to the recently seen list // Add to the recently seen list
c.ensureSpace(false) c.ensureSpace(false)
c.recent.Add(key, value) c.recent.Add(key, value)
return
} }
// ensureSpace is used to ensure we have space in the cache // ensureSpace is used to ensure we have space in the cache

View File

@ -1,3 +1,5 @@
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0 Mozilla Public License, version 2.0
1. Definitions 1. Definitions

View File

@ -1,25 +1,7 @@
golang-lru golang-lru
========== ==========
This provides the `lru` package which implements a fixed-size Please upgrade to github.com/hashicorp/golang-lru/v2 for all new code as v1 will
thread safe LRU cache. It is based on the cache in Groupcache. not be updated anymore. The v2 version supports generics and is faster; old code
can specify a specific tag, e.g. github.com/hashicorp/golang-lru/v1.0.2 for
Documentation backwards compatibility.
=============
Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
Example
=======
Using the LRU is very simple:
```go
l, _ := New(128)
for i := 0; i < 256; i++ {
l.Add(i, nil)
}
if l.Len() != 128 {
panic(fmt.Sprintf("bad len: %v", l.Len()))
}
```

View File

@ -173,7 +173,6 @@ func (c *ARCCache) Add(key, value interface{}) {
// Add to the recently seen list // Add to the recently seen list
c.t1.Add(key, value) c.t1.Add(key, value)
return
} }
// replace is used to adaptively evict from either T1 or T2 // replace is used to adaptively evict from either T1 or T2

View File

@ -6,9 +6,16 @@ import (
"github.com/hashicorp/golang-lru/simplelru" "github.com/hashicorp/golang-lru/simplelru"
) )
const (
// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val
DefaultEvictedBufferSize = 16
)
// Cache is a thread-safe fixed size LRU cache. // Cache is a thread-safe fixed size LRU cache.
type Cache struct { type Cache struct {
lru simplelru.LRUCache lru *simplelru.LRU
evictedKeys, evictedVals []interface{}
onEvictedCB func(k, v interface{})
lock sync.RWMutex lock sync.RWMutex
} }
@ -19,30 +26,63 @@ func New(size int) (*Cache, error) {
// NewWithEvict constructs a fixed size cache with the given eviction // NewWithEvict constructs a fixed size cache with the given eviction
// callback. // callback.
func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) { func NewWithEvict(size int, onEvicted func(key, value interface{})) (c *Cache, err error) {
lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted)) // create a cache with default settings
if err != nil { c = &Cache{
return nil, err onEvictedCB: onEvicted,
} }
c := &Cache{ if onEvicted != nil {
lru: lru, c.initEvictBuffers()
onEvicted = c.onEvicted
} }
return c, nil c.lru, err = simplelru.NewLRU(size, onEvicted)
return
}
func (c *Cache) initEvictBuffers() {
c.evictedKeys = make([]interface{}, 0, DefaultEvictedBufferSize)
c.evictedVals = make([]interface{}, 0, DefaultEvictedBufferSize)
}
// onEvicted save evicted key/val and sent in externally registered callback
// outside of critical section
func (c *Cache) onEvicted(k, v interface{}) {
c.evictedKeys = append(c.evictedKeys, k)
c.evictedVals = append(c.evictedVals, v)
} }
// Purge is used to completely clear the cache. // Purge is used to completely clear the cache.
func (c *Cache) Purge() { func (c *Cache) Purge() {
var ks, vs []interface{}
c.lock.Lock() c.lock.Lock()
c.lru.Purge() c.lru.Purge()
if c.onEvictedCB != nil && len(c.evictedKeys) > 0 {
ks, vs = c.evictedKeys, c.evictedVals
c.initEvictBuffers()
}
c.lock.Unlock() c.lock.Unlock()
// invoke callback outside of critical section
if c.onEvictedCB != nil {
for i := 0; i < len(ks); i++ {
c.onEvictedCB(ks[i], vs[i])
}
}
} }
// Add adds a value to the cache. Returns true if an eviction occurred. // Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) { func (c *Cache) Add(key, value interface{}) (evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
return evicted if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return
} }
// Get looks up a key's value from the cache. // Get looks up a key's value from the cache.
@ -75,13 +115,21 @@ func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
// recent-ness or deleting it for being stale, and if not, adds the value. // recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred. // Returns whether found and whether an eviction occurred.
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
if c.lru.Contains(key) { if c.lru.Contains(key) {
c.lock.Unlock()
return true, false return true, false
} }
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock()
if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return false, evicted return false, evicted
} }
@ -89,47 +137,80 @@ func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
// recent-ness or deleting it for being stale, and if not, adds the value. // recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred. // Returns whether found and whether an eviction occurred.
func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) { func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
previous, ok = c.lru.Peek(key) previous, ok = c.lru.Peek(key)
if ok { if ok {
c.lock.Unlock()
return previous, true, false return previous, true, false
} }
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock()
if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return nil, false, evicted return nil, false, evicted
} }
// Remove removes the provided key from the cache. // Remove removes the provided key from the cache.
func (c *Cache) Remove(key interface{}) (present bool) { func (c *Cache) Remove(key interface{}) (present bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
present = c.lru.Remove(key) present = c.lru.Remove(key)
if c.onEvictedCB != nil && present {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && present {
c.onEvictedCB(k, v)
}
return return
} }
// Resize changes the cache size. // Resize changes the cache size.
func (c *Cache) Resize(size int) (evicted int) { func (c *Cache) Resize(size int) (evicted int) {
var ks, vs []interface{}
c.lock.Lock() c.lock.Lock()
evicted = c.lru.Resize(size) evicted = c.lru.Resize(size)
if c.onEvictedCB != nil && evicted > 0 {
ks, vs = c.evictedKeys, c.evictedVals
c.initEvictBuffers()
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && evicted > 0 {
for i := 0; i < len(ks); i++ {
c.onEvictedCB(ks[i], vs[i])
}
}
return evicted return evicted
} }
// RemoveOldest removes the oldest item from the cache. // RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) { func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
key, value, ok = c.lru.RemoveOldest() key, value, ok = c.lru.RemoveOldest()
if c.onEvictedCB != nil && ok {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && ok {
c.onEvictedCB(k, v)
}
return return
} }
// GetOldest returns the oldest entry // GetOldest returns the oldest entry
func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) { func (c *Cache) GetOldest() (key, value interface{}, ok bool) {
c.lock.Lock() c.lock.RLock()
key, value, ok = c.lru.GetOldest() key, value, ok = c.lru.GetOldest()
c.lock.Unlock() c.lock.RUnlock()
return return
} }

View File

@ -25,7 +25,7 @@ type entry struct {
// NewLRU constructs an LRU of the given size // NewLRU constructs an LRU of the given size
func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
if size <= 0 { if size <= 0 {
return nil, errors.New("Must provide a positive size") return nil, errors.New("must provide a positive size")
} }
c := &LRU{ c := &LRU{
size: size, size: size,
@ -109,7 +109,7 @@ func (c *LRU) Remove(key interface{}) (present bool) {
} }
// RemoveOldest removes the oldest item from the cache. // RemoveOldest removes the oldest item from the cache.
func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { func (c *LRU) RemoveOldest() (key, value interface{}, ok bool) {
ent := c.evictList.Back() ent := c.evictList.Back()
if ent != nil { if ent != nil {
c.removeElement(ent) c.removeElement(ent)
@ -120,7 +120,7 @@ func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) {
} }
// GetOldest returns the oldest entry // GetOldest returns the oldest entry
func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { func (c *LRU) GetOldest() (key, value interface{}, ok bool) {
ent := c.evictList.Back() ent := c.evictList.Back()
if ent != nil { if ent != nil {
kv := ent.Value.(*entry) kv := ent.Value.(*entry)

View File

@ -1,3 +1,4 @@
// Package simplelru provides simple LRU implementation based on build-in container/list.
package simplelru package simplelru
// LRUCache is the interface for simple LRU cache. // LRUCache is the interface for simple LRU cache.

View File

@ -0,0 +1,16 @@
package lru
import (
"crypto/rand"
"math"
"math/big"
"testing"
)
func getRand(tb testing.TB) int64 {
out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
tb.Fatal(err)
}
return out.Int64()
}

30
vendor/github.com/hashicorp/golang-lru/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,30 @@
linters:
enable:
- megacheck
- revive
- govet
- unconvert
- megacheck
- gas
- gocyclo
- dupl
- misspell
- unparam
- unused
- typecheck
- ineffassign
- stylecheck
- exportloopref
- gocritic
- nakedret
- gosimple
- prealloc
fast: false
disable-all: true
issues:
exclude-rules:
- path: _test\.go
linters:
- dupl
exclude-use-default: false

View File

@ -44,7 +44,7 @@ func New2Q(size int) (*TwoQueueCache, error) {
// New2QParams creates a new TwoQueueCache using the provided // New2QParams creates a new TwoQueueCache using the provided
// parameter values. // parameter values.
func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) { func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, error) {
if size <= 0 { if size <= 0 {
return nil, fmt.Errorf("invalid size") return nil, fmt.Errorf("invalid size")
} }
@ -138,7 +138,6 @@ func (c *TwoQueueCache) Add(key, value interface{}) {
// Add to the recently seen list // Add to the recently seen list
c.ensureSpace(false) c.ensureSpace(false)
c.recent.Add(key, value) c.recent.Add(key, value)
return
} }
// ensureSpace is used to ensure we have space in the cache // ensureSpace is used to ensure we have space in the cache

View File

@ -1,3 +1,5 @@
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0 Mozilla Public License, version 2.0
1. Definitions 1. Definitions

View File

@ -1,25 +1,7 @@
golang-lru golang-lru
========== ==========
This provides the `lru` package which implements a fixed-size Please upgrade to github.com/hashicorp/golang-lru/v2 for all new code as v1 will
thread safe LRU cache. It is based on the cache in Groupcache. not be updated anymore. The v2 version supports generics and is faster; old code
can specify a specific tag, e.g. github.com/hashicorp/golang-lru/v1.0.2 for
Documentation backwards compatibility.
=============
Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru)
Example
=======
Using the LRU is very simple:
```go
l, _ := New(128)
for i := 0; i < 256; i++ {
l.Add(i, nil)
}
if l.Len() != 128 {
panic(fmt.Sprintf("bad len: %v", l.Len()))
}
```

View File

@ -173,7 +173,6 @@ func (c *ARCCache) Add(key, value interface{}) {
// Add to the recently seen list // Add to the recently seen list
c.t1.Add(key, value) c.t1.Add(key, value)
return
} }
// replace is used to adaptively evict from either T1 or T2 // replace is used to adaptively evict from either T1 or T2

View File

@ -6,9 +6,16 @@ import (
"github.com/hashicorp/golang-lru/simplelru" "github.com/hashicorp/golang-lru/simplelru"
) )
const (
// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val
DefaultEvictedBufferSize = 16
)
// Cache is a thread-safe fixed size LRU cache. // Cache is a thread-safe fixed size LRU cache.
type Cache struct { type Cache struct {
lru simplelru.LRUCache lru *simplelru.LRU
evictedKeys, evictedVals []interface{}
onEvictedCB func(k, v interface{})
lock sync.RWMutex lock sync.RWMutex
} }
@ -19,30 +26,63 @@ func New(size int) (*Cache, error) {
// NewWithEvict constructs a fixed size cache with the given eviction // NewWithEvict constructs a fixed size cache with the given eviction
// callback. // callback.
func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) { func NewWithEvict(size int, onEvicted func(key, value interface{})) (c *Cache, err error) {
lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted)) // create a cache with default settings
if err != nil { c = &Cache{
return nil, err onEvictedCB: onEvicted,
} }
c := &Cache{ if onEvicted != nil {
lru: lru, c.initEvictBuffers()
onEvicted = c.onEvicted
} }
return c, nil c.lru, err = simplelru.NewLRU(size, onEvicted)
return
}
func (c *Cache) initEvictBuffers() {
c.evictedKeys = make([]interface{}, 0, DefaultEvictedBufferSize)
c.evictedVals = make([]interface{}, 0, DefaultEvictedBufferSize)
}
// onEvicted save evicted key/val and sent in externally registered callback
// outside of critical section
func (c *Cache) onEvicted(k, v interface{}) {
c.evictedKeys = append(c.evictedKeys, k)
c.evictedVals = append(c.evictedVals, v)
} }
// Purge is used to completely clear the cache. // Purge is used to completely clear the cache.
func (c *Cache) Purge() { func (c *Cache) Purge() {
var ks, vs []interface{}
c.lock.Lock() c.lock.Lock()
c.lru.Purge() c.lru.Purge()
if c.onEvictedCB != nil && len(c.evictedKeys) > 0 {
ks, vs = c.evictedKeys, c.evictedVals
c.initEvictBuffers()
}
c.lock.Unlock() c.lock.Unlock()
// invoke callback outside of critical section
if c.onEvictedCB != nil {
for i := 0; i < len(ks); i++ {
c.onEvictedCB(ks[i], vs[i])
}
}
} }
// Add adds a value to the cache. Returns true if an eviction occurred. // Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) { func (c *Cache) Add(key, value interface{}) (evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
return evicted if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return
} }
// Get looks up a key's value from the cache. // Get looks up a key's value from the cache.
@ -75,13 +115,21 @@ func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
// recent-ness or deleting it for being stale, and if not, adds the value. // recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred. // Returns whether found and whether an eviction occurred.
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
if c.lru.Contains(key) { if c.lru.Contains(key) {
c.lock.Unlock()
return true, false return true, false
} }
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock()
if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return false, evicted return false, evicted
} }
@ -89,47 +137,80 @@ func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
// recent-ness or deleting it for being stale, and if not, adds the value. // recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred. // Returns whether found and whether an eviction occurred.
func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) { func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock()
previous, ok = c.lru.Peek(key) previous, ok = c.lru.Peek(key)
if ok { if ok {
c.lock.Unlock()
return previous, true, false return previous, true, false
} }
evicted = c.lru.Add(key, value) evicted = c.lru.Add(key, value)
if c.onEvictedCB != nil && evicted {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock()
if c.onEvictedCB != nil && evicted {
c.onEvictedCB(k, v)
}
return nil, false, evicted return nil, false, evicted
} }
// Remove removes the provided key from the cache. // Remove removes the provided key from the cache.
func (c *Cache) Remove(key interface{}) (present bool) { func (c *Cache) Remove(key interface{}) (present bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
present = c.lru.Remove(key) present = c.lru.Remove(key)
if c.onEvictedCB != nil && present {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && present {
c.onEvictedCB(k, v)
}
return return
} }
// Resize changes the cache size. // Resize changes the cache size.
func (c *Cache) Resize(size int) (evicted int) { func (c *Cache) Resize(size int) (evicted int) {
var ks, vs []interface{}
c.lock.Lock() c.lock.Lock()
evicted = c.lru.Resize(size) evicted = c.lru.Resize(size)
if c.onEvictedCB != nil && evicted > 0 {
ks, vs = c.evictedKeys, c.evictedVals
c.initEvictBuffers()
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && evicted > 0 {
for i := 0; i < len(ks); i++ {
c.onEvictedCB(ks[i], vs[i])
}
}
return evicted return evicted
} }
// RemoveOldest removes the oldest item from the cache. // RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) { func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) {
var k, v interface{}
c.lock.Lock() c.lock.Lock()
key, value, ok = c.lru.RemoveOldest() key, value, ok = c.lru.RemoveOldest()
if c.onEvictedCB != nil && ok {
k, v = c.evictedKeys[0], c.evictedVals[0]
c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
}
c.lock.Unlock() c.lock.Unlock()
if c.onEvictedCB != nil && ok {
c.onEvictedCB(k, v)
}
return return
} }
// GetOldest returns the oldest entry // GetOldest returns the oldest entry
func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) { func (c *Cache) GetOldest() (key, value interface{}, ok bool) {
c.lock.Lock() c.lock.RLock()
key, value, ok = c.lru.GetOldest() key, value, ok = c.lru.GetOldest()
c.lock.Unlock() c.lock.RUnlock()
return return
} }

View File

@ -25,7 +25,7 @@ type entry struct {
// NewLRU constructs an LRU of the given size // NewLRU constructs an LRU of the given size
func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
if size <= 0 { if size <= 0 {
return nil, errors.New("Must provide a positive size") return nil, errors.New("must provide a positive size")
} }
c := &LRU{ c := &LRU{
size: size, size: size,
@ -109,7 +109,7 @@ func (c *LRU) Remove(key interface{}) (present bool) {
} }
// RemoveOldest removes the oldest item from the cache. // RemoveOldest removes the oldest item from the cache.
func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { func (c *LRU) RemoveOldest() (key, value interface{}, ok bool) {
ent := c.evictList.Back() ent := c.evictList.Back()
if ent != nil { if ent != nil {
c.removeElement(ent) c.removeElement(ent)
@ -120,7 +120,7 @@ func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) {
} }
// GetOldest returns the oldest entry // GetOldest returns the oldest entry
func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { func (c *LRU) GetOldest() (key, value interface{}, ok bool) {
ent := c.evictList.Back() ent := c.evictList.Back()
if ent != nil { if ent != nil {
kv := ent.Value.(*entry) kv := ent.Value.(*entry)

View File

@ -1,3 +1,4 @@
// Package simplelru provides simple LRU implementation based on build-in container/list.
package simplelru package simplelru
// LRUCache is the interface for simple LRU cache. // LRUCache is the interface for simple LRU cache.

16
vendor/github.com/hashicorp/golang-lru/testing.go generated vendored Normal file
View File

@ -0,0 +1,16 @@
package lru
import (
"crypto/rand"
"math"
"math/big"
"testing"
)
func getRand(tb testing.TB) int64 {
out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
tb.Fatal(err)
}
return out.Int64()
}

2
vendor/modules.txt vendored
View File

@ -188,7 +188,7 @@ github.com/gorilla/websocket
github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule
github.com/grpc-ecosystem/grpc-gateway/v2/runtime github.com/grpc-ecosystem/grpc-gateway/v2/runtime
github.com/grpc-ecosystem/grpc-gateway/v2/utilities github.com/grpc-ecosystem/grpc-gateway/v2/utilities
# github.com/hashicorp/golang-lru v0.5.4 # github.com/hashicorp/golang-lru v1.0.2
## explicit; go 1.12 ## explicit; go 1.12
github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru
github.com/hashicorp/golang-lru/simplelru github.com/hashicorp/golang-lru/simplelru