aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go')
-rw-r--r--Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go236
1 files changed, 236 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go
new file mode 100644
index 000000000..07a9939b2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go
@@ -0,0 +1,236 @@
+// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
+// All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package cache
+
+import (
+ "math/rand"
+ "testing"
+)
+
+func set(ns Namespace, key uint64, value interface{}, charge int, fin func()) Object {
+ obj, _ := ns.Get(key, func() (bool, interface{}, int, SetFin) {
+ return true, value, charge, fin
+ })
+ return obj
+}
+
+func TestCache_HitMiss(t *testing.T) {
+ cases := []struct {
+ key uint64
+ value string
+ }{
+ {1, "vvvvvvvvv"},
+ {100, "v1"},
+ {0, "v2"},
+ {12346, "v3"},
+ {777, "v4"},
+ {999, "v5"},
+ {7654, "v6"},
+ {2, "v7"},
+ {3, "v8"},
+ {9, "v9"},
+ }
+
+ setfin := 0
+ c := NewLRUCache(1000)
+ ns := c.GetNamespace(0)
+ for i, x := range cases {
+ set(ns, x.key, x.value, len(x.value), func() {
+ setfin++
+ }).Release()
+ for j, y := range cases {
+ r, ok := ns.Get(y.key, nil)
+ if j <= i {
+ // should hit
+ if !ok {
+ t.Errorf("case '%d' iteration '%d' is miss", i, j)
+ } else if r.Value().(string) != y.value {
+ t.Errorf("case '%d' iteration '%d' has invalid value got '%s', want '%s'", i, j, r.Value().(string), y.value)
+ }
+ } else {
+ // should miss
+ if ok {
+ t.Errorf("case '%d' iteration '%d' is hit , value '%s'", i, j, r.Value().(string))
+ }
+ }
+ if ok {
+ r.Release()
+ }
+ }
+ }
+
+ for i, x := range cases {
+ finalizerOk := false
+ ns.Delete(x.key, func(exist bool) {
+ finalizerOk = true
+ })
+
+ if !finalizerOk {
+ t.Errorf("case %d delete finalizer not executed", i)
+ }
+
+ for j, y := range cases {
+ r, ok := ns.Get(y.key, nil)
+ if j > i {
+ // should hit
+ if !ok {
+ t.Errorf("case '%d' iteration '%d' is miss", i, j)
+ } else if r.Value().(string) != y.value {
+ t.Errorf("case '%d' iteration '%d' has invalid value got '%s', want '%s'", i, j, r.Value().(string), y.value)
+ }
+ } else {
+ // should miss
+ if ok {
+ t.Errorf("case '%d' iteration '%d' is hit, value '%s'", i, j, r.Value().(string))
+ }
+ }
+ if ok {
+ r.Release()
+ }
+ }
+ }
+
+ if setfin != len(cases) {
+ t.Errorf("some set finalizer may not be executed, want=%d got=%d", len(cases), setfin)
+ }
+}
+
+func TestLRUCache_Eviction(t *testing.T) {
+ c := NewLRUCache(12)
+ ns := c.GetNamespace(0)
+ o1 := set(ns, 1, 1, 1, nil)
+ set(ns, 2, 2, 1, nil).Release()
+ set(ns, 3, 3, 1, nil).Release()
+ set(ns, 4, 4, 1, nil).Release()
+ set(ns, 5, 5, 1, nil).Release()
+ if r, ok := ns.Get(2, nil); ok { // 1,3,4,5,2
+ r.Release()
+ }
+ set(ns, 9, 9, 10, nil).Release() // 5,2,9
+
+ for _, x := range []uint64{9, 2, 5, 1} {
+ r, ok := ns.Get(x, nil)
+ if !ok {
+ t.Errorf("miss for key '%d'", x)
+ } else {
+ if r.Value().(int) != int(x) {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", x, x, r.Value().(int))
+ }
+ r.Release()
+ }
+ }
+ o1.Release()
+ for _, x := range []uint64{1, 2, 5} {
+ r, ok := ns.Get(x, nil)
+ if !ok {
+ t.Errorf("miss for key '%d'", x)
+ } else {
+ if r.Value().(int) != int(x) {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", x, x, r.Value().(int))
+ }
+ r.Release()
+ }
+ }
+ for _, x := range []uint64{3, 4, 9} {
+ r, ok := ns.Get(x, nil)
+ if ok {
+ t.Errorf("hit for key '%d'", x)
+ if r.Value().(int) != int(x) {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", x, x, r.Value().(int))
+ }
+ r.Release()
+ }
+ }
+}
+
+func TestLRUCache_SetGet(t *testing.T) {
+ c := NewLRUCache(13)
+ ns := c.GetNamespace(0)
+ for i := 0; i < 200; i++ {
+ n := uint64(rand.Intn(99999) % 20)
+ set(ns, n, n, 1, nil).Release()
+ if p, ok := ns.Get(n, nil); ok {
+ if p.Value() == nil {
+ t.Errorf("key '%d' contains nil value", n)
+ } else {
+ got := p.Value().(uint64)
+ if got != n {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", n, n, got)
+ }
+ }
+ p.Release()
+ } else {
+ t.Errorf("key '%d' doesn't exist", n)
+ }
+ }
+}
+
+func TestLRUCache_Purge(t *testing.T) {
+ c := NewLRUCache(3)
+ ns1 := c.GetNamespace(0)
+ o1 := set(ns1, 1, 1, 1, nil)
+ o2 := set(ns1, 2, 2, 1, nil)
+ ns1.Purge(nil)
+ set(ns1, 3, 3, 1, nil).Release()
+ for _, x := range []uint64{1, 2, 3} {
+ r, ok := ns1.Get(x, nil)
+ if !ok {
+ t.Errorf("miss for key '%d'", x)
+ } else {
+ if r.Value().(int) != int(x) {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", x, x, r.Value().(int))
+ }
+ r.Release()
+ }
+ }
+ o1.Release()
+ o2.Release()
+ for _, x := range []uint64{1, 2} {
+ r, ok := ns1.Get(x, nil)
+ if ok {
+ t.Errorf("hit for key '%d'", x)
+ if r.Value().(int) != int(x) {
+ t.Errorf("invalid value for key '%d' want '%d', got '%d'", x, x, r.Value().(int))
+ }
+ r.Release()
+ }
+ }
+}
+
+func BenchmarkLRUCache_SetRelease(b *testing.B) {
+ capacity := b.N / 100
+ if capacity <= 0 {
+ capacity = 10
+ }
+ c := NewLRUCache(capacity)
+ ns := c.GetNamespace(0)
+ b.ResetTimer()
+ for i := uint64(0); i < uint64(b.N); i++ {
+ set(ns, i, nil, 1, nil).Release()
+ }
+}
+
+func BenchmarkLRUCache_SetReleaseTwice(b *testing.B) {
+ capacity := b.N / 100
+ if capacity <= 0 {
+ capacity = 10
+ }
+ c := NewLRUCache(capacity)
+ ns := c.GetNamespace(0)
+ b.ResetTimer()
+
+ na := b.N / 2
+ nb := b.N - na
+
+ for i := uint64(0); i < uint64(na); i++ {
+ set(ns, i, nil, 1, nil).Release()
+ }
+
+ for i := uint64(0); i < uint64(nb); i++ {
+ set(ns, i, nil, 1, nil).Release()
+ }
+}