diff --git a/swarm/shed/example_store_test.go b/swarm/shed/example_store_test.go index 2ed0be1413..68b2584d96 100644 --- a/swarm/shed/example_store_test.go +++ b/swarm/shed/example_store_test.go @@ -84,7 +84,7 @@ func New(path string) (s *Store, err error) { value = append(b, fields.Data...) return value, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) e.Data = value[8:] return e, nil @@ -108,7 +108,7 @@ func New(path string) (s *Store, err error) { binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp)) return b, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { e.AccessTimestamp = int64(binary.BigEndian.Uint64(value)) return e, nil }, @@ -134,7 +134,7 @@ func New(path string) (s *Store, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { return nil, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { return e, nil }, }) diff --git a/swarm/shed/index.go b/swarm/shed/index.go index ba803e3c23..70bb15f74b 100644 --- a/swarm/shed/index.go +++ b/swarm/shed/index.go @@ -77,7 +77,7 @@ type Index struct { encodeKeyFunc func(fields IndexItem) (key []byte, err error) decodeKeyFunc func(key []byte) (e IndexItem, err error) encodeValueFunc func(fields IndexItem) (value []byte, err error) - decodeValueFunc func(value []byte) (e IndexItem, err error) + decodeValueFunc func(keyFields IndexItem, value []byte) (e IndexItem, err error) } // IndexFuncs structure defines functions for encoding and decoding @@ -86,7 +86,7 @@ type IndexFuncs struct { EncodeKey func(fields IndexItem) (key []byte, err error) DecodeKey func(key []byte) (e IndexItem, err error) EncodeValue func(fields IndexItem) (value []byte, err error) - DecodeValue func(value []byte) (e IndexItem, err error) + DecodeValue func(keyFields IndexItem, value []byte) (e IndexItem, err error) } // NewIndex returns a new Index instance with defined name and @@ -135,7 +135,7 @@ func (f Index) Get(keyFields IndexItem) (out IndexItem, err error) { if err != nil { return out, err } - out, err = f.decodeValueFunc(value) + out, err = f.decodeValueFunc(keyFields, value) if err != nil { return out, err } @@ -210,15 +210,15 @@ func (f Index) IterateAll(fn IndexIterFunc) (err error) { if key[0] != f.prefix[0] { break } - keyIndexItem, err := f.decodeKeyFunc(key) + keyItem, err := f.decodeKeyFunc(key) if err != nil { return err } - valueIndexItem, err := f.decodeValueFunc(it.Value()) + valueItem, err := f.decodeValueFunc(keyItem, it.Value()) if err != nil { return err } - stop, err := fn(keyIndexItem.Merge(valueIndexItem)) + stop, err := fn(keyItem.Merge(valueItem)) if err != nil { return err } @@ -244,15 +244,15 @@ func (f Index) IterateFrom(start IndexItem, fn IndexIterFunc) (err error) { if key[0] != f.prefix[0] { break } - keyIndexItem, err := f.decodeKeyFunc(key) + keyItem, err := f.decodeKeyFunc(key) if err != nil { return err } - valueIndexItem, err := f.decodeValueFunc(it.Value()) + valueItem, err := f.decodeValueFunc(keyItem, it.Value()) if err != nil { return err } - stop, err := fn(keyIndexItem.Merge(valueIndexItem)) + stop, err := fn(keyItem.Merge(valueItem)) if err != nil { return err } diff --git a/swarm/shed/index_test.go b/swarm/shed/index_test.go index ba82216dfe..33003b1f23 100644 --- a/swarm/shed/index_test.go +++ b/swarm/shed/index_test.go @@ -42,7 +42,7 @@ var retrievalIndexFuncs = IndexFuncs{ value = append(b, fields.Data...) return value, nil }, - DecodeValue: func(value []byte) (e IndexItem, err error) { + DecodeValue: func(keyItem IndexItem, value []byte) (e IndexItem, err error) { e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) e.Data = value[8:] return e, nil diff --git a/swarm/storage/localstore/accessor_test.go b/swarm/storage/localstore/accessor_test.go index 439f7d9db3..810f1e49f0 100644 --- a/swarm/storage/localstore/accessor_test.go +++ b/swarm/storage/localstore/accessor_test.go @@ -19,30 +19,74 @@ package localstore import ( "bytes" "context" + "io/ioutil" "testing" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/storage/mock" + "github.com/ethereum/go-ethereum/swarm/storage/mock/mem" ) // TestAccessors tests most basic Put and Get functionalities // for different accessors. func TestAccessors(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testAccessors(t, db) } -// TestAccessors_withRetrievalCompositeIndex tests most basic +// TestAccessors_useRetrievalCompositeIndex tests most basic // Put and Get functionalities for different accessors // by using retrieval composite index. -func TestAccessors_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestAccessors_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testAccessors(t, db) } +// TestAccessors_mockStore tests most basic Put and Get +// functionalities for different accessors with the mock store +// as the storage for chunk data. +func TestAccessors_mockStore(t *testing.T) { + globalStore := mem.NewGlobalStore() + + addr := common.BytesToAddress(make([]byte, 32)) + + db, cleanupFunc := newTestDB(t, &Options{ + MockStore: globalStore.NewNodeStore(addr), + }) + defer cleanupFunc() + + testAccessors(t, db) + + // testAccessors leaves 5 chunks in global store + checkGlobalStoreChunkCount(t, globalStore, 5) +} + +// TestAccessors_mockStore_useRetrievalCompositeIndex tests +// most basic Put and Get functionalities for different accessors +// with the mock store as the storage for chunk data and by using +// retrieval composite index. +func TestAccessors_mockStore_useRetrievalCompositeIndex(t *testing.T) { + globalStore := mem.NewGlobalStore() + + addr := common.BytesToAddress(make([]byte, 32)) + + db, cleanupFunc := newTestDB(t, &Options{ + MockStore: globalStore.NewNodeStore(addr), + UseRetrievalCompositeIndex: true, + }) + defer cleanupFunc() + + testAccessors(t, db) + + // testAccessors leaves 5 chunks in global store + checkGlobalStoreChunkCount(t, globalStore, 5) +} + // testAccessors tests most basic Put and Get functionalities // for different accessors. This test validates that the chunk // is retrievable from the database, not if all indexes are set @@ -153,3 +197,17 @@ func testAccessors(t *testing.T, db *DB) { } }) } + +// checkGlobalStoreChunkCount counts the number of chunks +// in a global mock store to validate it against the expected value. +func checkGlobalStoreChunkCount(t *testing.T, s mock.ImportExporter, want int) { + t.Helper() + + n, err := s.Export(ioutil.Discard) + if err != nil { + t.Fatal(err) + } + if n != want { + t.Errorf("got %v chunks, want %v", n, want) + } +} diff --git a/swarm/storage/localstore/localstore.go b/swarm/storage/localstore/localstore.go index 6de38310c4..d6fc0c7608 100644 --- a/swarm/storage/localstore/localstore.go +++ b/swarm/storage/localstore/localstore.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/swarm/shed" "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/storage/mock" ) const ( @@ -73,36 +74,26 @@ type DB struct { close chan struct{} // closed on Close, signals other goroutines to terminate } -// Option is a function that sets optional field values on DB. -// It is used as a variadic parameter to New constructor. -type Option func(*DB) - -// WithRetrievalCompositeIndex is the optional variadic parameter to New constructor -// to use the single retrieval composite index instead two separate for data -// and access timestamp. This option is used for benchmarking this two types of -// retrieval schemas for performance. Composite retrieval index performes less seeks -// on retrieval as it has two times less key/value pairs then alternative approach, -// but it needs to write chunk data on every access timestamp change. -func WithRetrievalCompositeIndex(use bool) Option { - return func(db *DB) { - db.useRetrievalCompositeIndex = use - } +// Options struct holds optional parameters for configuring DB. +type Options struct { + UseRetrievalCompositeIndex bool + MockStore *mock.NodeStore } // New returns a new DB. All fields and indexes are initialized // and possible conflicts with schema from existing database is checked. // One goroutine for writing batches is created. -func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { - db = &DB{ - baseKey: baseKey, - batch: newBatch(), - writeTrigger: make(chan struct{}, 1), - close: make(chan struct{}), - writeDone: make(chan struct{}), +func New(path string, baseKey []byte, o *Options) (db *DB, err error) { + if o == nil { + o = new(Options) } - - for _, o := range opts { - o(db) + db = &DB{ + baseKey: baseKey, + useRetrievalCompositeIndex: o.UseRetrievalCompositeIndex, + batch: newBatch(), + writeTrigger: make(chan struct{}, 1), + close: make(chan struct{}), + writeDone: make(chan struct{}), } db.shed, err = shed.NewDB(path) @@ -119,6 +110,42 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { return nil, err } if db.useRetrievalCompositeIndex { + var ( + encodeValueFunc func(fields shed.IndexItem) (value []byte, err error) + decodeValueFunc func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) + ) + if o.MockStore != nil { + encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) { + b := make([]byte, 16) + binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp)) + binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp)) + err = o.MockStore.Put(fields.Address, fields.Data) + if err != nil { + return nil, err + } + return b, nil + } + decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { + e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) + e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16])) + e.Data, err = o.MockStore.Get(keyIndexItem.Address) + return e, err + } + } else { + encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) { + b := make([]byte, 16) + binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp)) + binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp)) + value = append(b, fields.Data...) + return value, nil + } + decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { + e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) + e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16])) + e.Data = value[16:] + return e, nil + } + } // Index storing chunk data with stored and access timestamps. db.retrievalCompositeIndex, err = db.shed.NewIndex("Hash->StoredTimestamp|AccessTimestamp|Data", shed.IndexFuncs{ EncodeKey: func(fields shed.IndexItem) (key []byte, err error) { @@ -128,24 +155,45 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { e.Address = key return e, nil }, - EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { - b := make([]byte, 16) - binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp)) - binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp)) - value = append(b, fields.Data...) - return value, nil - }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { - e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) - e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16])) - e.Data = value[16:] - return e, nil - }, + EncodeValue: encodeValueFunc, + DecodeValue: decodeValueFunc, }) if err != nil { return nil, err } } else { + var ( + encodeValueFunc func(fields shed.IndexItem) (value []byte, err error) + decodeValueFunc func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) + ) + if o.MockStore != nil { + encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp)) + err = o.MockStore.Put(fields.Address, fields.Data) + if err != nil { + return nil, err + } + return b, nil + } + decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { + e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) + e.Data, err = o.MockStore.Get(keyIndexItem.Address) + return e, err + } + } else { + encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp)) + value = append(b, fields.Data...) + return value, nil + } + decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { + e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) + e.Data = value[8:] + return e, nil + } + } // Index storing actual chunk address, data and store timestamp. db.retrievalDataIndex, err = db.shed.NewIndex("Address->StoreTimestamp|Data", shed.IndexFuncs{ EncodeKey: func(fields shed.IndexItem) (key []byte, err error) { @@ -155,17 +203,8 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { e.Address = key return e, nil }, - EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp)) - value = append(b, fields.Data...) - return value, nil - }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { - e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) - e.Data = value[8:] - return e, nil - }, + EncodeValue: encodeValueFunc, + DecodeValue: decodeValueFunc, }) if err != nil { return nil, err @@ -185,7 +224,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp)) return b, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { e.AccessTimestamp = int64(binary.BigEndian.Uint64(value)) return e, nil }, @@ -211,7 +250,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { return nil, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { return e, nil }, }) @@ -234,7 +273,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { return nil, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { return e, nil }, }) @@ -259,7 +298,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { return nil, nil }, - DecodeValue: func(value []byte) (e shed.IndexItem, err error) { + DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) { return e, nil }, }) diff --git a/swarm/storage/localstore/localstore_test.go b/swarm/storage/localstore/localstore_test.go index e019e0f058..7e276ad269 100644 --- a/swarm/storage/localstore/localstore_test.go +++ b/swarm/storage/localstore/localstore_test.go @@ -26,12 +26,12 @@ import ( "github.com/ethereum/go-ethereum/swarm/storage" ) -// TestWithRetrievalCompositeIndex checks if optional argument +// TestDB_useRetrievalCompositeIndex checks if optional argument // WithRetrievalCompositeIndex to New constructor is setting the // correct state. -func TestWithRetrievalCompositeIndex(t *testing.T) { +func TestDB_useRetrievalCompositeIndex(t *testing.T) { t.Run("set true", func(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() if !db.useRetrievalCompositeIndex { @@ -39,7 +39,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) { } }) t.Run("set false", func(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(false)) + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: false}) defer cleanupFunc() if db.useRetrievalCompositeIndex { @@ -47,7 +47,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) { } }) t.Run("unset", func(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() if db.useRetrievalCompositeIndex { @@ -59,7 +59,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) { // newTestDB is a helper function that constructs a // temporary database and returns a cleanup function that must // be called to remove the data. -func newTestDB(t *testing.T, opts ...Option) (db *DB, cleanupFunc func()) { +func newTestDB(t *testing.T, o *Options) (db *DB, cleanupFunc func()) { t.Helper() dir, err := ioutil.TempDir("", "shed-test") @@ -71,7 +71,7 @@ func newTestDB(t *testing.T, opts ...Option) (db *DB, cleanupFunc func()) { if _, err := rand.Read(baseKey); err != nil { t.Fatal(err) } - db, err = New(dir, baseKey, opts...) + db, err = New(dir, baseKey, o) if err != nil { cleanupFunc() t.Fatal(err) diff --git a/swarm/storage/localstore/mode_test.go b/swarm/storage/localstore/mode_test.go index 7321ccdfda..da226f3eb6 100644 --- a/swarm/storage/localstore/mode_test.go +++ b/swarm/storage/localstore/mode_test.go @@ -31,17 +31,17 @@ import ( // TestModeSyncing validates internal data operations and state // for ModeSyncing on DB with default configuration. func TestModeSyncing(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeSyncingValues(t, db) } -// TestModeSyncing_withRetrievalCompositeIndex validates internal +// TestModeSyncing_useRetrievalCompositeIndex validates internal // data operations and state for ModeSyncing on DB with // retrieval composite index enabled. -func TestModeSyncing_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeSyncing_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeSyncingValues(t, db) @@ -81,17 +81,17 @@ func testModeSyncingValues(t *testing.T, db *DB) { // TestModeUpload validates internal data operations and state // for ModeUpload on DB with default configuration. func TestModeUpload(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeUploadValues(t, db) } -// TestModeUpload_withRetrievalCompositeIndex validates internal +// TestModeUpload_useRetrievalCompositeIndex validates internal // data operations and state for ModeUpload on DB with // retrieval composite index enabled. -func TestModeUpload_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeUpload_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeUploadValues(t, db) @@ -133,17 +133,17 @@ func testModeUploadValues(t *testing.T, db *DB) { // TestModeRequest validates internal data operations and state // for ModeRequest on DB with default configuration. func TestModeRequest(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeRequestValues(t, db) } -// TestModeRequest_withRetrievalCompositeIndex validates internal +// TestModeRequest_useRetrievalCompositeIndex validates internal // data operations and state for ModeRequest on DB with // retrieval composite index enabled. -func TestModeRequest_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeRequest_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeRequestValues(t, db) @@ -174,17 +174,17 @@ func testModeRequestValues(t *testing.T, db *DB) { // TestModeSynced validates internal data operations and state // for ModeSynced on DB with default configuration. func TestModeSynced(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeSyncedValues(t, db) } -// TestModeSynced_withRetrievalCompositeIndex validates internal +// TestModeSynced_useRetrievalCompositeIndex validates internal // data operations and state for ModeSynced on DB with // retrieval composite index enabled. -func TestModeSynced_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeSynced_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeSyncedValues(t, db) @@ -224,17 +224,17 @@ func testModeSyncedValues(t *testing.T, db *DB) { // TestModeAccess validates internal data operations and state // for ModeAccess on DB with default configuration. func TestModeAccess(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeAccessValues(t, db) } -// TestModeAccess_withRetrievalCompositeIndex validates internal +// TestModeAccess_useRetrievalCompositeIndex validates internal // data operations and state for ModeAccess on DB with // retrieval composite index enabled. -func TestModeAccess_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeAccess_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeAccessValues(t, db) @@ -310,17 +310,17 @@ func testModeAccessValues(t *testing.T, db *DB) { // TestModeRemoval validates internal data operations and state // for ModeRemoval on DB with default configuration. func TestModeRemoval(t *testing.T) { - db, cleanupFunc := newTestDB(t) + db, cleanupFunc := newTestDB(t, nil) defer cleanupFunc() testModeRemovalValues(t, db) } -// TestModeRemoval_withRetrievalCompositeIndex validates internal +// TestModeRemoval_useRetrievalCompositeIndex validates internal // data operations and state for ModeRemoval on DB with // retrieval composite index enabled. -func TestModeRemoval_withRetrievalCompositeIndex(t *testing.T) { - db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) +func TestModeRemoval_useRetrievalCompositeIndex(t *testing.T) { + db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true}) defer cleanupFunc() testModeRemovalValues(t, db)