mirror of
https://github.com/luxfi/database.git
synced 2026-10-30 15:01:18 +00:00
186 lines
3.9 KiB
Go
186 lines
3.9 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package hookdb
|
|
|
|
import (
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/luxfi/database/memdb"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHookDB_Put(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, DefaultConfig())
|
|
defer hookDB.Close()
|
|
|
|
var eventCount atomic.Int32
|
|
var (
|
|
mu sync.Mutex
|
|
lastEvent Event
|
|
)
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
eventCount.Add(1)
|
|
mu.Lock()
|
|
lastEvent = e
|
|
mu.Unlock()
|
|
})
|
|
|
|
// Put a value
|
|
err := hookDB.Put([]byte("key1"), []byte("value1"))
|
|
require.NoError(err)
|
|
|
|
// Wait for async processing
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
mu.Lock()
|
|
got := lastEvent
|
|
mu.Unlock()
|
|
require.Equal(int32(1), eventCount.Load())
|
|
require.Equal(EventPut, got.Type)
|
|
require.Equal([]byte("key1"), got.Key)
|
|
require.Equal([]byte("value1"), got.Value)
|
|
|
|
// Verify data was written
|
|
val, err := hookDB.Get([]byte("key1"))
|
|
require.NoError(err)
|
|
require.Equal([]byte("value1"), val)
|
|
}
|
|
|
|
func TestHookDB_Delete(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, DefaultConfig())
|
|
defer hookDB.Close()
|
|
|
|
var eventCount atomic.Int32
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
eventCount.Add(1)
|
|
})
|
|
|
|
// Put then delete
|
|
err := hookDB.Put([]byte("key1"), []byte("value1"))
|
|
require.NoError(err)
|
|
|
|
err = hookDB.Delete([]byte("key1"))
|
|
require.NoError(err)
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
require.Equal(int32(2), eventCount.Load()) // Put + Delete
|
|
}
|
|
|
|
func TestHookDB_PrefixFilter(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, DefaultConfig())
|
|
defer hookDB.Close()
|
|
|
|
var blockEvents atomic.Int32
|
|
var txEvents atomic.Int32
|
|
|
|
hookDB.RegisterHandler([]byte("block:"), func(e Event) {
|
|
blockEvents.Add(1)
|
|
})
|
|
|
|
hookDB.RegisterHandler([]byte("tx:"), func(e Event) {
|
|
txEvents.Add(1)
|
|
})
|
|
|
|
// Write with different prefixes
|
|
hookDB.Put([]byte("block:123"), []byte("block data"))
|
|
hookDB.Put([]byte("tx:456"), []byte("tx data"))
|
|
hookDB.Put([]byte("other:789"), []byte("other data"))
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
require.Equal(int32(1), blockEvents.Load())
|
|
require.Equal(int32(1), txEvents.Load())
|
|
}
|
|
|
|
func TestHookDB_Batch(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, DefaultConfig())
|
|
defer hookDB.Close()
|
|
|
|
var eventCount atomic.Int32
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
eventCount.Add(1)
|
|
})
|
|
|
|
// Create batch
|
|
batch := hookDB.NewBatch()
|
|
batch.Put([]byte("key1"), []byte("value1"))
|
|
batch.Put([]byte("key2"), []byte("value2"))
|
|
batch.Put([]byte("key3"), []byte("value3"))
|
|
|
|
// Events shouldn't fire until Write
|
|
time.Sleep(50 * time.Millisecond)
|
|
require.Equal(int32(0), eventCount.Load())
|
|
|
|
// Write batch
|
|
err := batch.Write()
|
|
require.NoError(err)
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
require.Equal(int32(3), eventCount.Load())
|
|
}
|
|
|
|
func TestHookDB_MultipleHandlers(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, DefaultConfig())
|
|
defer hookDB.Close()
|
|
|
|
var handler1Count atomic.Int32
|
|
var handler2Count atomic.Int32
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
handler1Count.Add(1)
|
|
})
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
handler2Count.Add(1)
|
|
})
|
|
|
|
hookDB.Put([]byte("key"), []byte("value"))
|
|
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
// Both handlers should receive the event
|
|
require.Equal(int32(1), handler1Count.Load())
|
|
require.Equal(int32(1), handler2Count.Load())
|
|
}
|
|
|
|
func BenchmarkHookDB_Put(b *testing.B) {
|
|
memDB := memdb.New()
|
|
hookDB := New(memDB, Config{BufferSize: 100000, Workers: 4})
|
|
defer hookDB.Close()
|
|
|
|
hookDB.RegisterHandler(nil, func(e Event) {
|
|
// Simulate some processing
|
|
})
|
|
|
|
key := []byte("benchmark-key")
|
|
value := []byte("benchmark-value")
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
hookDB.Put(key, value)
|
|
}
|
|
}
|