mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/storage/localstore: remove composite retrieval index
This commit is contained in:
parent
e17fec20f2
commit
560532303b
12 changed files with 219 additions and 663 deletions
|
|
@ -87,12 +87,8 @@ func (db *DB) collectGarbage() (collectedCount int64, done bool, err error) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
// delete from retrieve, pull, gc
|
// delete from retrieve, pull, gc
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.DeleteInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalDataIndex.DeleteInBatch(batch, item)
|
db.retrievalDataIndex.DeleteInBatch(batch, item)
|
||||||
db.retrievalAccessIndex.DeleteInBatch(batch, item)
|
db.retrievalAccessIndex.DeleteInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pullIndex.DeleteInBatch(batch, item)
|
db.pullIndex.DeleteInBatch(batch, item)
|
||||||
db.gcIndex.DeleteInBatch(batch, item)
|
db.gcIndex.DeleteInBatch(batch, item)
|
||||||
collectedCount++
|
collectedCount++
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,6 @@ func TestDB_collectGarbageWorker(t *testing.T) {
|
||||||
testDB_collectGarbageWorker(t, db)
|
testDB_collectGarbageWorker(t, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDB_collectGarbageWorker_useRetrievalCompositeIndex tests
|
|
||||||
// garbage collection runs by uploading and syncing a number
|
|
||||||
// of chunks using composite retrieval index.
|
|
||||||
func TestDB_collectGarbageWorker_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{
|
|
||||||
Capacity: 100,
|
|
||||||
UseRetrievalCompositeIndex: true,
|
|
||||||
})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testDB_collectGarbageWorker(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDB_collectGarbageWorker_multipleBatches tests garbage
|
// TestDB_collectGarbageWorker_multipleBatches tests garbage
|
||||||
// collection runs by uploading and syncing a number of
|
// collection runs by uploading and syncing a number of
|
||||||
// chunks by having multiple smaller batches.
|
// chunks by having multiple smaller batches.
|
||||||
|
|
@ -68,25 +55,6 @@ func TestDB_collectGarbageWorker_multipleBatches(t *testing.T) {
|
||||||
testDB_collectGarbageWorker(t, db)
|
testDB_collectGarbageWorker(t, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDB_collectGarbageWorker_multipleBatches_useRetrievalCompositeIndex
|
|
||||||
// tests garbage collection runs by uploading and syncing a number
|
|
||||||
// of chunks using composite retrieval index and having multiple
|
|
||||||
// smaller batches.
|
|
||||||
func TestDB_collectGarbageWorker_multipleBatches_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
// lower the maximal number of chunks in a single
|
|
||||||
// gc batch to ensure multiple batches.
|
|
||||||
defer func(s int64) { gcBatchSize = s }(gcBatchSize)
|
|
||||||
gcBatchSize = 2
|
|
||||||
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{
|
|
||||||
Capacity: 100,
|
|
||||||
UseRetrievalCompositeIndex: true,
|
|
||||||
})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testDB_collectGarbageWorker(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testDB_collectGarbageWorker is a helper test function to test
|
// testDB_collectGarbageWorker is a helper test function to test
|
||||||
// garbage collection runs by uploading and syncing a number of chunks.
|
// garbage collection runs by uploading and syncing a number of chunks.
|
||||||
func testDB_collectGarbageWorker(t *testing.T, db *DB) {
|
func testDB_collectGarbageWorker(t *testing.T, db *DB) {
|
||||||
|
|
@ -163,34 +131,15 @@ func testDB_collectGarbageWorker(t *testing.T, db *DB) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDB_collectGarbageWorker_withRequests tests garbage collection
|
// TestDB_collectGarbageWorker_withRequests is a helper test function
|
||||||
// runs by uploading, syncing and requesting a number of chunks.
|
// to test garbage collection runs by uploading, syncing and
|
||||||
|
// requesting a number of chunks.
|
||||||
func TestDB_collectGarbageWorker_withRequests(t *testing.T) {
|
func TestDB_collectGarbageWorker_withRequests(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, &Options{
|
db, cleanupFunc := newTestDB(t, &Options{
|
||||||
Capacity: 100,
|
Capacity: 100,
|
||||||
})
|
})
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testDB_collectGarbageWorker_withRequests(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDB_collectGarbageWorker_withRequests_useRetrievalCompositeIndex
|
|
||||||
// tests garbage collection runs by uploading, syncing and
|
|
||||||
// requesting a number of chunks using composite retrieval index.
|
|
||||||
func TestDB_collectGarbageWorker_withRequests_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{
|
|
||||||
Capacity: 100,
|
|
||||||
UseRetrievalCompositeIndex: true,
|
|
||||||
})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testDB_collectGarbageWorker_withRequests(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testDB_collectGarbageWorker_withRequests is a helper test function
|
|
||||||
// to test garbage collection runs by uploading, syncing and
|
|
||||||
// requesting a number of chunks.
|
|
||||||
func testDB_collectGarbageWorker_withRequests(t *testing.T, db *DB) {
|
|
||||||
uploader := db.NewPutter(ModePutUpload)
|
uploader := db.NewPutter(ModePutUpload)
|
||||||
syncer := db.NewSetter(ModeSetSync)
|
syncer := db.NewSetter(ModeSetSync)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,24 +80,13 @@ func TestDB_pullIndex(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDB_gcIndex validates garbage collection index by uploading
|
||||||
|
// a chunk with and performing operations using synced, access and
|
||||||
|
// request modes.
|
||||||
func TestDB_gcIndex(t *testing.T) {
|
func TestDB_gcIndex(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testDB_gcIndex(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDB_gcIndex_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testDB_gcIndex(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testDB_gcIndex validates garbage collection index by uploading
|
|
||||||
// a chunk with and performing operations using synced, access and
|
|
||||||
// request modes.
|
|
||||||
func testDB_gcIndex(t *testing.T, db *DB) {
|
|
||||||
uploader := db.NewPutter(ModePutUpload)
|
uploader := db.NewPutter(ModePutUpload)
|
||||||
|
|
||||||
chunkCount := 50
|
chunkCount := 50
|
||||||
|
|
|
||||||
|
|
@ -58,14 +58,7 @@ type DB struct {
|
||||||
// filed that stores number of intems in gc index
|
// filed that stores number of intems in gc index
|
||||||
storedGCSize shed.Uint64Field
|
storedGCSize shed.Uint64Field
|
||||||
|
|
||||||
// this flag is for benchmarking two types of retrieval indexes
|
|
||||||
// - single retrieval composite index retrievalCompositeIndex
|
|
||||||
// - two separated indexes for data and access time
|
|
||||||
// - retrievalDataIndex
|
|
||||||
// - retrievalAccessIndex
|
|
||||||
useRetrievalCompositeIndex bool
|
|
||||||
// retrieval indexes
|
// retrieval indexes
|
||||||
retrievalCompositeIndex shed.Index
|
|
||||||
retrievalDataIndex shed.Index
|
retrievalDataIndex shed.Index
|
||||||
retrievalAccessIndex shed.Index
|
retrievalAccessIndex shed.Index
|
||||||
// sync indexes
|
// sync indexes
|
||||||
|
|
@ -107,15 +100,6 @@ type DB struct {
|
||||||
|
|
||||||
// Options struct holds optional parameters for configuring DB.
|
// Options struct holds optional parameters for configuring DB.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// UseRetrievalCompositeIndex option is for benchmarking
|
|
||||||
// two types of retrieval indexes:
|
|
||||||
// - single retrieval composite index retrievalCompositeIndex
|
|
||||||
// - two separated indexes for data and access time
|
|
||||||
// - retrievalDataIndex
|
|
||||||
// - retrievalAccessIndex
|
|
||||||
// It should be temporary until the decision is reached
|
|
||||||
// about the retrieval index structure.
|
|
||||||
UseRetrievalCompositeIndex bool
|
|
||||||
// MockStore is a mock node store that is used to store
|
// MockStore is a mock node store that is used to store
|
||||||
// chunk data in a central store. It can be used to reduce
|
// chunk data in a central store. It can be used to reduce
|
||||||
// total storage space requirements in testing large number
|
// total storage space requirements in testing large number
|
||||||
|
|
@ -137,7 +121,6 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
||||||
db = &DB{
|
db = &DB{
|
||||||
capacity: o.Capacity,
|
capacity: o.Capacity,
|
||||||
baseKey: baseKey,
|
baseKey: baseKey,
|
||||||
useRetrievalCompositeIndex: o.UseRetrievalCompositeIndex,
|
|
||||||
// channels collectGarbageTrigger and writeGCSizeTrigger
|
// channels collectGarbageTrigger and writeGCSizeTrigger
|
||||||
// need to be buffered with the size of 1
|
// need to be buffered with the size of 1
|
||||||
// to signal another event if it
|
// to signal another event if it
|
||||||
|
|
@ -167,59 +150,7 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if db.useRetrievalCompositeIndex {
|
// Functions for retrieval data index.
|
||||||
var (
|
|
||||||
encodeValueFunc func(fields shed.Item) (value []byte, err error)
|
|
||||||
decodeValueFunc func(keyItem shed.Item, value []byte) (e shed.Item, err error)
|
|
||||||
)
|
|
||||||
if o.MockStore != nil {
|
|
||||||
encodeValueFunc = func(fields shed.Item) (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(keyItem shed.Item, value []byte) (e shed.Item, 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(keyItem.Address)
|
|
||||||
return e, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
encodeValueFunc = func(fields shed.Item) (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(keyItem shed.Item, value []byte) (e shed.Item, 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.Item) (key []byte, err error) {
|
|
||||||
return fields.Address, nil
|
|
||||||
},
|
|
||||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
|
||||||
e.Address = key
|
|
||||||
return e, nil
|
|
||||||
},
|
|
||||||
EncodeValue: encodeValueFunc,
|
|
||||||
DecodeValue: decodeValueFunc,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var (
|
var (
|
||||||
encodeValueFunc func(fields shed.Item) (value []byte, err error)
|
encodeValueFunc func(fields shed.Item) (value []byte, err error)
|
||||||
decodeValueFunc func(keyItem shed.Item, value []byte) (e shed.Item, err error)
|
decodeValueFunc func(keyItem shed.Item, value []byte) (e shed.Item, err error)
|
||||||
|
|
@ -290,7 +221,6 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// pull index allows history and live syncing per po bin
|
// pull index allows history and live syncing per po bin
|
||||||
db.pullIndex, err = db.shed.NewIndex("PO|StoredTimestamp|Hash->nil", shed.IndexFuncs{
|
db.pullIndex, err = db.shed.NewIndex("PO|StoredTimestamp|Hash->nil", shed.IndexFuncs{
|
||||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||||
|
|
|
||||||
|
|
@ -61,36 +61,6 @@ func TestDB(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDB_useRetrievalCompositeIndex checks if optional argument
|
|
||||||
// WithRetrievalCompositeIndex to New constructor is setting the
|
|
||||||
// correct state.
|
|
||||||
func TestDB_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
t.Run("set true", func(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
if !db.useRetrievalCompositeIndex {
|
|
||||||
t.Error("useRetrievalCompositeIndex is not set to true")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("set false", func(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: false})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
t.Error("useRetrievalCompositeIndex is not set to false")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
t.Run("unset", func(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
t.Error("useRetrievalCompositeIndex is not set to false")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDB_updateGCSem tests maxParallelUpdateGC limit.
|
// TestDB_updateGCSem tests maxParallelUpdateGC limit.
|
||||||
// This test temporary sets the limit to a low number,
|
// This test temporary sets the limit to a low number,
|
||||||
// makes updateGC function execution time longer by
|
// makes updateGC function execution time longer by
|
||||||
|
|
@ -321,13 +291,6 @@ func TestGenerateFakeRandomChunk(t *testing.T) {
|
||||||
// chunk values are in the retrieval indexes.
|
// chunk values are in the retrieval indexes.
|
||||||
func newRetrieveIndexesTest(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp int64) func(t *testing.T) {
|
func newRetrieveIndexesTest(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp int64) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
item, err := db.retrievalCompositeIndex.Get(addressToItem(chunk.Address()))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
validateItem(t, item, chunk.Address(), chunk.Data(), storeTimestamp, accessTimestamp)
|
|
||||||
} else {
|
|
||||||
item, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
item, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
@ -341,20 +304,12 @@ func newRetrieveIndexesTest(db *DB, chunk storage.Chunk, storeTimestamp, accessT
|
||||||
t.Errorf("got error %v, want %v", err, wantErr)
|
t.Errorf("got error %v, want %v", err, wantErr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRetrieveIndexesTestWithAccess returns a test function that validates if the right
|
// newRetrieveIndexesTestWithAccess returns a test function that validates if the right
|
||||||
// chunk values are in the retrieval indexes when access time must be stored.
|
// chunk values are in the retrieval indexes when access time must be stored.
|
||||||
func newRetrieveIndexesTestWithAccess(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp int64) func(t *testing.T) {
|
func newRetrieveIndexesTestWithAccess(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp int64) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
item, err := db.retrievalCompositeIndex.Get(addressToItem(chunk.Address()))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
validateItem(t, item, chunk.Address(), chunk.Data(), storeTimestamp, accessTimestamp)
|
|
||||||
} else {
|
|
||||||
item, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
item, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
@ -369,7 +324,6 @@ func newRetrieveIndexesTestWithAccess(db *DB, chunk storage.Chunk, storeTimestam
|
||||||
validateItem(t, item, chunk.Address(), nil, 0, accessTimestamp)
|
validateItem(t, item, chunk.Address(), nil, 0, accessTimestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newPullIndexTest returns a test function that validates if the right
|
// newPullIndexTest returns a test function that validates if the right
|
||||||
|
|
|
||||||
|
|
@ -70,20 +70,10 @@ func (g *Getter) Get(addr storage.Address) (chunk storage.Chunk, err error) {
|
||||||
func (db *DB) get(mode ModeGet, addr storage.Address) (out shed.Item, err error) {
|
func (db *DB) get(mode ModeGet, addr storage.Address) (out shed.Item, err error) {
|
||||||
item := addressToItem(addr)
|
item := addressToItem(addr)
|
||||||
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
out, err = db.retrievalCompositeIndex.Get(item)
|
|
||||||
if err != nil {
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No need to get access timestamp here as it is used
|
|
||||||
// only for some of Modes in update and access time
|
|
||||||
// is not property of the chunk returned by the Accessor.Get.
|
|
||||||
out, err = db.retrievalDataIndex.Get(item)
|
out, err = db.retrievalDataIndex.Get(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
switch mode {
|
switch mode {
|
||||||
// update the access timestamp and gc index
|
// update the access timestamp and gc index
|
||||||
case ModeGetRequest:
|
case ModeGetRequest:
|
||||||
|
|
@ -133,10 +123,6 @@ func (db *DB) updateGC(item shed.Item) (err error) {
|
||||||
|
|
||||||
// update accessTimeStamp in retrieve, gc
|
// update accessTimeStamp in retrieve, gc
|
||||||
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
// access timestamp is already populated
|
|
||||||
// in the provided item, passed from access function.
|
|
||||||
} else {
|
|
||||||
i, err := db.retrievalAccessIndex.Get(item)
|
i, err := db.retrievalAccessIndex.Get(item)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
|
|
@ -146,7 +132,6 @@ func (db *DB) updateGC(item shed.Item) (err error) {
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if item.AccessTimestamp == 0 {
|
if item.AccessTimestamp == 0 {
|
||||||
// chunk is not yes synced
|
// chunk is not yes synced
|
||||||
// do not add it to the gc index
|
// do not add it to the gc index
|
||||||
|
|
@ -157,11 +142,7 @@ func (db *DB) updateGC(item shed.Item) (err error) {
|
||||||
// update access timestamp
|
// update access timestamp
|
||||||
item.AccessTimestamp = now()
|
item.AccessTimestamp = now()
|
||||||
// update retrieve access index
|
// update retrieve access index
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalAccessIndex.PutInBatch(batch, item)
|
db.retrievalAccessIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
// add new entry to gc index
|
// add new entry to gc index
|
||||||
db.gcIndex.PutInBatch(batch, item)
|
db.gcIndex.PutInBatch(batch, item)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,27 +22,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestModeGetRequest validates internal data operations and state
|
// TestModeGetRequest validates ModeGetRequest index values on the provided DB.
|
||||||
// for ModeGetRequest on DB with default configuration.
|
|
||||||
func TestModeGetRequest(t *testing.T) {
|
func TestModeGetRequest(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModeGetRequestValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModeGetRequest_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModeGetRequest on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModeGetRequest_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModeGetRequestValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModeGetRequestValues validates ModeGetRequest index values on the provided DB.
|
|
||||||
func testModeGetRequestValues(t *testing.T, db *DB) {
|
|
||||||
uploadTimestamp := time.Now().UTC().UnixNano()
|
uploadTimestamp := time.Now().UTC().UnixNano()
|
||||||
defer setNow(func() (t int64) {
|
defer setNow(func() (t int64) {
|
||||||
return uploadTimestamp
|
return uploadTimestamp
|
||||||
|
|
@ -152,27 +136,11 @@ func testModeGetRequestValues(t *testing.T, db *DB) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestModeGetSync validates internal data operations and state
|
// TestModeGetSync validates ModeGetSync index values on the provided DB.
|
||||||
// for ModeGetSync on DB with default configuration.
|
|
||||||
func TestModeGetSync(t *testing.T) {
|
func TestModeGetSync(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModeGetSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModeGetSync_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModeGetSync on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModeGetSync_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModeGetSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModeGetSyncValues validates ModeGetSync index values on the provided DB.
|
|
||||||
func testModeGetSyncValues(t *testing.T, db *DB) {
|
|
||||||
uploadTimestamp := time.Now().UTC().UnixNano()
|
uploadTimestamp := time.Now().UTC().UnixNano()
|
||||||
defer setNow(func() (t int64) {
|
defer setNow(func() (t int64) {
|
||||||
return uploadTimestamp
|
return uploadTimestamp
|
||||||
|
|
|
||||||
|
|
@ -78,18 +78,6 @@ func (db *DB) put(mode ModePut, item shed.Item) (err error) {
|
||||||
|
|
||||||
// check if the chunk already is in the database
|
// check if the chunk already is in the database
|
||||||
// as gc index is updated
|
// as gc index is updated
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
i, err := db.retrievalCompositeIndex.Get(item)
|
|
||||||
switch err {
|
|
||||||
case nil:
|
|
||||||
item.AccessTimestamp = i.AccessTimestamp
|
|
||||||
item.StoreTimestamp = i.StoreTimestamp
|
|
||||||
case leveldb.ErrNotFound:
|
|
||||||
// no chunk in database
|
|
||||||
default:
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i, err := db.retrievalAccessIndex.Get(item)
|
i, err := db.retrievalAccessIndex.Get(item)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
|
|
@ -108,7 +96,6 @@ func (db *DB) put(mode ModePut, item shed.Item) (err error) {
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if item.AccessTimestamp != 0 {
|
if item.AccessTimestamp != 0 {
|
||||||
// delete current entry from the gc index
|
// delete current entry from the gc index
|
||||||
db.gcIndex.DeleteInBatch(batch, item)
|
db.gcIndex.DeleteInBatch(batch, item)
|
||||||
|
|
@ -120,32 +107,20 @@ func (db *DB) put(mode ModePut, item shed.Item) (err error) {
|
||||||
// update access timestamp
|
// update access timestamp
|
||||||
item.AccessTimestamp = now()
|
item.AccessTimestamp = now()
|
||||||
// update retrieve access index
|
// update retrieve access index
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalAccessIndex.PutInBatch(batch, item)
|
db.retrievalAccessIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
// add new entry to gc index
|
// add new entry to gc index
|
||||||
db.gcIndex.PutInBatch(batch, item)
|
db.gcIndex.PutInBatch(batch, item)
|
||||||
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
||||||
db.incGCSize(1)
|
db.incGCSize(1)
|
||||||
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalDataIndex.PutInBatch(batch, item)
|
db.retrievalDataIndex.PutInBatch(batch, item)
|
||||||
db.retrievalAccessIndex.PutInBatch(batch, item)
|
db.retrievalAccessIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
|
|
||||||
case ModePutUpload:
|
case ModePutUpload:
|
||||||
// put to indexes: retrieve, push, pull
|
// put to indexes: retrieve, push, pull
|
||||||
|
|
||||||
item.StoreTimestamp = now()
|
item.StoreTimestamp = now()
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalDataIndex.PutInBatch(batch, item)
|
db.retrievalDataIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pullIndex.PutInBatch(batch, item)
|
db.pullIndex.PutInBatch(batch, item)
|
||||||
db.pushIndex.PutInBatch(batch, item)
|
db.pushIndex.PutInBatch(batch, item)
|
||||||
|
|
||||||
|
|
@ -153,11 +128,7 @@ func (db *DB) put(mode ModePut, item shed.Item) (err error) {
|
||||||
// put to indexes: retrieve, pull
|
// put to indexes: retrieve, pull
|
||||||
|
|
||||||
item.StoreTimestamp = now()
|
item.StoreTimestamp = now()
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalDataIndex.PutInBatch(batch, item)
|
db.retrievalDataIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pullIndex.PutInBatch(batch, item)
|
db.pullIndex.PutInBatch(batch, item)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -21,27 +21,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestModePutRequest validates internal data operations and state
|
// TestModePutRequest validates ModePutRequest index values on the provided DB.
|
||||||
// for ModePutRequest on DB with default configuration.
|
|
||||||
func TestModePutRequest(t *testing.T) {
|
func TestModePutRequest(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModePutRequestValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModePutRequest_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModePutRequest on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModePutRequest_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModePutRequestValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModePutRequestValues validates ModePutRequest index values on the provided DB.
|
|
||||||
func testModePutRequestValues(t *testing.T, db *DB) {
|
|
||||||
putter := db.NewPutter(ModePutRequest)
|
putter := db.NewPutter(ModePutRequest)
|
||||||
|
|
||||||
chunk := generateRandomChunk()
|
chunk := generateRandomChunk()
|
||||||
|
|
@ -88,27 +72,11 @@ func testModePutRequestValues(t *testing.T, db *DB) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestModePutSync validates internal data operations and state
|
// TestModePutSync validates ModePutSync index values on the provided DB.
|
||||||
// for ModePutSync on DB with default configuration.
|
|
||||||
func TestModePutSync(t *testing.T) {
|
func TestModePutSync(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModePutSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModePutSync_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModePutSync on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModePutSync_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModePutSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModePutSyncValues validates ModePutSync index values on the provided DB.
|
|
||||||
func testModePutSyncValues(t *testing.T, db *DB) {
|
|
||||||
wantTimestamp := time.Now().UTC().UnixNano()
|
wantTimestamp := time.Now().UTC().UnixNano()
|
||||||
defer setNow(func() (t int64) {
|
defer setNow(func() (t int64) {
|
||||||
return wantTimestamp
|
return wantTimestamp
|
||||||
|
|
@ -126,27 +94,11 @@ func testModePutSyncValues(t *testing.T, db *DB) {
|
||||||
t.Run("pull index", newPullIndexTest(db, chunk, wantTimestamp, nil))
|
t.Run("pull index", newPullIndexTest(db, chunk, wantTimestamp, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestModePutUpload validates internal data operations and state
|
// TestModePutUpload validates ModePutUpload index values on the provided DB.
|
||||||
// for ModePutUpload on DB with default configuration.
|
|
||||||
func TestModePutUpload(t *testing.T) {
|
func TestModePutUpload(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModePutUploadValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModePutUpload_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModePutUpload on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModePutUpload_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModePutUploadValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModePutUploadValues validates ModePutUpload index values on the provided DB.
|
|
||||||
func testModePutUploadValues(t *testing.T, db *DB) {
|
|
||||||
wantTimestamp := time.Now().UTC().UnixNano()
|
wantTimestamp := time.Now().UTC().UnixNano()
|
||||||
defer setNow(func() (t int64) {
|
defer setNow(func() (t int64) {
|
||||||
return wantTimestamp
|
return wantTimestamp
|
||||||
|
|
|
||||||
|
|
@ -79,22 +79,7 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
// need to get access timestamp here as it is not
|
// need to get access timestamp here as it is not
|
||||||
// provided by the access function, and it is not
|
// provided by the access function, and it is not
|
||||||
// a property of a chunk provided to Accessor.Put.
|
// a property of a chunk provided to Accessor.Put.
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
i, err := db.retrievalCompositeIndex.Get(item)
|
|
||||||
switch err {
|
|
||||||
case nil:
|
|
||||||
item.AccessTimestamp = i.AccessTimestamp
|
|
||||||
item.StoreTimestamp = i.StoreTimestamp
|
|
||||||
db.gcIndex.DeleteInBatch(batch, item)
|
|
||||||
db.incGCSize(-1)
|
|
||||||
case leveldb.ErrNotFound:
|
|
||||||
db.pullIndex.DeleteInBatch(batch, item)
|
|
||||||
item.AccessTimestamp = now()
|
|
||||||
item.StoreTimestamp = now()
|
|
||||||
default:
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i, err := db.retrievalDataIndex.Get(item)
|
i, err := db.retrievalDataIndex.Get(item)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
|
|
@ -119,7 +104,6 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
}
|
}
|
||||||
item.AccessTimestamp = now()
|
item.AccessTimestamp = now()
|
||||||
db.retrievalAccessIndex.PutInBatch(batch, item)
|
db.retrievalAccessIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pullIndex.PutInBatch(batch, item)
|
db.pullIndex.PutInBatch(batch, item)
|
||||||
db.gcIndex.PutInBatch(batch, item)
|
db.gcIndex.PutInBatch(batch, item)
|
||||||
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
||||||
|
|
@ -131,34 +115,6 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
// need to get access timestamp here as it is not
|
// need to get access timestamp here as it is not
|
||||||
// provided by the access function, and it is not
|
// provided by the access function, and it is not
|
||||||
// a property of a chunk provided to Accessor.Put.
|
// a property of a chunk provided to Accessor.Put.
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
i, err := db.retrievalCompositeIndex.Get(item)
|
|
||||||
if err != nil {
|
|
||||||
if err == leveldb.ErrNotFound {
|
|
||||||
// chunk is not found,
|
|
||||||
// no need to update gc index
|
|
||||||
// just delete from the push index
|
|
||||||
// if it is there
|
|
||||||
db.pushIndex.DeleteInBatch(batch, item)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
item.AccessTimestamp = i.AccessTimestamp
|
|
||||||
item.StoreTimestamp = i.StoreTimestamp
|
|
||||||
item.Data = i.Data
|
|
||||||
if item.AccessTimestamp == 0 {
|
|
||||||
// the chunk is not accessed before
|
|
||||||
// set access time for gc index
|
|
||||||
item.AccessTimestamp = now()
|
|
||||||
db.retrievalCompositeIndex.PutInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
// the chunk is accessed before
|
|
||||||
// remove the current gc index item
|
|
||||||
db.gcIndex.DeleteInBatch(batch, item)
|
|
||||||
db.incGCSize(-1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i, err := db.retrievalDataIndex.Get(item)
|
i, err := db.retrievalDataIndex.Get(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
|
|
@ -186,7 +142,6 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
}
|
}
|
||||||
item.AccessTimestamp = now()
|
item.AccessTimestamp = now()
|
||||||
db.retrievalAccessIndex.PutInBatch(batch, item)
|
db.retrievalAccessIndex.PutInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pushIndex.DeleteInBatch(batch, item)
|
db.pushIndex.DeleteInBatch(batch, item)
|
||||||
db.gcIndex.PutInBatch(batch, item)
|
db.gcIndex.PutInBatch(batch, item)
|
||||||
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
db.gcUncountedHashesIndex.PutInBatch(batch, item)
|
||||||
|
|
@ -198,14 +153,7 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
// need to get access timestamp here as it is not
|
// need to get access timestamp here as it is not
|
||||||
// provided by the access function, and it is not
|
// provided by the access function, and it is not
|
||||||
// a property of a chunk provided to Accessor.Put.
|
// a property of a chunk provided to Accessor.Put.
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
i, err := db.retrievalCompositeIndex.Get(item)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
item.StoreTimestamp = i.StoreTimestamp
|
|
||||||
item.AccessTimestamp = i.AccessTimestamp
|
|
||||||
} else {
|
|
||||||
i, err := db.retrievalAccessIndex.Get(item)
|
i, err := db.retrievalAccessIndex.Get(item)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
|
|
@ -219,13 +167,9 @@ func (db *DB) set(mode ModeSet, addr storage.Address) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item.StoreTimestamp = i.StoreTimestamp
|
item.StoreTimestamp = i.StoreTimestamp
|
||||||
}
|
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
db.retrievalCompositeIndex.DeleteInBatch(batch, item)
|
|
||||||
} else {
|
|
||||||
db.retrievalDataIndex.DeleteInBatch(batch, item)
|
db.retrievalDataIndex.DeleteInBatch(batch, item)
|
||||||
db.retrievalAccessIndex.DeleteInBatch(batch, item)
|
db.retrievalAccessIndex.DeleteInBatch(batch, item)
|
||||||
}
|
|
||||||
db.pullIndex.DeleteInBatch(batch, item)
|
db.pullIndex.DeleteInBatch(batch, item)
|
||||||
db.gcIndex.DeleteInBatch(batch, item)
|
db.gcIndex.DeleteInBatch(batch, item)
|
||||||
db.gcUncountedHashesIndex.DeleteInBatch(batch, item)
|
db.gcUncountedHashesIndex.DeleteInBatch(batch, item)
|
||||||
|
|
|
||||||
|
|
@ -23,27 +23,11 @@ import (
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestModeSetAccess validates internal data operations and state
|
// TestModeSetAccess validates ModeSetAccess index values on the provided DB.
|
||||||
// for ModeSetAccess on DB with default configuration.
|
|
||||||
func TestModeSetAccess(t *testing.T) {
|
func TestModeSetAccess(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModeSetAccessValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModeSetAccess_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModeSetAccess on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModeSetAccess_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModeSetAccessValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModeSetAccessValues validates ModeSetAccess index values on the provided DB.
|
|
||||||
func testModeSetAccessValues(t *testing.T, db *DB) {
|
|
||||||
chunk := generateRandomChunk()
|
chunk := generateRandomChunk()
|
||||||
|
|
||||||
wantTimestamp := time.Now().UTC().UnixNano()
|
wantTimestamp := time.Now().UTC().UnixNano()
|
||||||
|
|
@ -67,27 +51,11 @@ func testModeSetAccessValues(t *testing.T, db *DB) {
|
||||||
t.Run("gc size", newIndexGCSizeTest(db))
|
t.Run("gc size", newIndexGCSizeTest(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestModeSetSync validates internal data operations and state
|
// TestModeSetSync validates ModeSetSync index values on the provided DB.
|
||||||
// for ModeSetSync on DB with default configuration.
|
|
||||||
func TestModeSetSync(t *testing.T) {
|
func TestModeSetSync(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModeSetSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModeSetSync_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModeSetSync on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModeSetSync_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModeSetSyncValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModeSetSyncValues validates ModeSetSync index values on the provided DB.
|
|
||||||
func testModeSetSyncValues(t *testing.T, db *DB) {
|
|
||||||
chunk := generateRandomChunk()
|
chunk := generateRandomChunk()
|
||||||
|
|
||||||
wantTimestamp := time.Now().UTC().UnixNano()
|
wantTimestamp := time.Now().UTC().UnixNano()
|
||||||
|
|
@ -116,27 +84,11 @@ func testModeSetSyncValues(t *testing.T, db *DB) {
|
||||||
t.Run("gc size", newIndexGCSizeTest(db))
|
t.Run("gc size", newIndexGCSizeTest(db))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestModeSetRemoval validates internal data operations and state
|
// TestModeSetRemoval validates ModeSetRemoval index values on the provided DB.
|
||||||
// for ModeSetRemoval on DB with default configuration.
|
|
||||||
func TestModeSetRemoval(t *testing.T) {
|
func TestModeSetRemoval(t *testing.T) {
|
||||||
db, cleanupFunc := newTestDB(t, nil)
|
db, cleanupFunc := newTestDB(t, nil)
|
||||||
defer cleanupFunc()
|
defer cleanupFunc()
|
||||||
|
|
||||||
testModeSetRemovalValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestModeSetRemoval_useRetrievalCompositeIndex validates internal
|
|
||||||
// data operations and state for ModeSetRemoval on DB with
|
|
||||||
// retrieval composite index enabled.
|
|
||||||
func TestModeSetRemoval_useRetrievalCompositeIndex(t *testing.T) {
|
|
||||||
db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
|
|
||||||
defer cleanupFunc()
|
|
||||||
|
|
||||||
testModeSetRemovalValues(t, db)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testModeSetRemovalValues validates ModeSetRemoval index values on the provided DB.
|
|
||||||
func testModeSetRemovalValues(t *testing.T, db *DB) {
|
|
||||||
chunk := generateRandomChunk()
|
chunk := generateRandomChunk()
|
||||||
|
|
||||||
err := db.NewPutter(ModePutUpload).Put(chunk)
|
err := db.NewPutter(ModePutUpload).Put(chunk)
|
||||||
|
|
@ -151,13 +103,6 @@ func testModeSetRemovalValues(t *testing.T, db *DB) {
|
||||||
|
|
||||||
t.Run("retrieve indexes", func(t *testing.T) {
|
t.Run("retrieve indexes", func(t *testing.T) {
|
||||||
wantErr := leveldb.ErrNotFound
|
wantErr := leveldb.ErrNotFound
|
||||||
if db.useRetrievalCompositeIndex {
|
|
||||||
_, err := db.retrievalCompositeIndex.Get(addressToItem(chunk.Address()))
|
|
||||||
if err != wantErr {
|
|
||||||
t.Errorf("got error %v, want %v", err, wantErr)
|
|
||||||
}
|
|
||||||
t.Run("retrieve index count", newItemsCountTest(db.retrievalCompositeIndex, 0))
|
|
||||||
} else {
|
|
||||||
_, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
_, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
||||||
if err != wantErr {
|
if err != wantErr {
|
||||||
t.Errorf("got error %v, want %v", err, wantErr)
|
t.Errorf("got error %v, want %v", err, wantErr)
|
||||||
|
|
@ -170,7 +115,6 @@ func testModeSetRemovalValues(t *testing.T, db *DB) {
|
||||||
t.Errorf("got error %v, want %v", err, wantErr)
|
t.Errorf("got error %v, want %v", err, wantErr)
|
||||||
}
|
}
|
||||||
t.Run("retrieve access index count", newItemsCountTest(db.retrievalAccessIndex, 0))
|
t.Run("retrieve access index count", newItemsCountTest(db.retrievalAccessIndex, 0))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("pull index", newPullIndexTest(db, chunk, 0, leveldb.ErrNotFound))
|
t.Run("pull index", newPullIndexTest(db, chunk, 0, leveldb.ErrNotFound))
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BenchmarkRetrievalIndexes compares two different retrieval
|
// BenchmarkRetrievalIndexes uploads a number of chunks in order to measure
|
||||||
// index schemas:
|
|
||||||
// - single retrieval composite index retrievalCompositeIndex
|
|
||||||
// - two separated indexes for data and access time
|
|
||||||
// - retrievalDataIndex
|
|
||||||
// - retrievalAccessIndex
|
|
||||||
// This benchmark uploads a number of chunks in order to measure
|
|
||||||
// total time of updating their retrieval indexes by setting them
|
// total time of updating their retrieval indexes by setting them
|
||||||
// to synced state and requesting them.
|
// to synced state and requesting them.
|
||||||
//
|
//
|
||||||
|
|
@ -42,12 +36,9 @@ import (
|
||||||
// goos: darwin
|
// goos: darwin
|
||||||
// goarch: amd64
|
// goarch: amd64
|
||||||
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
||||||
// BenchmarkRetrievalIndexes/1000-split-8 20 75556686 ns/op 19033493 B/op 84500 allocs/op
|
// BenchmarkRetrievalIndexes/1000-8 20 75556686 ns/op 19033493 B/op 84500 allocs/op
|
||||||
// BenchmarkRetrievalIndexes/1000-composite-8 10 143774538 ns/op 67474551 B/op 72104 allocs/op
|
// BenchmarkRetrievalIndexes/10000-8 1 1079084922 ns/op 382792064 B/op 1429644 allocs/op
|
||||||
// BenchmarkRetrievalIndexes/10000-split-8 1 1079084922 ns/op 382792064 B/op 1429644 allocs/op
|
// BenchmarkRetrievalIndexes/100000-8 1 16891305737 ns/op 2629165304 B/op 12465019 allocs/op
|
||||||
// BenchmarkRetrievalIndexes/10000-composite-8 1 2597268475 ns/op 1005916808 B/op 1516443 allocs/op
|
|
||||||
// BenchmarkRetrievalIndexes/100000-split-8 1 16891305737 ns/op 2629165304 B/op 12465019 allocs/op
|
|
||||||
// BenchmarkRetrievalIndexes/100000-composite-8 1 67158059676 ns/op 12292703424 B/op 22436767 allocs/op
|
|
||||||
// PASS
|
// PASS
|
||||||
func BenchmarkRetrievalIndexes(b *testing.B) {
|
func BenchmarkRetrievalIndexes(b *testing.B) {
|
||||||
for _, count := range []int{
|
for _, count := range []int{
|
||||||
|
|
@ -60,11 +51,6 @@ func BenchmarkRetrievalIndexes(b *testing.B) {
|
||||||
benchmarkRetrievalIndexes(b, nil, count)
|
benchmarkRetrievalIndexes(b, nil, count)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
b.Run(strconv.Itoa(count)+"-composite", func(b *testing.B) {
|
|
||||||
for n := 0; n < b.N; n++ {
|
|
||||||
benchmarkRetrievalIndexes(b, &Options{UseRetrievalCompositeIndex: true}, count)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,12 +108,9 @@ func benchmarkRetrievalIndexes(b *testing.B, o *Options, count int) {
|
||||||
// goos: darwin
|
// goos: darwin
|
||||||
// goarch: amd64
|
// goarch: amd64
|
||||||
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
// pkg: github.com/ethereum/go-ethereum/swarm/storage/localstore
|
||||||
// BenchmarkUpload/1000-split-8 20 59437463 ns/op 25205193 B/op 23208 allocs/op
|
// BenchmarkUpload/1000-8 20 59437463 ns/op 25205193 B/op 23208 allocs/op
|
||||||
// BenchmarkUpload/1000-composite-8 20 59823642 ns/op 25204900 B/op 23202 allocs/op
|
// BenchmarkUpload/10000-8 2 580646362 ns/op 216532932 B/op 248090 allocs/op
|
||||||
// BenchmarkUpload/10000-split-8 2 580646362 ns/op 216532932 B/op 248090 allocs/op
|
// BenchmarkUpload/100000-8 1 22373390892 ns/op 2323055312 B/op 3995903 allocs/op
|
||||||
// BenchmarkUpload/10000-composite-8 2 589351080 ns/op 216540740 B/op 248007 allocs/op
|
|
||||||
// BenchmarkUpload/100000-split-8 1 22373390892 ns/op 2323055312 B/op 3995903 allocs/op
|
|
||||||
// BenchmarkUpload/100000-composite-8 1 22090725078 ns/op 2320312976 B/op 3969219 allocs/op
|
|
||||||
// PASS
|
// PASS
|
||||||
func BenchmarkUpload(b *testing.B) {
|
func BenchmarkUpload(b *testing.B) {
|
||||||
for _, count := range []int{
|
for _, count := range []int{
|
||||||
|
|
@ -135,16 +118,11 @@ func BenchmarkUpload(b *testing.B) {
|
||||||
10000,
|
10000,
|
||||||
100000,
|
100000,
|
||||||
} {
|
} {
|
||||||
b.Run(strconv.Itoa(count)+"-split", func(b *testing.B) {
|
b.Run(strconv.Itoa(count), func(b *testing.B) {
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
benchmarkUpload(b, nil, count)
|
benchmarkUpload(b, nil, count)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
b.Run(strconv.Itoa(count)+"-composite", func(b *testing.B) {
|
|
||||||
for n := 0; n < b.N; n++ {
|
|
||||||
benchmarkUpload(b, &Options{UseRetrievalCompositeIndex: true}, count)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue