Update go dependencies
This commit is contained in:
parent
15ffb51394
commit
bb4d483837
1621 changed files with 86368 additions and 284392 deletions
21
vendor/github.com/hashicorp/golang-lru/2q.go
generated
vendored
21
vendor/github.com/hashicorp/golang-lru/2q.go
generated
vendored
|
|
@ -30,9 +30,9 @@ type TwoQueueCache struct {
|
|||
size int
|
||||
recentSize int
|
||||
|
||||
recent *simplelru.LRU
|
||||
frequent *simplelru.LRU
|
||||
recentEvict *simplelru.LRU
|
||||
recent simplelru.LRUCache
|
||||
frequent simplelru.LRUCache
|
||||
recentEvict simplelru.LRUCache
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,8 @@ func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCa
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func (c *TwoQueueCache) Get(key interface{}) (interface{}, bool) {
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
|
|
@ -105,6 +106,7 @@ func (c *TwoQueueCache) Get(key interface{}) (interface{}, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
// Add adds a value to the cache.
|
||||
func (c *TwoQueueCache) Add(key, value interface{}) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
|
@ -160,12 +162,15 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) {
|
|||
c.frequent.RemoveOldest()
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *TwoQueueCache) Len() int {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.recent.Len() + c.frequent.Len()
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache.
|
||||
// The frequently used keys are first in the returned slice.
|
||||
func (c *TwoQueueCache) Keys() []interface{} {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
|
@ -174,6 +179,7 @@ func (c *TwoQueueCache) Keys() []interface{} {
|
|||
return append(k1, k2...)
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache.
|
||||
func (c *TwoQueueCache) Remove(key interface{}) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
|
@ -188,6 +194,7 @@ func (c *TwoQueueCache) Remove(key interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *TwoQueueCache) Purge() {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
|
@ -196,13 +203,17 @@ func (c *TwoQueueCache) Purge() {
|
|||
c.recentEvict.Purge()
|
||||
}
|
||||
|
||||
// Contains is used to check if the cache contains a key
|
||||
// without updating recency or frequency.
|
||||
func (c *TwoQueueCache) Contains(key interface{}) bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.frequent.Contains(key) || c.recent.Contains(key)
|
||||
}
|
||||
|
||||
func (c *TwoQueueCache) Peek(key interface{}) (interface{}, bool) {
|
||||
// Peek is used to inspect the cache value of a key
|
||||
// without updating recency or frequency.
|
||||
func (c *TwoQueueCache) Peek(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
if val, ok := c.frequent.Peek(key); ok {
|
||||
|
|
|
|||
306
vendor/github.com/hashicorp/golang-lru/2q_test.go
generated
vendored
306
vendor/github.com/hashicorp/golang-lru/2q_test.go
generated
vendored
|
|
@ -1,306 +0,0 @@
|
|||
package lru
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Benchmark2Q_Rand(b *testing.B) {
|
||||
l, err := New2Q(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func Benchmark2Q_Freq(b *testing.B) {
|
||||
l, err := New2Q(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = rand.Int63() % 16384
|
||||
} else {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func Test2Q_RandomOps(t *testing.T) {
|
||||
size := 128
|
||||
l, err := New2Q(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
n := 200000
|
||||
for i := 0; i < n; i++ {
|
||||
key := rand.Int63() % 512
|
||||
r := rand.Int63()
|
||||
switch r % 3 {
|
||||
case 0:
|
||||
l.Add(key, key)
|
||||
case 1:
|
||||
l.Get(key)
|
||||
case 2:
|
||||
l.Remove(key)
|
||||
}
|
||||
|
||||
if l.recent.Len()+l.frequent.Len() > size {
|
||||
t.Fatalf("bad: recent: %d freq: %d",
|
||||
l.recent.Len(), l.frequent.Len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Get_RecentToFrequent(t *testing.T) {
|
||||
l, err := New2Q(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Touch all the entries, should be in t1
|
||||
for i := 0; i < 128; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if n := l.recent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get should upgrade to t2
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get be from t2
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Add_RecentToFrequent(t *testing.T) {
|
||||
l, err := New2Q(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Add initially to recent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should upgrade to frequent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should remain in frequent
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q_Add_RecentEvict(t *testing.T) {
|
||||
l, err := New2Q(4)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Add 1,2,3,4,5 -> Evict 1
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
l.Add(3, 3)
|
||||
l.Add(4, 4)
|
||||
l.Add(5, 5)
|
||||
if n := l.recent.Len(); n != 4 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Pull in the recently evicted
|
||||
l.Add(1, 1)
|
||||
if n := l.recent.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add 6, should cause another recent evict
|
||||
l.Add(6, 6)
|
||||
if n := l.recent.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.recentEvict.Len(); n != 2 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.frequent.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func Test2Q(t *testing.T) {
|
||||
l, err := New2Q(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
l.Remove(i)
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Contains doesn't update recent-ness
|
||||
func Test2Q_Contains(t *testing.T) {
|
||||
l, err := New2Q(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Peek doesn't update recent-ness
|
||||
func Test2Q_Peek(t *testing.T) {
|
||||
l, err := New2Q(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
16
vendor/github.com/hashicorp/golang-lru/arc.go
generated
vendored
16
vendor/github.com/hashicorp/golang-lru/arc.go
generated
vendored
|
|
@ -18,11 +18,11 @@ type ARCCache struct {
|
|||
size int // Size is the total capacity of the cache
|
||||
p int // P is the dynamic preference towards T1 or T2
|
||||
|
||||
t1 *simplelru.LRU // T1 is the LRU for recently accessed items
|
||||
b1 *simplelru.LRU // B1 is the LRU for evictions from t1
|
||||
t1 simplelru.LRUCache // T1 is the LRU for recently accessed items
|
||||
b1 simplelru.LRUCache // B1 is the LRU for evictions from t1
|
||||
|
||||
t2 *simplelru.LRU // T2 is the LRU for frequently accessed items
|
||||
b2 *simplelru.LRU // B2 is the LRU for evictions from t2
|
||||
t2 simplelru.LRUCache // T2 is the LRU for frequently accessed items
|
||||
b2 simplelru.LRUCache // B2 is the LRU for evictions from t2
|
||||
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
|
@ -60,11 +60,11 @@ func NewARC(size int) (*ARCCache, error) {
|
|||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *ARCCache) Get(key interface{}) (interface{}, bool) {
|
||||
func (c *ARCCache) Get(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Ff the value is contained in T1 (recent), then
|
||||
// If the value is contained in T1 (recent), then
|
||||
// promote it to T2 (frequent)
|
||||
if val, ok := c.t1.Peek(key); ok {
|
||||
c.t1.Remove(key)
|
||||
|
|
@ -153,7 +153,7 @@ func (c *ARCCache) Add(key, value interface{}) {
|
|||
// Remove from B2
|
||||
c.b2.Remove(key)
|
||||
|
||||
// Add the key to the frequntly used list
|
||||
// Add the key to the frequently used list
|
||||
c.t2.Add(key, value)
|
||||
return
|
||||
}
|
||||
|
|
@ -247,7 +247,7 @@ func (c *ARCCache) Contains(key interface{}) bool {
|
|||
|
||||
// Peek is used to inspect the cache value of a key
|
||||
// without updating recency or frequency.
|
||||
func (c *ARCCache) Peek(key interface{}) (interface{}, bool) {
|
||||
func (c *ARCCache) Peek(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
if val, ok := c.t1.Peek(key); ok {
|
||||
|
|
|
|||
377
vendor/github.com/hashicorp/golang-lru/arc_test.go
generated
vendored
377
vendor/github.com/hashicorp/golang-lru/arc_test.go
generated
vendored
|
|
@ -1,377 +0,0 @@
|
|||
package lru
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
}
|
||||
|
||||
func BenchmarkARC_Rand(b *testing.B) {
|
||||
l, err := NewARC(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func BenchmarkARC_Freq(b *testing.B) {
|
||||
l, err := NewARC(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = rand.Int63() % 16384
|
||||
} else {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func TestARC_RandomOps(t *testing.T) {
|
||||
size := 128
|
||||
l, err := NewARC(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
n := 200000
|
||||
for i := 0; i < n; i++ {
|
||||
key := rand.Int63() % 512
|
||||
r := rand.Int63()
|
||||
switch r % 3 {
|
||||
case 0:
|
||||
l.Add(key, key)
|
||||
case 1:
|
||||
l.Get(key)
|
||||
case 2:
|
||||
l.Remove(key)
|
||||
}
|
||||
|
||||
if l.t1.Len()+l.t2.Len() > size {
|
||||
t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
|
||||
l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
|
||||
}
|
||||
if l.b1.Len()+l.b2.Len() > size {
|
||||
t.Fatalf("bad: t1: %d t2: %d b1: %d b2: %d p: %d",
|
||||
l.t1.Len(), l.t2.Len(), l.b1.Len(), l.b2.Len(), l.p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestARC_Get_RecentToFrequent(t *testing.T) {
|
||||
l, err := NewARC(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Touch all the entries, should be in t1
|
||||
for i := 0; i < 128; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if n := l.t1.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get should upgrade to t2
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Get be from t2
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("missing: %d", i)
|
||||
}
|
||||
}
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 128 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestARC_Add_RecentToFrequent(t *testing.T) {
|
||||
l, err := NewARC(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Add initially to t1
|
||||
l.Add(1, 1)
|
||||
if n := l.t1.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should upgrade to t2
|
||||
l.Add(1, 1)
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Add should remain in t2
|
||||
l.Add(1, 1)
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestARC_Adaptive(t *testing.T) {
|
||||
l, err := NewARC(4)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Fill t1
|
||||
for i := 0; i < 4; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if n := l.t1.Len(); n != 4 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Move to t2
|
||||
l.Get(0)
|
||||
l.Get(1)
|
||||
if n := l.t2.Len(); n != 2 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Evict from t1
|
||||
l.Add(4, 4)
|
||||
if n := l.b1.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Current state
|
||||
// t1 : (MRU) [4, 3] (LRU)
|
||||
// t2 : (MRU) [1, 0] (LRU)
|
||||
// b1 : (MRU) [2] (LRU)
|
||||
// b2 : (MRU) [] (LRU)
|
||||
|
||||
// Add 2, should cause hit on b1
|
||||
l.Add(2, 2)
|
||||
if n := l.b1.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if l.p != 1 {
|
||||
t.Fatalf("bad: %d", l.p)
|
||||
}
|
||||
if n := l.t2.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Current state
|
||||
// t1 : (MRU) [4] (LRU)
|
||||
// t2 : (MRU) [2, 1, 0] (LRU)
|
||||
// b1 : (MRU) [3] (LRU)
|
||||
// b2 : (MRU) [] (LRU)
|
||||
|
||||
// Add 4, should migrate to t2
|
||||
l.Add(4, 4)
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 4 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Current state
|
||||
// t1 : (MRU) [] (LRU)
|
||||
// t2 : (MRU) [4, 2, 1, 0] (LRU)
|
||||
// b1 : (MRU) [3] (LRU)
|
||||
// b2 : (MRU) [] (LRU)
|
||||
|
||||
// Add 4, should evict to b2
|
||||
l.Add(5, 5)
|
||||
if n := l.t1.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 3 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.b2.Len(); n != 1 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
|
||||
// Current state
|
||||
// t1 : (MRU) [5] (LRU)
|
||||
// t2 : (MRU) [4, 2, 1] (LRU)
|
||||
// b1 : (MRU) [3] (LRU)
|
||||
// b2 : (MRU) [0] (LRU)
|
||||
|
||||
// Add 0, should decrease p
|
||||
l.Add(0, 0)
|
||||
if n := l.t1.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.t2.Len(); n != 4 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.b1.Len(); n != 2 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if n := l.b2.Len(); n != 0 {
|
||||
t.Fatalf("bad: %d", n)
|
||||
}
|
||||
if l.p != 0 {
|
||||
t.Fatalf("bad: %d", l.p)
|
||||
}
|
||||
|
||||
// Current state
|
||||
// t1 : (MRU) [] (LRU)
|
||||
// t2 : (MRU) [0, 4, 2, 1] (LRU)
|
||||
// b1 : (MRU) [5, 3] (LRU)
|
||||
// b2 : (MRU) [0] (LRU)
|
||||
}
|
||||
|
||||
func TestARC(t *testing.T) {
|
||||
l, err := NewARC(128)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
l.Remove(i)
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Contains doesn't update recent-ness
|
||||
func TestARC_Contains(t *testing.T) {
|
||||
l, err := NewARC(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Peek doesn't update recent-ness
|
||||
func TestARC_Peek(t *testing.T) {
|
||||
l, err := NewARC(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
21
vendor/github.com/hashicorp/golang-lru/doc.go
generated
vendored
Normal file
21
vendor/github.com/hashicorp/golang-lru/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Package lru provides three different LRU caches of varying sophistication.
|
||||
//
|
||||
// Cache is a simple LRU cache. It is based on the
|
||||
// LRU implementation in groupcache:
|
||||
// https://github.com/golang/groupcache/tree/master/lru
|
||||
//
|
||||
// TwoQueueCache tracks frequently used and recently used entries separately.
|
||||
// This avoids a burst of accesses from taking out frequently used entries,
|
||||
// at the cost of about 2x computational overhead and some extra bookkeeping.
|
||||
//
|
||||
// ARCCache is an adaptive replacement cache. It tracks recent evictions as
|
||||
// well as recent usage in both the frequent and recent caches. Its
|
||||
// computational overhead is comparable to TwoQueueCache, but the memory
|
||||
// overhead is linear with the size of the cache.
|
||||
//
|
||||
// ARC has been patented by IBM, so do not use it if that is problematic for
|
||||
// your program.
|
||||
//
|
||||
// All caches in this package take locks while operating, and are therefore
|
||||
// thread-safe for consumers.
|
||||
package lru
|
||||
28
vendor/github.com/hashicorp/golang-lru/lru.go
generated
vendored
28
vendor/github.com/hashicorp/golang-lru/lru.go
generated
vendored
|
|
@ -1,6 +1,3 @@
|
|||
// This package provides a simple LRU cache. It is based on the
|
||||
// LRU implementation in groupcache:
|
||||
// https://github.com/golang/groupcache/tree/master/lru
|
||||
package lru
|
||||
|
||||
import (
|
||||
|
|
@ -11,11 +8,11 @@ import (
|
|||
|
||||
// Cache is a thread-safe fixed size LRU cache.
|
||||
type Cache struct {
|
||||
lru *simplelru.LRU
|
||||
lru simplelru.LRUCache
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// New creates an LRU of the given size
|
||||
// New creates an LRU of the given size.
|
||||
func New(size int) (*Cache, error) {
|
||||
return NewWithEvict(size, nil)
|
||||
}
|
||||
|
|
@ -33,7 +30,7 @@ func NewWithEvict(size int, onEvicted func(key interface{}, value interface{}))
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *Cache) Purge() {
|
||||
c.lock.Lock()
|
||||
c.lru.Purge()
|
||||
|
|
@ -41,30 +38,30 @@ func (c *Cache) Purge() {
|
|||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
func (c *Cache) Add(key, value interface{}) bool {
|
||||
func (c *Cache) Add(key, value interface{}) (evicted bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
return c.lru.Add(key, value)
|
||||
}
|
||||
|
||||
// Get looks up a key's value from the cache.
|
||||
func (c *Cache) Get(key interface{}) (interface{}, bool) {
|
||||
func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
return c.lru.Get(key)
|
||||
}
|
||||
|
||||
// Check if a key is in the cache, without updating the recent-ness
|
||||
// or deleting it for being stale.
|
||||
// Contains checks if a key is in the cache, without updating the
|
||||
// recent-ness or deleting it for being stale.
|
||||
func (c *Cache) Contains(key interface{}) bool {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.lru.Contains(key)
|
||||
}
|
||||
|
||||
// Returns the key value (or undefined if not found) without updating
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *Cache) Peek(key interface{}) (interface{}, bool) {
|
||||
func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
return c.lru.Peek(key)
|
||||
|
|
@ -73,16 +70,15 @@ func (c *Cache) Peek(key interface{}) (interface{}, bool) {
|
|||
// ContainsOrAdd checks if a key is in the cache without updating the
|
||||
// recent-ness or deleting it for being stale, and if not, adds the value.
|
||||
// Returns whether found and whether an eviction occurred.
|
||||
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evict bool) {
|
||||
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
if c.lru.Contains(key) {
|
||||
return true, false
|
||||
} else {
|
||||
evict := c.lru.Add(key, value)
|
||||
return false, evict
|
||||
}
|
||||
evicted = c.lru.Add(key, value)
|
||||
return false, evicted
|
||||
}
|
||||
|
||||
// Remove removes the provided key from the cache.
|
||||
|
|
|
|||
221
vendor/github.com/hashicorp/golang-lru/lru_test.go
generated
vendored
221
vendor/github.com/hashicorp/golang-lru/lru_test.go
generated
vendored
|
|
@ -1,221 +0,0 @@
|
|||
package lru
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkLRU_Rand(b *testing.B) {
|
||||
l, err := New(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
var hit, miss int
|
||||
for i := 0; i < 2*b.N; i++ {
|
||||
if i%2 == 0 {
|
||||
l.Add(trace[i], trace[i])
|
||||
} else {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func BenchmarkLRU_Freq(b *testing.B) {
|
||||
l, err := New(8192)
|
||||
if err != nil {
|
||||
b.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
trace := make([]int64, b.N*2)
|
||||
for i := 0; i < b.N*2; i++ {
|
||||
if i%2 == 0 {
|
||||
trace[i] = rand.Int63() % 16384
|
||||
} else {
|
||||
trace[i] = rand.Int63() % 32768
|
||||
}
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
l.Add(trace[i], trace[i])
|
||||
}
|
||||
var hit, miss int
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, ok := l.Get(trace[i])
|
||||
if ok {
|
||||
hit++
|
||||
} else {
|
||||
miss++
|
||||
}
|
||||
}
|
||||
b.Logf("hit: %d miss: %d ratio: %f", hit, miss, float64(hit)/float64(miss))
|
||||
}
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k interface{}, v interface{}) {
|
||||
if k != v {
|
||||
t.Fatalf("Evict values not equal (%v!=%v)", k, v)
|
||||
}
|
||||
evictCounter += 1
|
||||
}
|
||||
l, err := NewWithEvict(128, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
if evictCounter != 128 {
|
||||
t.Fatalf("bad evict count: %v", evictCounter)
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
l.Remove(i)
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Get(192) // expect 192 to be last key in l.Keys()
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if (i < 63 && k != i+193) || (i == 63 && k != 192) {
|
||||
t.Fatalf("out of order key: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Add returns true/false if an eviction occurred
|
||||
func TestLRUAdd(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k interface{}, v interface{}) {
|
||||
evictCounter += 1
|
||||
}
|
||||
|
||||
l, err := NewWithEvict(1, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if l.Add(1, 1) == true || evictCounter != 0 {
|
||||
t.Errorf("should not have an eviction")
|
||||
}
|
||||
if l.Add(2, 2) == false || evictCounter != 1 {
|
||||
t.Errorf("should have an eviction")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Contains doesn't update recent-ness
|
||||
func TestLRUContains(t *testing.T) {
|
||||
l, err := New(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Contains doesn't update recent-ness
|
||||
func TestLRUContainsOrAdd(t *testing.T) {
|
||||
l, err := New(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
contains, evict := l.ContainsOrAdd(1, 1)
|
||||
if !contains {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
if evict {
|
||||
t.Errorf("nothing should be evicted here")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
contains, evict = l.ContainsOrAdd(1, 1)
|
||||
if contains {
|
||||
t.Errorf("1 should not have been contained")
|
||||
}
|
||||
if !evict {
|
||||
t.Errorf("an eviction should have occurred")
|
||||
}
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("now 1 should be contained")
|
||||
}
|
||||
}
|
||||
|
||||
// test that Peek doesn't update recent-ness
|
||||
func TestLRUPeek(t *testing.T) {
|
||||
l, err := New(2)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
17
vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
generated
vendored
17
vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
generated
vendored
|
|
@ -36,7 +36,7 @@ func NewLRU(size int, onEvict EvictCallback) (*LRU, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
// Purge is used to completely clear the cache
|
||||
// Purge is used to completely clear the cache.
|
||||
func (c *LRU) Purge() {
|
||||
for k, v := range c.items {
|
||||
if c.onEvict != nil {
|
||||
|
|
@ -48,7 +48,7 @@ func (c *LRU) Purge() {
|
|||
}
|
||||
|
||||
// Add adds a value to the cache. Returns true if an eviction occurred.
|
||||
func (c *LRU) Add(key, value interface{}) bool {
|
||||
func (c *LRU) Add(key, value interface{}) (evicted bool) {
|
||||
// Check for existing item
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.evictList.MoveToFront(ent)
|
||||
|
|
@ -78,17 +78,18 @@ func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
|
|||
return
|
||||
}
|
||||
|
||||
// Check if a key is in the cache, without updating the recent-ness
|
||||
// Contains checks if a key is in the cache, without updating the recent-ness
|
||||
// or deleting it for being stale.
|
||||
func (c *LRU) Contains(key interface{}) (ok bool) {
|
||||
_, ok = c.items[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Returns the key value (or undefined if not found) without updating
|
||||
// Peek returns the key value (or undefined if not found) without updating
|
||||
// the "recently used"-ness of the key.
|
||||
func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) {
|
||||
if ent, ok := c.items[key]; ok {
|
||||
var ent *list.Element
|
||||
if ent, ok = c.items[key]; ok {
|
||||
return ent.Value.(*entry).value, true
|
||||
}
|
||||
return nil, ok
|
||||
|
|
@ -96,7 +97,7 @@ func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) {
|
|||
|
||||
// Remove removes the provided key from the cache, returning if the
|
||||
// key was contained.
|
||||
func (c *LRU) Remove(key interface{}) bool {
|
||||
func (c *LRU) Remove(key interface{}) (present bool) {
|
||||
if ent, ok := c.items[key]; ok {
|
||||
c.removeElement(ent)
|
||||
return true
|
||||
|
|
@ -105,7 +106,7 @@ func (c *LRU) Remove(key interface{}) bool {
|
|||
}
|
||||
|
||||
// RemoveOldest removes the oldest item from the cache.
|
||||
func (c *LRU) RemoveOldest() (interface{}, interface{}, bool) {
|
||||
func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) {
|
||||
ent := c.evictList.Back()
|
||||
if ent != nil {
|
||||
c.removeElement(ent)
|
||||
|
|
@ -116,7 +117,7 @@ func (c *LRU) RemoveOldest() (interface{}, interface{}, bool) {
|
|||
}
|
||||
|
||||
// GetOldest returns the oldest entry
|
||||
func (c *LRU) GetOldest() (interface{}, interface{}, bool) {
|
||||
func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) {
|
||||
ent := c.evictList.Back()
|
||||
if ent != nil {
|
||||
kv := ent.Value.(*entry)
|
||||
|
|
|
|||
37
vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
generated
vendored
Normal file
37
vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package simplelru
|
||||
|
||||
|
||||
// LRUCache is the interface for simple LRU cache.
|
||||
type LRUCache interface {
|
||||
// Adds a value to the cache, returns true if an eviction occurred and
|
||||
// updates the "recently used"-ness of the key.
|
||||
Add(key, value interface{}) bool
|
||||
|
||||
// Returns key's value from the cache and
|
||||
// updates the "recently used"-ness of the key. #value, isFound
|
||||
Get(key interface{}) (value interface{}, ok bool)
|
||||
|
||||
// Check if a key exsists in cache without updating the recent-ness.
|
||||
Contains(key interface{}) (ok bool)
|
||||
|
||||
// Returns key's value without updating the "recently used"-ness of the key.
|
||||
Peek(key interface{}) (value interface{}, ok bool)
|
||||
|
||||
// Removes a key from the cache.
|
||||
Remove(key interface{}) bool
|
||||
|
||||
// Removes the oldest entry from cache.
|
||||
RemoveOldest() (interface{}, interface{}, bool)
|
||||
|
||||
// Returns the oldest entry from the cache. #key, value, isFound
|
||||
GetOldest() (interface{}, interface{}, bool)
|
||||
|
||||
// Returns a slice of the keys in the cache, from oldest to newest.
|
||||
Keys() []interface{}
|
||||
|
||||
// Returns the number of items in the cache.
|
||||
Len() int
|
||||
|
||||
// Clear all cache entries
|
||||
Purge()
|
||||
}
|
||||
167
vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
generated
vendored
167
vendor/github.com/hashicorp/golang-lru/simplelru/lru_test.go
generated
vendored
|
|
@ -1,167 +0,0 @@
|
|||
package simplelru
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLRU(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k interface{}, v interface{}) {
|
||||
if k != v {
|
||||
t.Fatalf("Evict values not equal (%v!=%v)", k, v)
|
||||
}
|
||||
evictCounter += 1
|
||||
}
|
||||
l, err := NewLRU(128, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
if l.Len() != 128 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
|
||||
if evictCounter != 128 {
|
||||
t.Fatalf("bad evict count: %v", evictCounter)
|
||||
}
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if v, ok := l.Get(k); !ok || v != k || v != i+128 {
|
||||
t.Fatalf("bad key: %v", k)
|
||||
}
|
||||
}
|
||||
for i := 0; i < 128; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 256; i++ {
|
||||
_, ok := l.Get(i)
|
||||
if !ok {
|
||||
t.Fatalf("should not be evicted")
|
||||
}
|
||||
}
|
||||
for i := 128; i < 192; i++ {
|
||||
ok := l.Remove(i)
|
||||
if !ok {
|
||||
t.Fatalf("should be contained")
|
||||
}
|
||||
ok = l.Remove(i)
|
||||
if ok {
|
||||
t.Fatalf("should not be contained")
|
||||
}
|
||||
_, ok = l.Get(i)
|
||||
if ok {
|
||||
t.Fatalf("should be deleted")
|
||||
}
|
||||
}
|
||||
|
||||
l.Get(192) // expect 192 to be last key in l.Keys()
|
||||
|
||||
for i, k := range l.Keys() {
|
||||
if (i < 63 && k != i+193) || (i == 63 && k != 192) {
|
||||
t.Fatalf("out of order key: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
l.Purge()
|
||||
if l.Len() != 0 {
|
||||
t.Fatalf("bad len: %v", l.Len())
|
||||
}
|
||||
if _, ok := l.Get(200); ok {
|
||||
t.Fatalf("should contain nothing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLRU_GetOldest_RemoveOldest(t *testing.T) {
|
||||
l, err := NewLRU(128, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
l.Add(i, i)
|
||||
}
|
||||
k, _, ok := l.GetOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k.(int) != 128 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
|
||||
k, _, ok = l.RemoveOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k.(int) != 128 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
|
||||
k, _, ok = l.RemoveOldest()
|
||||
if !ok {
|
||||
t.Fatalf("missing")
|
||||
}
|
||||
if k.(int) != 129 {
|
||||
t.Fatalf("bad: %v", k)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Add returns true/false if an eviction occurred
|
||||
func TestLRU_Add(t *testing.T) {
|
||||
evictCounter := 0
|
||||
onEvicted := func(k interface{}, v interface{}) {
|
||||
evictCounter += 1
|
||||
}
|
||||
|
||||
l, err := NewLRU(1, onEvicted)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
if l.Add(1, 1) == true || evictCounter != 0 {
|
||||
t.Errorf("should not have an eviction")
|
||||
}
|
||||
if l.Add(2, 2) == false || evictCounter != 1 {
|
||||
t.Errorf("should have an eviction")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Contains doesn't update recent-ness
|
||||
func TestLRU_Contains(t *testing.T) {
|
||||
l, err := NewLRU(2, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if !l.Contains(1) {
|
||||
t.Errorf("1 should be contained")
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("Contains should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Peek doesn't update recent-ness
|
||||
func TestLRU_Peek(t *testing.T) {
|
||||
l, err := NewLRU(2, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
l.Add(1, 1)
|
||||
l.Add(2, 2)
|
||||
if v, ok := l.Peek(1); !ok || v != 1 {
|
||||
t.Errorf("1 should be set to 1: %v, %v", v, ok)
|
||||
}
|
||||
|
||||
l.Add(3, 3)
|
||||
if l.Contains(1) {
|
||||
t.Errorf("should not have updated recent-ness of 1")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue