mirror of
https://github.com/luxfi/database.git
synced 2026-10-30 15:01:18 +00:00
463 lines
9.7 KiB
Go
463 lines
9.7 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package linkeddb
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
database "github.com/luxfi/database"
|
|
"github.com/luxfi/database/memdb"
|
|
)
|
|
|
|
func TestLinkedDB(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key := []byte("hello")
|
|
value := []byte("world")
|
|
|
|
has, err := ldb.Has(key)
|
|
require.NoError(err)
|
|
require.False(has)
|
|
|
|
_, err = ldb.Get(key)
|
|
require.Equal(database.ErrNotFound, err)
|
|
|
|
require.NoError(ldb.Delete(key))
|
|
|
|
require.NoError(ldb.Put(key, value))
|
|
|
|
has, err = ldb.Has(key)
|
|
require.NoError(err)
|
|
require.True(has)
|
|
|
|
v, err := ldb.Get(key)
|
|
require.NoError(err)
|
|
require.Equal(value, v)
|
|
|
|
require.NoError(ldb.Delete(key))
|
|
|
|
has, err = ldb.Has(key)
|
|
require.NoError(err)
|
|
require.False(has)
|
|
|
|
_, err = ldb.Get(key)
|
|
require.Equal(database.ErrNotFound, err)
|
|
|
|
iterator := ldb.NewIterator()
|
|
require.False(iterator.Next())
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestLinkedDBDuplicatedPut(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key := []byte("hello")
|
|
value1 := []byte("world1")
|
|
value2 := []byte("world2")
|
|
|
|
require.NoError(ldb.Put(key, value1))
|
|
|
|
require.NoError(ldb.Put(key, value2))
|
|
|
|
v, err := ldb.Get(key)
|
|
require.NoError(err)
|
|
require.Equal(value2, v)
|
|
|
|
require.NoError(ldb.Delete(key))
|
|
|
|
iterator := ldb.NewIterator()
|
|
require.False(iterator.Next())
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestLinkedDBMultiplePuts(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key1 := []byte("hello1")
|
|
key2 := []byte("hello2")
|
|
key3 := []byte("hello3")
|
|
value1 := []byte("world1")
|
|
value2 := []byte("world2")
|
|
value3 := []byte("world3")
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
require.NoError(ldb.Put(key2, value2))
|
|
|
|
v, err := ldb.Get(key1)
|
|
require.NoError(err)
|
|
require.Equal(value1, v)
|
|
|
|
v, err = ldb.Get(key2)
|
|
require.NoError(err)
|
|
require.Equal(value2, v)
|
|
|
|
require.NoError(ldb.Delete(key2))
|
|
|
|
require.NoError(ldb.Put(key2, value2))
|
|
|
|
require.NoError(ldb.Put(key3, value3))
|
|
|
|
require.NoError(ldb.Delete(key2))
|
|
|
|
require.NoError(ldb.Delete(key1))
|
|
|
|
require.NoError(ldb.Delete(key3))
|
|
|
|
iterator := ldb.NewIterator()
|
|
next := iterator.Next()
|
|
require.False(next, "database should be empty")
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestEmptyLinkedDBIterator(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
iterator := ldb.NewIterator()
|
|
next := iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
k := iterator.Key()
|
|
require.Nil(k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Nil(v, "The iterator returned the wrong value")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestLinkedDBLoadHeadKey(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key := []byte("hello")
|
|
value := []byte("world")
|
|
|
|
require.NoError(ldb.Put(key, value))
|
|
|
|
ldb = NewDefault(db)
|
|
|
|
iterator := ldb.NewIterator()
|
|
next := iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k := iterator.Key()
|
|
require.Equal(key, k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Equal(value, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
k = iterator.Key()
|
|
require.Nil(k, "The iterator returned the wrong key")
|
|
|
|
v = iterator.Value()
|
|
require.Nil(v, "The iterator returned the wrong value")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestSingleLinkedDBIterator(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key := []byte("hello")
|
|
value := []byte("world")
|
|
|
|
require.NoError(ldb.Put(key, value))
|
|
|
|
iterator := ldb.NewIterator()
|
|
next := iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k := iterator.Key()
|
|
require.Equal(key, k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Equal(value, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
k = iterator.Key()
|
|
require.Nil(k, "The iterator returned the wrong key")
|
|
|
|
v = iterator.Value()
|
|
require.Nil(v, "The iterator returned the wrong value")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestMultipleLinkedDBIterator(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key0 := []byte("hello0")
|
|
key1 := []byte("hello1")
|
|
value0 := []byte("world0")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
iterator := ldb.NewIterator()
|
|
next := iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k := iterator.Key()
|
|
require.Equal(key1, k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Equal(value1, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k = iterator.Key()
|
|
require.Equal(key0, k, "The iterator returned the wrong key")
|
|
|
|
v = iterator.Value()
|
|
require.Equal(value0, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestMultipleLinkedDBIteratorStart(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key0 := []byte("hello0")
|
|
key1 := []byte("hello1")
|
|
value0 := []byte("world0")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
iterator := ldb.NewIteratorWithStart(key1)
|
|
next := iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k := iterator.Key()
|
|
require.Equal(key1, k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Equal(value1, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k = iterator.Key()
|
|
require.Equal(key0, k, "The iterator returned the wrong key")
|
|
|
|
v = iterator.Value()
|
|
require.Equal(value0, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
func TestSingleLinkedDBIteratorStart(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key0 := []byte("hello0")
|
|
key1 := []byte("hello1")
|
|
value0 := []byte("world0")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
iterator := ldb.NewIteratorWithStart(key0)
|
|
|
|
next := iterator.Next()
|
|
require.True(next, "The iterator shouldn't be exhausted yet")
|
|
|
|
k := iterator.Key()
|
|
require.Equal(key0, k, "The iterator returned the wrong key")
|
|
|
|
v := iterator.Value()
|
|
require.Equal(value0, v, "The iterator returned the wrong value")
|
|
|
|
next = iterator.Next()
|
|
require.False(next, "The iterator should now be exhausted")
|
|
|
|
require.NoError(iterator.Error())
|
|
|
|
iterator.Release()
|
|
}
|
|
|
|
// Test that if we call NewIteratorWithStart with a key that is not
|
|
// in the database, the iterator will start at the head
|
|
func TestEmptyLinkedDBIteratorStart(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
key0 := []byte("hello0")
|
|
key1 := []byte("hello1")
|
|
key2 := []byte("hello2")
|
|
value0 := []byte("world0")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
iter := ldb.NewIteratorWithStart(key2)
|
|
|
|
i := 0
|
|
for iter.Next() {
|
|
require.Contains([][]byte{key0, key1}, iter.Key())
|
|
require.Contains([][]byte{value0, value1}, iter.Value())
|
|
i++
|
|
}
|
|
require.Equal(2, i)
|
|
|
|
require.NoError(iter.Error())
|
|
|
|
iter.Release()
|
|
}
|
|
|
|
func TestLinkedDBIsEmpty(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
isEmpty, err := ldb.IsEmpty()
|
|
require.NoError(err)
|
|
require.True(isEmpty)
|
|
|
|
key := []byte("hello")
|
|
value := []byte("world")
|
|
|
|
require.NoError(ldb.Put(key, value))
|
|
|
|
isEmpty, err = ldb.IsEmpty()
|
|
require.NoError(err)
|
|
require.False(isEmpty)
|
|
|
|
require.NoError(ldb.Delete(key))
|
|
|
|
isEmpty, err = ldb.IsEmpty()
|
|
require.NoError(err)
|
|
require.True(isEmpty)
|
|
}
|
|
|
|
func TestLinkedDBHeadKey(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
_, err := ldb.HeadKey()
|
|
require.Equal(database.ErrNotFound, err)
|
|
|
|
key0 := []byte("hello0")
|
|
value0 := []byte("world0")
|
|
key1 := []byte("hello1")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
headKey, err := ldb.HeadKey()
|
|
require.NoError(err)
|
|
require.Equal(key0, headKey)
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
headKey, err = ldb.HeadKey()
|
|
require.NoError(err)
|
|
require.Equal(key1, headKey)
|
|
|
|
require.NoError(ldb.Delete(key1))
|
|
|
|
headKey, err = ldb.HeadKey()
|
|
require.NoError(err)
|
|
require.Equal(key0, headKey)
|
|
}
|
|
|
|
func TestLinkedDBHead(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
db := memdb.New()
|
|
ldb := NewDefault(db)
|
|
|
|
_, _, err := ldb.Head()
|
|
require.Equal(database.ErrNotFound, err)
|
|
|
|
key0 := []byte("hello0")
|
|
value0 := []byte("world0")
|
|
key1 := []byte("hello1")
|
|
value1 := []byte("world1")
|
|
|
|
require.NoError(ldb.Put(key0, value0))
|
|
|
|
headKey, headVal, err := ldb.Head()
|
|
require.NoError(err)
|
|
require.Equal(key0, headKey)
|
|
require.Equal(value0, headVal)
|
|
|
|
require.NoError(ldb.Put(key1, value1))
|
|
|
|
headKey, headVal, err = ldb.Head()
|
|
require.NoError(err)
|
|
require.Equal(key1, headKey)
|
|
require.Equal(value1, headVal)
|
|
|
|
require.NoError(ldb.Delete(key1))
|
|
|
|
headKey, headVal, err = ldb.Head()
|
|
require.NoError(err)
|
|
require.Equal(key0, headKey)
|
|
require.Equal(value0, headVal)
|
|
}
|