aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go')
-rw-r--r--Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go461
1 files changed, 461 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go
new file mode 100644
index 000000000..ea6801a89
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go
@@ -0,0 +1,461 @@
+// 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 leveldb
+
+import (
+ "bytes"
+ "fmt"
+ "math/rand"
+ "os"
+ "path/filepath"
+ "runtime"
+ "testing"
+
+ "github.com/syndtr/goleveldb/leveldb/iterator"
+ "github.com/syndtr/goleveldb/leveldb/opt"
+ "github.com/syndtr/goleveldb/leveldb/storage"
+)
+
+func randomString(r *rand.Rand, n int) []byte {
+ b := new(bytes.Buffer)
+ for i := 0; i < n; i++ {
+ b.WriteByte(' ' + byte(r.Intn(95)))
+ }
+ return b.Bytes()
+}
+
+func compressibleStr(r *rand.Rand, frac float32, n int) []byte {
+ nn := int(float32(n) * frac)
+ rb := randomString(r, nn)
+ b := make([]byte, 0, n+nn)
+ for len(b) < n {
+ b = append(b, rb...)
+ }
+ return b[:n]
+}
+
+type valueGen struct {
+ src []byte
+ pos int
+}
+
+func newValueGen(frac float32) *valueGen {
+ v := new(valueGen)
+ r := rand.New(rand.NewSource(301))
+ v.src = make([]byte, 0, 1048576+100)
+ for len(v.src) < 1048576 {
+ v.src = append(v.src, compressibleStr(r, frac, 100)...)
+ }
+ return v
+}
+
+func (v *valueGen) get(n int) []byte {
+ if v.pos+n > len(v.src) {
+ v.pos = 0
+ }
+ v.pos += n
+ return v.src[v.pos-n : v.pos]
+}
+
+var benchDB = filepath.Join(os.TempDir(), fmt.Sprintf("goleveldbbench-%d", os.Getuid()))
+
+type dbBench struct {
+ b *testing.B
+ stor storage.Storage
+ db *DB
+
+ o *opt.Options
+ ro *opt.ReadOptions
+ wo *opt.WriteOptions
+
+ keys, values [][]byte
+}
+
+func openDBBench(b *testing.B, noCompress bool) *dbBench {
+ _, err := os.Stat(benchDB)
+ if err == nil {
+ err = os.RemoveAll(benchDB)
+ if err != nil {
+ b.Fatal("cannot remove old db: ", err)
+ }
+ }
+
+ p := &dbBench{
+ b: b,
+ o: &opt.Options{},
+ ro: &opt.ReadOptions{},
+ wo: &opt.WriteOptions{},
+ }
+ p.stor, err = storage.OpenFile(benchDB)
+ if err != nil {
+ b.Fatal("cannot open stor: ", err)
+ }
+ if noCompress {
+ p.o.Compression = opt.NoCompression
+ }
+
+ p.db, err = Open(p.stor, p.o)
+ if err != nil {
+ b.Fatal("cannot open db: ", err)
+ }
+
+ runtime.GOMAXPROCS(runtime.NumCPU())
+ return p
+}
+
+func (p *dbBench) reopen() {
+ p.db.Close()
+ var err error
+ p.db, err = Open(p.stor, p.o)
+ if err != nil {
+ p.b.Fatal("Reopen: got error: ", err)
+ }
+}
+
+func (p *dbBench) populate(n int) {
+ p.keys, p.values = make([][]byte, n), make([][]byte, n)
+ v := newValueGen(0.5)
+ for i := range p.keys {
+ p.keys[i], p.values[i] = []byte(fmt.Sprintf("%016d", i)), v.get(100)
+ }
+}
+
+func (p *dbBench) randomize() {
+ m := len(p.keys)
+ times := m * 2
+ r1, r2 := rand.New(rand.NewSource(0xdeadbeef)), rand.New(rand.NewSource(0xbeefface))
+ for n := 0; n < times; n++ {
+ i, j := r1.Int()%m, r2.Int()%m
+ if i == j {
+ continue
+ }
+ p.keys[i], p.keys[j] = p.keys[j], p.keys[i]
+ p.values[i], p.values[j] = p.values[j], p.values[i]
+ }
+}
+
+func (p *dbBench) writes(perBatch int) {
+ b := p.b
+ db := p.db
+
+ n := len(p.keys)
+ m := n / perBatch
+ if n%perBatch > 0 {
+ m++
+ }
+ batches := make([]Batch, m)
+ j := 0
+ for i := range batches {
+ first := true
+ for ; j < n && ((j+1)%perBatch != 0 || first); j++ {
+ first = false
+ batches[i].Put(p.keys[j], p.values[j])
+ }
+ }
+ runtime.GC()
+
+ b.ResetTimer()
+ b.StartTimer()
+ for i := range batches {
+ err := db.Write(&(batches[i]), p.wo)
+ if err != nil {
+ b.Fatal("write failed: ", err)
+ }
+ }
+ b.StopTimer()
+ b.SetBytes(116)
+}
+
+func (p *dbBench) drop() {
+ p.keys, p.values = nil, nil
+ runtime.GC()
+}
+
+func (p *dbBench) puts() {
+ b := p.b
+ db := p.db
+
+ b.ResetTimer()
+ b.StartTimer()
+ for i := range p.keys {
+ err := db.Put(p.keys[i], p.values[i], p.wo)
+ if err != nil {
+ b.Fatal("put failed: ", err)
+ }
+ }
+ b.StopTimer()
+ b.SetBytes(116)
+}
+
+func (p *dbBench) fill() {
+ b := p.b
+ db := p.db
+
+ perBatch := 10000
+ batch := new(Batch)
+ for i, n := 0, len(p.keys); i < n; {
+ first := true
+ for ; i < n && ((i+1)%perBatch != 0 || first); i++ {
+ first = false
+ batch.Put(p.keys[i], p.values[i])
+ }
+ err := db.Write(batch, p.wo)
+ if err != nil {
+ b.Fatal("write failed: ", err)
+ }
+ batch.Reset()
+ }
+}
+
+func (p *dbBench) gets() {
+ b := p.b
+ db := p.db
+
+ b.ResetTimer()
+ for i := range p.keys {
+ _, err := db.Get(p.keys[i], p.ro)
+ if err != nil {
+ b.Error("got error: ", err)
+ }
+ }
+ b.StopTimer()
+}
+
+func (p *dbBench) seeks() {
+ b := p.b
+
+ iter := p.newIter()
+ defer iter.Release()
+ b.ResetTimer()
+ for i := range p.keys {
+ if !iter.Seek(p.keys[i]) {
+ b.Error("value not found for: ", string(p.keys[i]))
+ }
+ }
+ b.StopTimer()
+}
+
+func (p *dbBench) newIter() iterator.Iterator {
+ iter := p.db.NewIterator(nil, p.ro)
+ err := iter.Error()
+ if err != nil {
+ p.b.Fatal("cannot create iterator: ", err)
+ }
+ return iter
+}
+
+func (p *dbBench) close() {
+ p.db.Close()
+ p.stor.Close()
+ os.RemoveAll(benchDB)
+ p.db = nil
+ p.keys = nil
+ p.values = nil
+ runtime.GC()
+ runtime.GOMAXPROCS(1)
+}
+
+func BenchmarkDBWrite(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBWriteBatch(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.writes(1000)
+ p.close()
+}
+
+func BenchmarkDBWriteUncompressed(b *testing.B) {
+ p := openDBBench(b, true)
+ p.populate(b.N)
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBWriteBatchUncompressed(b *testing.B) {
+ p := openDBBench(b, true)
+ p.populate(b.N)
+ p.writes(1000)
+ p.close()
+}
+
+func BenchmarkDBWriteRandom(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.randomize()
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBWriteRandomSync(b *testing.B) {
+ p := openDBBench(b, false)
+ p.wo.Sync = true
+ p.populate(b.N)
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBOverwrite(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.writes(1)
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBOverwriteRandom(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.writes(1)
+ p.randomize()
+ p.writes(1)
+ p.close()
+}
+
+func BenchmarkDBPut(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.puts()
+ p.close()
+}
+
+func BenchmarkDBRead(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.drop()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ for iter.Next() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBReadGC(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ for iter.Next() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBReadUncompressed(b *testing.B) {
+ p := openDBBench(b, true)
+ p.populate(b.N)
+ p.fill()
+ p.drop()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ for iter.Next() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBReadTable(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.reopen()
+ p.drop()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ for iter.Next() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBReadReverse(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.drop()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ iter.Last()
+ for iter.Prev() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBReadReverseTable(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.reopen()
+ p.drop()
+
+ iter := p.newIter()
+ b.ResetTimer()
+ iter.Last()
+ for iter.Prev() {
+ }
+ iter.Release()
+ b.StopTimer()
+ b.SetBytes(116)
+ p.close()
+}
+
+func BenchmarkDBSeek(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.seeks()
+ p.close()
+}
+
+func BenchmarkDBSeekRandom(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.randomize()
+ p.seeks()
+ p.close()
+}
+
+func BenchmarkDBGet(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.gets()
+ p.close()
+}
+
+func BenchmarkDBGetRandom(b *testing.B) {
+ p := openDBBench(b, false)
+ p.populate(b.N)
+ p.fill()
+ p.randomize()
+ p.gets()
+ p.close()
+}