kevo/pkg/memtable/bench_test.go
Jeremy Tregunna 6fc3be617d
Some checks failed
Go Tests / Run Tests (1.24.2) (push) Has been cancelled
feat: Initial release of kevo storage engine.
Adds a complete LSM-based storage engine with these features:
- Single-writer based architecture for the storage engine
- WAL for durability, and hey it's configurable
- MemTable with skip list implementation for fast read/writes
- SSTable with block-based structure for on-disk level-based storage
- Background compaction with tiered strategy
- ACID transactions
- Good documentation (I hope)
2025-04-20 14:06:50 -06:00

133 lines
3.0 KiB
Go

package memtable
import (
"fmt"
"math/rand"
"strconv"
"testing"
)
func BenchmarkSkipListInsert(b *testing.B) {
sl := NewSkipList()
// Create random keys ahead of time
keys := make([][]byte, b.N)
values := make([][]byte, b.N)
for i := 0; i < b.N; i++ {
keys[i] = []byte(fmt.Sprintf("key-%d", i))
values[i] = []byte(fmt.Sprintf("value-%d", i))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
e := newEntry(keys[i], values[i], TypeValue, uint64(i))
sl.Insert(e)
}
}
func BenchmarkSkipListFind(b *testing.B) {
sl := NewSkipList()
// Insert entries first
const numEntries = 100000
keys := make([][]byte, numEntries)
for i := 0; i < numEntries; i++ {
key := []byte(fmt.Sprintf("key-%d", i))
value := []byte(fmt.Sprintf("value-%d", i))
keys[i] = key
sl.Insert(newEntry(key, value, TypeValue, uint64(i)))
}
// Create random keys for lookup
lookupKeys := make([][]byte, b.N)
r := rand.New(rand.NewSource(42)) // Use fixed seed for reproducibility
for i := 0; i < b.N; i++ {
idx := r.Intn(numEntries)
lookupKeys[i] = keys[idx]
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
sl.Find(lookupKeys[i])
}
}
func BenchmarkMemTablePut(b *testing.B) {
mt := NewMemTable()
b.ResetTimer()
for i := 0; i < b.N; i++ {
key := []byte("key-" + strconv.Itoa(i))
value := []byte("value-" + strconv.Itoa(i))
mt.Put(key, value, uint64(i))
}
}
func BenchmarkMemTableGet(b *testing.B) {
mt := NewMemTable()
// Insert entries first
const numEntries = 100000
keys := make([][]byte, numEntries)
for i := 0; i < numEntries; i++ {
key := []byte(fmt.Sprintf("key-%d", i))
value := []byte(fmt.Sprintf("value-%d", i))
keys[i] = key
mt.Put(key, value, uint64(i))
}
// Create random keys for lookup
lookupKeys := make([][]byte, b.N)
r := rand.New(rand.NewSource(42)) // Use fixed seed for reproducibility
for i := 0; i < b.N; i++ {
idx := r.Intn(numEntries)
lookupKeys[i] = keys[idx]
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
mt.Get(lookupKeys[i])
}
}
func BenchmarkMemPoolGet(b *testing.B) {
cfg := createTestConfig()
cfg.MemTableSize = 1024 * 1024 * 32 // 32MB for benchmark
pool := NewMemTablePool(cfg)
// Create multiple memtables with entries
const entriesPerTable = 50000
const numTables = 3
keys := make([][]byte, entriesPerTable*numTables)
// Fill tables
for t := 0; t < numTables; t++ {
// Fill a table
for i := 0; i < entriesPerTable; i++ {
idx := t*entriesPerTable + i
key := []byte(fmt.Sprintf("key-%d", idx))
value := []byte(fmt.Sprintf("value-%d", idx))
keys[idx] = key
pool.Put(key, value, uint64(idx))
}
// Switch to a new memtable (except for last one)
if t < numTables-1 {
pool.SwitchToNewMemTable()
}
}
// Create random keys for lookup
lookupKeys := make([][]byte, b.N)
r := rand.New(rand.NewSource(42)) // Use fixed seed for reproducibility
for i := 0; i < b.N; i++ {
idx := r.Intn(entriesPerTable * numTables)
lookupKeys[i] = keys[idx]
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
pool.Get(lookupKeys[i])
}
}