mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
swarm/shed, swarm/storage/localstore: rename IndexItem to Item
This commit is contained in:
parent
e6e29f55ee
commit
750268d8d0
14 changed files with 187 additions and 187 deletions
|
|
@ -18,7 +18,7 @@
|
|||
// more complex operations on storage data organized in fields and indexes.
|
||||
//
|
||||
// Only type which holds logical information about swarm storage chunks data
|
||||
// and metadata is IndexItem. This part is not generalized mostly for
|
||||
// and metadata is Item. This part is not generalized mostly for
|
||||
// performance reasons.
|
||||
package shed
|
||||
|
||||
|
|
|
|||
|
|
@ -71,20 +71,20 @@ func New(path string) (s *Store, err error) {
|
|||
}
|
||||
// Index storing actual chunk address, data and store timestamp.
|
||||
s.retrievalIndex, err = db.NewIndex("Address->StoreTimestamp|Data", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (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(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
|
||||
e.Data = value[8:]
|
||||
return e, nil
|
||||
|
|
@ -96,19 +96,19 @@ func New(path string) (s *Store, err error) {
|
|||
// Index storing access timestamp for a particular address.
|
||||
// It is needed in order to update gc index keys for iteration order.
|
||||
s.accessIndex, err = db.NewIndex("Address->AccessTimestamp", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp))
|
||||
return b, nil
|
||||
},
|
||||
DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value))
|
||||
return e, nil
|
||||
},
|
||||
|
|
@ -118,23 +118,23 @@ func New(path string) (s *Store, err error) {
|
|||
}
|
||||
// Index with keys ordered by access timestamp for garbage collection prioritization.
|
||||
s.gcIndex, err = db.NewIndex("AccessTimestamp|StoredTimestamp|Address->nil", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
b := make([]byte, 16, 16+len(fields.Address))
|
||||
binary.BigEndian.PutUint64(b[:8], uint64(fields.AccessTimestamp))
|
||||
binary.BigEndian.PutUint64(b[8:16], uint64(fields.StoreTimestamp))
|
||||
key = append(b, fields.Address...)
|
||||
return key, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.AccessTimestamp = int64(binary.BigEndian.Uint64(key[:8]))
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(key[8:16]))
|
||||
e.Address = key[16:]
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
return nil, nil
|
||||
},
|
||||
DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
return e, nil
|
||||
},
|
||||
})
|
||||
|
|
@ -146,7 +146,7 @@ func New(path string) (s *Store, err error) {
|
|||
|
||||
// Put stores the chunk and sets it store timestamp.
|
||||
func (s *Store) Put(_ context.Context, ch storage.Chunk) (err error) {
|
||||
return s.retrievalIndex.Put(shed.IndexItem{
|
||||
return s.retrievalIndex.Put(shed.Item{
|
||||
Address: ch.Address(),
|
||||
Data: ch.Data(),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -161,7 +161,7 @@ func (s *Store) Get(_ context.Context, addr storage.Address) (c storage.Chunk, e
|
|||
batch := new(leveldb.Batch)
|
||||
|
||||
// Get the chunk data and storage timestamp.
|
||||
item, err := s.retrievalIndex.Get(shed.IndexItem{
|
||||
item, err := s.retrievalIndex.Get(shed.Item{
|
||||
Address: addr,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -172,13 +172,13 @@ func (s *Store) Get(_ context.Context, addr storage.Address) (c storage.Chunk, e
|
|||
}
|
||||
|
||||
// Get the chunk access timestamp.
|
||||
accessItem, err := s.accessIndex.Get(shed.IndexItem{
|
||||
accessItem, err := s.accessIndex.Get(shed.Item{
|
||||
Address: addr,
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
// Remove gc index entry if access timestamp is found.
|
||||
err = s.gcIndex.DeleteInBatch(batch, shed.IndexItem{
|
||||
err = s.gcIndex.DeleteInBatch(batch, shed.Item{
|
||||
Address: item.Address,
|
||||
StoreTimestamp: accessItem.AccessTimestamp,
|
||||
AccessTimestamp: item.StoreTimestamp,
|
||||
|
|
@ -197,7 +197,7 @@ func (s *Store) Get(_ context.Context, addr storage.Address) (c storage.Chunk, e
|
|||
accessTimestamp := time.Now().UTC().UnixNano()
|
||||
|
||||
// Put new access timestamp in access index.
|
||||
err = s.accessIndex.PutInBatch(batch, shed.IndexItem{
|
||||
err = s.accessIndex.PutInBatch(batch, shed.Item{
|
||||
Address: addr,
|
||||
AccessTimestamp: accessTimestamp,
|
||||
})
|
||||
|
|
@ -206,7 +206,7 @@ func (s *Store) Get(_ context.Context, addr storage.Address) (c storage.Chunk, e
|
|||
}
|
||||
|
||||
// Put new access timestamp in gc index.
|
||||
err = s.gcIndex.PutInBatch(batch, shed.IndexItem{
|
||||
err = s.gcIndex.PutInBatch(batch, shed.Item{
|
||||
Address: item.Address,
|
||||
AccessTimestamp: accessTimestamp,
|
||||
StoreTimestamp: item.StoreTimestamp,
|
||||
|
|
@ -244,7 +244,7 @@ func (s *Store) CollectGarbage() (err error) {
|
|||
// New batch for a new cg round.
|
||||
trash := new(leveldb.Batch)
|
||||
// Iterate through all index items and break when needed.
|
||||
err = s.gcIndex.IterateAll(func(item shed.IndexItem) (stop bool, err error) {
|
||||
err = s.gcIndex.IterateAll(func(item shed.Item) (stop bool, err error) {
|
||||
// Remove the chunk.
|
||||
err = s.retrievalIndex.DeleteInBatch(trash, item)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -20,19 +20,19 @@ import (
|
|||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
// IndexItem holds fields relevant to Swarm Chunk data and metadata.
|
||||
// Item holds fields relevant to Swarm Chunk data and metadata.
|
||||
// All information required for swarm storage and operations
|
||||
// on that storage must be defined here.
|
||||
// This structure is logically connected to swarm storage,
|
||||
// the only part of this package that is not generalized,
|
||||
// mostly for performance reasons.
|
||||
//
|
||||
// IndexItem is a type that is used for retrieving, storing and encoding
|
||||
// Item is a type that is used for retrieving, storing and encoding
|
||||
// chunk data and metadata. It is passed as an argument to Index encoding
|
||||
// functions, get function and put function.
|
||||
// But it is also returned with additional data from get function call
|
||||
// and as the argument in iterator function definition.
|
||||
type IndexItem struct {
|
||||
type Item struct {
|
||||
Address []byte
|
||||
Data []byte
|
||||
AccessTimestamp int64
|
||||
|
|
@ -43,9 +43,9 @@ type IndexItem struct {
|
|||
}
|
||||
|
||||
// Merge is a helper method to construct a new
|
||||
// IndexItem by filling up fields with default values
|
||||
// of a particular IndexItem with values from another one.
|
||||
func (i IndexItem) Merge(i2 IndexItem) (new IndexItem) {
|
||||
// Item by filling up fields with default values
|
||||
// of a particular Item with values from another one.
|
||||
func (i Item) Merge(i2 Item) (new Item) {
|
||||
if i.Address == nil {
|
||||
i.Address = i2.Address
|
||||
}
|
||||
|
|
@ -67,26 +67,26 @@ func (i IndexItem) Merge(i2 IndexItem) (new IndexItem) {
|
|||
// Index represents a set of LevelDB key value pairs that have common
|
||||
// prefix. It holds functions for encoding and decoding keys and values
|
||||
// to provide transparent actions on saved data which inclide:
|
||||
// - getting a particular IndexItem
|
||||
// - saving a particular IndexItem
|
||||
// - getting a particular Item
|
||||
// - saving a particular Item
|
||||
// - iterating over a sorted LevelDB keys
|
||||
// It implements IndexIteratorInterface interface.
|
||||
type Index struct {
|
||||
db *DB
|
||||
prefix []byte
|
||||
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(keyFields IndexItem, value []byte) (e IndexItem, err error)
|
||||
encodeKeyFunc func(fields Item) (key []byte, err error)
|
||||
decodeKeyFunc func(key []byte) (e Item, err error)
|
||||
encodeValueFunc func(fields Item) (value []byte, err error)
|
||||
decodeValueFunc func(keyFields Item, value []byte) (e Item, err error)
|
||||
}
|
||||
|
||||
// IndexFuncs structure defines functions for encoding and decoding
|
||||
// LevelDB keys and values for a specific index.
|
||||
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(keyFields IndexItem, value []byte) (e IndexItem, err error)
|
||||
EncodeKey func(fields Item) (key []byte, err error)
|
||||
DecodeKey func(key []byte) (e Item, err error)
|
||||
EncodeValue func(fields Item) (value []byte, err error)
|
||||
DecodeValue func(keyFields Item, value []byte) (e Item, err error)
|
||||
}
|
||||
|
||||
// NewIndex returns a new Index instance with defined name and
|
||||
|
|
@ -105,7 +105,7 @@ func (db *DB) NewIndex(name string, funcs IndexFuncs) (f Index, err error) {
|
|||
// by appending the provided index id byte.
|
||||
// This is needed to avoid collisions between keys of different
|
||||
// indexes as all index ids are unique.
|
||||
encodeKeyFunc: func(e IndexItem) (key []byte, err error) {
|
||||
encodeKeyFunc: func(e Item) (key []byte, err error) {
|
||||
key, err = funcs.EncodeKey(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -115,7 +115,7 @@ func (db *DB) NewIndex(name string, funcs IndexFuncs) (f Index, err error) {
|
|||
// This function reverses the encodeKeyFunc constructed key
|
||||
// to transparently work with index keys without their index ids.
|
||||
// It assumes that index keys are prefixed with only one byte.
|
||||
decodeKeyFunc: func(key []byte) (e IndexItem, err error) {
|
||||
decodeKeyFunc: func(key []byte) (e Item, err error) {
|
||||
return funcs.DecodeKey(key[1:])
|
||||
},
|
||||
encodeValueFunc: funcs.EncodeValue,
|
||||
|
|
@ -123,10 +123,10 @@ func (db *DB) NewIndex(name string, funcs IndexFuncs) (f Index, err error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Get accepts key fields represented as IndexItem to retrieve a
|
||||
// Get accepts key fields represented as Item to retrieve a
|
||||
// value from the index and return maximum available information
|
||||
// from the index represented as another IndexItem.
|
||||
func (f Index) Get(keyFields IndexItem) (out IndexItem, err error) {
|
||||
// from the index represented as another Item.
|
||||
func (f Index) Get(keyFields Item) (out Item, err error) {
|
||||
key, err := f.encodeKeyFunc(keyFields)
|
||||
if err != nil {
|
||||
return out, err
|
||||
|
|
@ -142,9 +142,9 @@ func (f Index) Get(keyFields IndexItem) (out IndexItem, err error) {
|
|||
return out.Merge(keyFields), nil
|
||||
}
|
||||
|
||||
// Put accepts IndexItem to encode information from it
|
||||
// Put accepts Item to encode information from it
|
||||
// and save it to the database.
|
||||
func (f Index) Put(i IndexItem) (err error) {
|
||||
func (f Index) Put(i Item) (err error) {
|
||||
key, err := f.encodeKeyFunc(i)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -159,7 +159,7 @@ func (f Index) Put(i IndexItem) (err error) {
|
|||
// PutInBatch is the same as Put method, but it just
|
||||
// saves the key/value pair to the batch instead
|
||||
// directly to the database.
|
||||
func (f Index) PutInBatch(batch *leveldb.Batch, i IndexItem) (err error) {
|
||||
func (f Index) PutInBatch(batch *leveldb.Batch, i Item) (err error) {
|
||||
key, err := f.encodeKeyFunc(i)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -172,9 +172,9 @@ func (f Index) PutInBatch(batch *leveldb.Batch, i IndexItem) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Delete accepts IndexItem to remove a key/value pair
|
||||
// Delete accepts Item to remove a key/value pair
|
||||
// from the database based on its fields.
|
||||
func (f Index) Delete(keyFields IndexItem) (err error) {
|
||||
func (f Index) Delete(keyFields Item) (err error) {
|
||||
key, err := f.encodeKeyFunc(keyFields)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -184,7 +184,7 @@ func (f Index) Delete(keyFields IndexItem) (err error) {
|
|||
|
||||
// DeleteInBatch is the same as Delete just the operation
|
||||
// is performed on the batch instead on the database.
|
||||
func (f Index) DeleteInBatch(batch *leveldb.Batch, keyFields IndexItem) (err error) {
|
||||
func (f Index) DeleteInBatch(batch *leveldb.Batch, keyFields Item) (err error) {
|
||||
key, err := f.encodeKeyFunc(keyFields)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -193,12 +193,12 @@ func (f Index) DeleteInBatch(batch *leveldb.Batch, keyFields IndexItem) (err err
|
|||
return nil
|
||||
}
|
||||
|
||||
// IndexIterFunc is a callback on every IndexItem that is decoded
|
||||
// IndexIterFunc is a callback on every Item that is decoded
|
||||
// by iterating on an Index keys.
|
||||
// By returning a true for stop variable, iteration will
|
||||
// stop, and by returning the error, that error will be
|
||||
// propagated to the called iterator method on Index.
|
||||
type IndexIterFunc func(item IndexItem) (stop bool, err error)
|
||||
type IndexIterFunc func(item Item) (stop bool, err error)
|
||||
|
||||
// IterateAll iterates over all keys of the Index.
|
||||
func (f Index) IterateAll(fn IndexIterFunc) (err error) {
|
||||
|
|
@ -230,8 +230,8 @@ func (f Index) IterateAll(fn IndexIterFunc) (err error) {
|
|||
}
|
||||
|
||||
// IterateFrom iterates over Index keys starting from the key
|
||||
// encoded from the provided IndexItem.
|
||||
func (f Index) IterateFrom(start IndexItem, fn IndexIterFunc) (err error) {
|
||||
// encoded from the provided Item.
|
||||
func (f Index) IterateFrom(start Item, fn IndexIterFunc) (err error) {
|
||||
startKey, err := f.encodeKeyFunc(start)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -29,20 +29,20 @@ import (
|
|||
|
||||
// Index functions for the index that is used in tests in this file.
|
||||
var retrievalIndexFuncs = IndexFuncs{
|
||||
EncodeKey: func(fields IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields Item) (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(keyItem IndexItem, value []byte) (e IndexItem, err error) {
|
||||
DecodeValue: func(keyItem Item, value []byte) (e Item, err error) {
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
|
||||
e.Data = value[8:]
|
||||
return e, nil
|
||||
|
|
@ -60,7 +60,7 @@ func TestIndex(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("put", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("put-hash"),
|
||||
Data: []byte("DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -70,16 +70,16 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
|
||||
t.Run("overwrite", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("put-hash"),
|
||||
Data: []byte("New DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -89,18 +89,18 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("put in batch", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("put-in-batch-hash"),
|
||||
Data: []byte("DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -112,16 +112,16 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
|
||||
t.Run("overwrite", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("put-in-batch-hash"),
|
||||
Data: []byte("New DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -133,13 +133,13 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -150,13 +150,13 @@ func TestIndex(t *testing.T) {
|
|||
address := []byte("put-in-batch-twice-hash")
|
||||
|
||||
// put the first item
|
||||
index.PutInBatch(batch, IndexItem{
|
||||
index.PutInBatch(batch, Item{
|
||||
Address: address,
|
||||
Data: []byte("DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
})
|
||||
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: address,
|
||||
Data: []byte("New DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -168,17 +168,17 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
})
|
||||
|
||||
t.Run("delete", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("delete-hash"),
|
||||
Data: []byte("DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -188,15 +188,15 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
|
||||
err = index.Delete(IndexItem{
|
||||
err = index.Delete(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -204,7 +204,7 @@ func TestIndex(t *testing.T) {
|
|||
}
|
||||
|
||||
wantErr := leveldb.ErrNotFound
|
||||
got, err = index.Get(IndexItem{
|
||||
got, err = index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != wantErr {
|
||||
|
|
@ -213,7 +213,7 @@ func TestIndex(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("delete in batch", func(t *testing.T) {
|
||||
want := IndexItem{
|
||||
want := Item{
|
||||
Address: []byte("delete-in-batch-hash"),
|
||||
Data: []byte("DATA"),
|
||||
StoreTimestamp: time.Now().UTC().UnixNano(),
|
||||
|
|
@ -223,16 +223,16 @@ func TestIndex(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := index.Get(IndexItem{
|
||||
got, err := index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkIndexItem(t, got, want)
|
||||
checkItem(t, got, want)
|
||||
|
||||
batch := new(leveldb.Batch)
|
||||
index.DeleteInBatch(batch, IndexItem{
|
||||
index.DeleteInBatch(batch, Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
err = db.WriteBatch(batch)
|
||||
|
|
@ -241,7 +241,7 @@ func TestIndex(t *testing.T) {
|
|||
}
|
||||
|
||||
wantErr := leveldb.ErrNotFound
|
||||
got, err = index.Get(IndexItem{
|
||||
got, err = index.Get(Item{
|
||||
Address: want.Address,
|
||||
})
|
||||
if err != wantErr {
|
||||
|
|
@ -260,7 +260,7 @@ func TestIndex_iterate(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
items := []IndexItem{
|
||||
items := []Item{
|
||||
{
|
||||
Address: []byte("iterate-hash-01"),
|
||||
Data: []byte("data80"),
|
||||
|
|
@ -290,7 +290,7 @@ func TestIndex_iterate(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
item04 := IndexItem{
|
||||
item04 := Item{
|
||||
Address: []byte("iterate-hash-04"),
|
||||
Data: []byte("data0"),
|
||||
}
|
||||
|
|
@ -306,12 +306,12 @@ func TestIndex_iterate(t *testing.T) {
|
|||
|
||||
t.Run("all", func(t *testing.T) {
|
||||
var i int
|
||||
err := index.IterateAll(func(item IndexItem) (stop bool, err error) {
|
||||
err := index.IterateAll(func(item Item) (stop bool, err error) {
|
||||
if i > len(items)-1 {
|
||||
return true, fmt.Errorf("got unexpected index item: %#v", item)
|
||||
}
|
||||
want := items[i]
|
||||
checkIndexItem(t, item, want)
|
||||
checkItem(t, item, want)
|
||||
i++
|
||||
return false, nil
|
||||
})
|
||||
|
|
@ -323,12 +323,12 @@ func TestIndex_iterate(t *testing.T) {
|
|||
t.Run("from", func(t *testing.T) {
|
||||
startIndex := 2
|
||||
i := startIndex
|
||||
err := index.IterateFrom(items[startIndex], func(item IndexItem) (stop bool, err error) {
|
||||
err := index.IterateFrom(items[startIndex], func(item Item) (stop bool, err error) {
|
||||
if i > len(items)-1 {
|
||||
return true, fmt.Errorf("got unexpected index item: %#v", item)
|
||||
}
|
||||
want := items[i]
|
||||
checkIndexItem(t, item, want)
|
||||
checkItem(t, item, want)
|
||||
i++
|
||||
return false, nil
|
||||
})
|
||||
|
|
@ -341,12 +341,12 @@ func TestIndex_iterate(t *testing.T) {
|
|||
var i int
|
||||
stopIndex := 3
|
||||
var count int
|
||||
err := index.IterateAll(func(item IndexItem) (stop bool, err error) {
|
||||
err := index.IterateAll(func(item Item) (stop bool, err error) {
|
||||
if i > len(items)-1 {
|
||||
return true, fmt.Errorf("got unexpected index item: %#v", item)
|
||||
}
|
||||
want := items[i]
|
||||
checkIndexItem(t, item, want)
|
||||
checkItem(t, item, want)
|
||||
count++
|
||||
if i == stopIndex {
|
||||
return true, nil
|
||||
|
|
@ -369,22 +369,22 @@ func TestIndex_iterate(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
secondIndexItem := IndexItem{
|
||||
secondItem := Item{
|
||||
Address: []byte("iterate-hash-10"),
|
||||
Data: []byte("data-second"),
|
||||
}
|
||||
err = secondIndex.Put(secondIndexItem)
|
||||
err = secondIndex.Put(secondItem)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var i int
|
||||
err = index.IterateAll(func(item IndexItem) (stop bool, err error) {
|
||||
err = index.IterateAll(func(item Item) (stop bool, err error) {
|
||||
if i > len(items)-1 {
|
||||
return true, fmt.Errorf("got unexpected index item: %#v", item)
|
||||
}
|
||||
want := items[i]
|
||||
checkIndexItem(t, item, want)
|
||||
checkItem(t, item, want)
|
||||
i++
|
||||
return false, nil
|
||||
})
|
||||
|
|
@ -393,11 +393,11 @@ func TestIndex_iterate(t *testing.T) {
|
|||
}
|
||||
|
||||
i = 0
|
||||
err = secondIndex.IterateAll(func(item IndexItem) (stop bool, err error) {
|
||||
err = secondIndex.IterateAll(func(item Item) (stop bool, err error) {
|
||||
if i > 1 {
|
||||
return true, fmt.Errorf("got unexpected index item: %#v", item)
|
||||
}
|
||||
checkIndexItem(t, item, secondIndexItem)
|
||||
checkItem(t, item, secondItem)
|
||||
i++
|
||||
return false, nil
|
||||
})
|
||||
|
|
@ -418,7 +418,7 @@ func TestIndex_Count(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
items := []IndexItem{
|
||||
items := []Item{
|
||||
{
|
||||
Address: []byte("iterate-hash-01"),
|
||||
Data: []byte("data80"),
|
||||
|
|
@ -461,7 +461,7 @@ func TestIndex_Count(t *testing.T) {
|
|||
|
||||
// update the index with another item
|
||||
|
||||
item04 := IndexItem{
|
||||
item04 := Item{
|
||||
Address: []byte("iterate-hash-04"),
|
||||
Data: []byte("data0"),
|
||||
}
|
||||
|
|
@ -502,8 +502,8 @@ func TestIndex_Count(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// checkIndexItem is a test helper function that compares if two Index items are the same.
|
||||
func checkIndexItem(t *testing.T, got, want IndexItem) {
|
||||
// checkItem is a test helper function that compares if two Index items are the same.
|
||||
func checkItem(t *testing.T, got, want Item) {
|
||||
t.Helper()
|
||||
|
||||
if !bytes.Equal(got.Address, want.Address) {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func (db *DB) collectGarbage() {
|
|||
// sets a gc trigger if batch limit is reached
|
||||
var triggerNextIteration bool
|
||||
var collectedCount int64
|
||||
err := db.gcIndex.IterateAll(func(item shed.IndexItem) (stop bool, err error) {
|
||||
err := db.gcIndex.IterateAll(func(item shed.Item) (stop bool, err error) {
|
||||
gcSize := atomic.LoadInt64(&db.gcSize)
|
||||
if gcSize-collectedCount <= target {
|
||||
return true, nil
|
||||
|
|
|
|||
|
|
@ -137,9 +137,9 @@ func testDB_collectGarbage(t *testing.T, db *DB) {
|
|||
t.Errorf("total collected chunks %v, want %v", totalCollectedCount, wantTotalCollectedCount)
|
||||
}
|
||||
|
||||
t.Run("pull index count", newIndexItemsCountTest(db.pullIndex, int(gcTarget)))
|
||||
t.Run("pull index count", newItemsCountTest(db.pullIndex, int(gcTarget)))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, int(gcTarget)))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, int(gcTarget)))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
|
||||
|
|
@ -259,9 +259,9 @@ func testDB_collectGarbage_withRequests(t *testing.T, db *DB) {
|
|||
t.Errorf("total collected chunks %v, want %v", totalCollectedCount, wantTotalCollectedCount)
|
||||
}
|
||||
|
||||
t.Run("pull index count", newIndexItemsCountTest(db.pullIndex, int(gcTarget)))
|
||||
t.Run("pull index count", newItemsCountTest(db.pullIndex, int(gcTarget)))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, int(gcTarget)))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, int(gcTarget)))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import (
|
|||
|
||||
// TestDB_pullIndex validates the ordering of keys in pull index.
|
||||
// Pull index key contains PO prefix which is calculated from
|
||||
// DB base key and chunk address. This is not an IndexItem field
|
||||
// DB base key and chunk address. This is not an Item field
|
||||
// which are checked in Mode tests.
|
||||
// This test uploads chunks, sorts them in expected order and
|
||||
// validates that pull index iterator will iterate it the same
|
||||
|
|
@ -61,7 +61,7 @@ func TestDB_pullIndex(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
testIndexItemsOrder(t, db.pullIndex, chunks, func(i, j int) (less bool) {
|
||||
testItemsOrder(t, db.pullIndex, chunks, func(i, j int) (less bool) {
|
||||
poi := storage.Proximity(db.baseKey, chunks[i].Address())
|
||||
poj := storage.Proximity(db.baseKey, chunks[j].Address())
|
||||
if poi < poj {
|
||||
|
|
@ -119,10 +119,10 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
}
|
||||
|
||||
// check if all chunks are stored
|
||||
newIndexItemsCountTest(db.pullIndex, chunkCount)(t)
|
||||
newItemsCountTest(db.pullIndex, chunkCount)(t)
|
||||
|
||||
// check that chunks are not collectable for garbage
|
||||
newIndexItemsCountTest(db.gcIndex, 0)(t)
|
||||
newItemsCountTest(db.gcIndex, 0)(t)
|
||||
|
||||
// set update gc test hook to signal when
|
||||
// update gc goroutine is done by sending to
|
||||
|
|
@ -145,7 +145,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
|
||||
// the chunk is not synced
|
||||
// should not be in the garbace collection index
|
||||
newIndexItemsCountTest(db.gcIndex, 0)(t)
|
||||
newItemsCountTest(db.gcIndex, 0)(t)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
@ -159,7 +159,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
}
|
||||
|
||||
// the chunk is synced and should be in gc index
|
||||
newIndexItemsCountTest(db.gcIndex, 1)(t)
|
||||
newItemsCountTest(db.gcIndex, 1)(t)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
@ -174,7 +174,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
}
|
||||
}
|
||||
|
||||
testIndexItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
testItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
@ -194,7 +194,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
chunks = append(chunks[:i], chunks[i+1:]...)
|
||||
chunks = append(chunks, c)
|
||||
|
||||
testIndexItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
testItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
@ -215,7 +215,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
<-testHookUpdateGCChan
|
||||
}
|
||||
|
||||
testIndexItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
testItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
@ -231,7 +231,7 @@ func testDB_gcIndex(t *testing.T, db *DB) {
|
|||
// remove the chunk from the expected chunks in gc index
|
||||
chunks = append(chunks[:i], chunks[i+1:]...)
|
||||
|
||||
testIndexItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
testItemsOrder(t, db.gcIndex, chunks, nil)
|
||||
|
||||
newIndexGCSizeTest(db)(t)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -151,11 +151,11 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
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)
|
||||
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.IndexItem) (value []byte, err error) {
|
||||
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))
|
||||
|
|
@ -165,21 +165,21 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
return b, nil
|
||||
}
|
||||
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
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(keyIndexItem.Address)
|
||||
e.Data, err = o.MockStore.Get(keyItem.Address)
|
||||
return e, err
|
||||
}
|
||||
} else {
|
||||
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
|
||||
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(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
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:]
|
||||
|
|
@ -188,10 +188,10 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
// 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) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
|
|
@ -203,11 +203,11 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
} else {
|
||||
var (
|
||||
encodeValueFunc func(fields shed.IndexItem) (value []byte, err error)
|
||||
decodeValueFunc func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error)
|
||||
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.IndexItem) (value []byte, err error) {
|
||||
encodeValueFunc = func(fields shed.Item) (value []byte, err error) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp))
|
||||
err = o.MockStore.Put(fields.Address, fields.Data)
|
||||
|
|
@ -216,19 +216,19 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
return b, nil
|
||||
}
|
||||
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
decodeValueFunc = func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
|
||||
e.Data, err = o.MockStore.Get(keyIndexItem.Address)
|
||||
e.Data, err = o.MockStore.Get(keyItem.Address)
|
||||
return e, err
|
||||
}
|
||||
} else {
|
||||
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
|
||||
encodeValueFunc = func(fields shed.Item) (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) {
|
||||
decodeValueFunc = func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
|
||||
e.Data = value[8:]
|
||||
return e, nil
|
||||
|
|
@ -236,10 +236,10 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
// 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) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
|
|
@ -252,19 +252,19 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
// Index storing access timestamp for a particular address.
|
||||
// It is needed in order to update gc index keys for iteration order.
|
||||
db.retrievalAccessIndex, err = db.shed.NewIndex("Address->AccessTimestamp", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
return fields.Address, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp))
|
||||
return b, nil
|
||||
},
|
||||
DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value))
|
||||
return e, nil
|
||||
},
|
||||
|
|
@ -275,22 +275,22 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
// pull index allows history and live syncing per po bin
|
||||
db.pullIndex, err = db.shed.NewIndex("PO|StoredTimestamp|Hash->nil", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
key = make([]byte, 41)
|
||||
key[0] = db.po(fields.Address)
|
||||
binary.BigEndian.PutUint64(key[1:9], uint64(fields.StoreTimestamp))
|
||||
copy(key[9:], fields.Address[:])
|
||||
return key, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key[9:]
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(key[1:9]))
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
return nil, nil
|
||||
},
|
||||
DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
return e, nil
|
||||
},
|
||||
})
|
||||
|
|
@ -299,21 +299,21 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
// push index contains as yet unsynced chunks
|
||||
db.pushIndex, err = db.shed.NewIndex("StoredTimestamp|Hash->nil", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
key = make([]byte, 40)
|
||||
binary.BigEndian.PutUint64(key[:8], uint64(fields.StoreTimestamp))
|
||||
copy(key[8:], fields.Address[:])
|
||||
return key, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.Address = key[8:]
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(key[:8]))
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
return nil, nil
|
||||
},
|
||||
DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
return e, nil
|
||||
},
|
||||
})
|
||||
|
|
@ -322,23 +322,23 @@ func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
|
|||
}
|
||||
// gc index for removable chunk ordered by ascending last access time
|
||||
db.gcIndex, err = db.shed.NewIndex("AccessTimestamp|StoredTimestamp|Hash->nil", shed.IndexFuncs{
|
||||
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
|
||||
EncodeKey: func(fields shed.Item) (key []byte, err error) {
|
||||
b := make([]byte, 16, 16+len(fields.Address))
|
||||
binary.BigEndian.PutUint64(b[:8], uint64(fields.AccessTimestamp))
|
||||
binary.BigEndian.PutUint64(b[8:16], uint64(fields.StoreTimestamp))
|
||||
key = append(b, fields.Address...)
|
||||
return key, nil
|
||||
},
|
||||
DecodeKey: func(key []byte) (e shed.IndexItem, err error) {
|
||||
DecodeKey: func(key []byte) (e shed.Item, err error) {
|
||||
e.AccessTimestamp = int64(binary.BigEndian.Uint64(key[:8]))
|
||||
e.StoreTimestamp = int64(binary.BigEndian.Uint64(key[8:16]))
|
||||
e.Address = key[16:]
|
||||
return e, nil
|
||||
},
|
||||
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
|
||||
EncodeValue: func(fields shed.Item) (value []byte, err error) {
|
||||
return nil, nil
|
||||
},
|
||||
DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
|
||||
DecodeValue: func(keyItem shed.Item, value []byte) (e shed.Item, err error) {
|
||||
return e, nil
|
||||
},
|
||||
})
|
||||
|
|
@ -397,17 +397,17 @@ func (db *DB) lockAddr(addr storage.Address) (unlock func(), err error) {
|
|||
return func() { db.addressLocks.Delete(lockKey) }, nil
|
||||
}
|
||||
|
||||
// chunkToItem creates new IndexItem with data provided by the Chunk.
|
||||
func chunkToItem(ch storage.Chunk) shed.IndexItem {
|
||||
return shed.IndexItem{
|
||||
// chunkToItem creates new Item with data provided by the Chunk.
|
||||
func chunkToItem(ch storage.Chunk) shed.Item {
|
||||
return shed.Item{
|
||||
Address: ch.Address(),
|
||||
Data: ch.Data(),
|
||||
}
|
||||
}
|
||||
|
||||
// addressToItem creates new IndexItem with a provided address.
|
||||
func addressToItem(addr storage.Address) shed.IndexItem {
|
||||
return shed.IndexItem{
|
||||
// addressToItem creates new Item with a provided address.
|
||||
func addressToItem(addr storage.Address) shed.Item {
|
||||
return shed.Item{
|
||||
Address: addr,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ func newRetrieveIndexesTestWithAccess(db *DB, chunk storage.Chunk, storeTimestam
|
|||
// chunk values are in the pull index.
|
||||
func newPullIndexTest(db *DB, chunk storage.Chunk, storeTimestamp int64, wantError error) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
item, err := db.pullIndex.Get(shed.IndexItem{
|
||||
item, err := db.pullIndex.Get(shed.Item{
|
||||
Address: chunk.Address(),
|
||||
StoreTimestamp: storeTimestamp,
|
||||
})
|
||||
|
|
@ -393,7 +393,7 @@ func newPullIndexTest(db *DB, chunk storage.Chunk, storeTimestamp int64, wantErr
|
|||
// chunk values are in the push index.
|
||||
func newPushIndexTest(db *DB, chunk storage.Chunk, storeTimestamp int64, wantError error) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
item, err := db.pushIndex.Get(shed.IndexItem{
|
||||
item, err := db.pushIndex.Get(shed.Item{
|
||||
Address: chunk.Address(),
|
||||
StoreTimestamp: storeTimestamp,
|
||||
})
|
||||
|
|
@ -410,7 +410,7 @@ func newPushIndexTest(db *DB, chunk storage.Chunk, storeTimestamp int64, wantErr
|
|||
// chunk values are in the push index.
|
||||
func newGCIndexTest(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp int64) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
item, err := db.gcIndex.Get(shed.IndexItem{
|
||||
item, err := db.gcIndex.Get(shed.Item{
|
||||
Address: chunk.Address(),
|
||||
StoreTimestamp: storeTimestamp,
|
||||
AccessTimestamp: accessTimestamp,
|
||||
|
|
@ -422,12 +422,12 @@ func newGCIndexTest(db *DB, chunk storage.Chunk, storeTimestamp, accessTimestamp
|
|||
}
|
||||
}
|
||||
|
||||
// newIndexItemsCountTest returns a test function that validates if
|
||||
// newItemsCountTest returns a test function that validates if
|
||||
// an index contains expected number of key/value pairs.
|
||||
func newIndexItemsCountTest(i shed.Index, want int) func(t *testing.T) {
|
||||
func newItemsCountTest(i shed.Index, want int) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
var c int
|
||||
i.IterateAll(func(item shed.IndexItem) (stop bool, err error) {
|
||||
i.IterateAll(func(item shed.Item) (stop bool, err error) {
|
||||
c++
|
||||
return
|
||||
})
|
||||
|
|
@ -442,7 +442,7 @@ func newIndexItemsCountTest(i shed.Index, want int) func(t *testing.T) {
|
|||
func newIndexGCSizeTest(db *DB) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
var want int64
|
||||
db.gcIndex.IterateAll(func(item shed.IndexItem) (stop bool, err error) {
|
||||
db.gcIndex.IterateAll(func(item shed.Item) (stop bool, err error) {
|
||||
want++
|
||||
return
|
||||
})
|
||||
|
|
@ -460,17 +460,17 @@ type testIndexChunk struct {
|
|||
storeTimestamp int64
|
||||
}
|
||||
|
||||
// testIndexItemsOrder tests the order of chunks in the index. If sortFunc is not nil,
|
||||
// testItemsOrder tests the order of chunks in the index. If sortFunc is not nil,
|
||||
// chunks will be sorted with it before validation.
|
||||
func testIndexItemsOrder(t *testing.T, i shed.Index, chunks []testIndexChunk, sortFunc func(i, j int) (less bool)) {
|
||||
newIndexItemsCountTest(i, len(chunks))(t)
|
||||
func testItemsOrder(t *testing.T, i shed.Index, chunks []testIndexChunk, sortFunc func(i, j int) (less bool)) {
|
||||
newItemsCountTest(i, len(chunks))(t)
|
||||
|
||||
if sortFunc != nil {
|
||||
sort.Slice(chunks, sortFunc)
|
||||
}
|
||||
|
||||
var cursor int
|
||||
err := i.IterateAll(func(item shed.IndexItem) (stop bool, err error) {
|
||||
err := i.IterateAll(func(item shed.Item) (stop bool, err error) {
|
||||
want := chunks[cursor].Address()
|
||||
got := item.Address
|
||||
if !bytes.Equal(got, want) {
|
||||
|
|
@ -484,8 +484,8 @@ func testIndexItemsOrder(t *testing.T, i shed.Index, chunks []testIndexChunk, so
|
|||
}
|
||||
}
|
||||
|
||||
// validateItem is a helper function that checks IndexItem values.
|
||||
func validateItem(t *testing.T, item shed.IndexItem, address, data []byte, storeTimestamp, accessTimestamp int64) {
|
||||
// validateItem is a helper function that checks Item values.
|
||||
func validateItem(t *testing.T, item shed.Item, address, data []byte, storeTimestamp, accessTimestamp int64) {
|
||||
t.Helper()
|
||||
|
||||
if !bytes.Equal(item.Address, address) {
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ func (g *Getter) Get(addr storage.Address) (chunk storage.Chunk, err error) {
|
|||
return storage.NewChunk(out.Address, out.Data), nil
|
||||
}
|
||||
|
||||
// get returns IndexItem with from the retrieval index
|
||||
// get returns Item with from the retrieval index
|
||||
// and updates other indexes.
|
||||
func (db *DB) get(mode ModeGet, addr storage.Address) (out shed.IndexItem, err error) {
|
||||
func (db *DB) get(mode ModeGet, addr storage.Address) (out shed.Item, err error) {
|
||||
item := addressToItem(addr)
|
||||
|
||||
if db.useRetrievalCompositeIndex {
|
||||
|
|
@ -120,7 +120,7 @@ func (db *DB) get(mode ModeGet, addr storage.Address) (out shed.IndexItem, err e
|
|||
// a single item. Provided item is expected to have
|
||||
// only Address and Data fields with non zero values,
|
||||
// which is ensured by the get function.
|
||||
func (db *DB) updateGC(item shed.IndexItem) (err error) {
|
||||
func (db *DB) updateGC(item shed.Item) (err error) {
|
||||
unlock, err := db.lockAddr(item.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ func testModeGetRequestValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("retrieve indexes", newRetrieveIndexesTestWithAccess(db, chunk, uploadTimestamp, 0))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 0))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 0))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
})
|
||||
|
|
@ -116,7 +116,7 @@ func testModeGetRequestValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("gc index", newGCIndexTest(db, chunk, uploadTimestamp, uploadTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
})
|
||||
|
|
@ -146,7 +146,7 @@ func testModeGetRequestValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("gc index", newGCIndexTest(db, chunk, uploadTimestamp, accessTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
})
|
||||
|
|
@ -200,7 +200,7 @@ func testModeGetSyncValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("retrieve indexes", newRetrieveIndexesTestWithAccess(db, chunk, uploadTimestamp, 0))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 0))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 0))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@ func (p *Putter) Put(ch storage.Chunk) (err error) {
|
|||
return p.db.put(p.mode, chunkToItem(ch))
|
||||
}
|
||||
|
||||
// put stores IndexItem to database and updates other
|
||||
// put stores Item to database and updates other
|
||||
// indexes. It acquires lockAddr to protect two calls
|
||||
// of this function for the same address in parallel.
|
||||
// IndexItem fields Address and Data must not be
|
||||
// Item fields Address and Data must not be
|
||||
// with their nil values.
|
||||
func (db *DB) put(mode ModePut, item shed.IndexItem) (err error) {
|
||||
func (db *DB) put(mode ModePut, item shed.Item) (err error) {
|
||||
// protect parallel updates
|
||||
unlock, err := db.lockAddr(item.Address)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ func testModePutRequestValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("retrieve indexes", newRetrieveIndexesTestWithAccess(db, chunk, wantTimestamp, wantTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
})
|
||||
|
|
@ -82,7 +82,7 @@ func testModePutRequestValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("retrieve indexes", newRetrieveIndexesTestWithAccess(db, chunk, storeTimestamp, wantTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -58,11 +58,11 @@ func testModeSetAccessValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("pull index", newPullIndexTest(db, chunk, wantTimestamp, nil))
|
||||
|
||||
t.Run("pull index count", newIndexItemsCountTest(db.pullIndex, 1))
|
||||
t.Run("pull index count", newItemsCountTest(db.pullIndex, 1))
|
||||
|
||||
t.Run("gc index", newGCIndexTest(db, chunk, wantTimestamp, wantTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ func testModeSetSyncValues(t *testing.T, db *DB) {
|
|||
|
||||
t.Run("gc index", newGCIndexTest(db, chunk, wantTimestamp, wantTimestamp))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 1))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 1))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
}
|
||||
|
|
@ -156,28 +156,28 @@ func testModeSetRemovalValues(t *testing.T, db *DB) {
|
|||
if err != wantErr {
|
||||
t.Errorf("got error %v, want %v", err, wantErr)
|
||||
}
|
||||
t.Run("retrieve index count", newIndexItemsCountTest(db.retrievalCompositeIndex, 0))
|
||||
t.Run("retrieve index count", newItemsCountTest(db.retrievalCompositeIndex, 0))
|
||||
} else {
|
||||
_, err := db.retrievalDataIndex.Get(addressToItem(chunk.Address()))
|
||||
if err != wantErr {
|
||||
t.Errorf("got error %v, want %v", err, wantErr)
|
||||
}
|
||||
t.Run("retrieve data index count", newIndexItemsCountTest(db.retrievalDataIndex, 0))
|
||||
t.Run("retrieve data index count", newItemsCountTest(db.retrievalDataIndex, 0))
|
||||
|
||||
// access index should not be set
|
||||
_, err = db.retrievalAccessIndex.Get(addressToItem(chunk.Address()))
|
||||
if err != wantErr {
|
||||
t.Errorf("got error %v, want %v", err, wantErr)
|
||||
}
|
||||
t.Run("retrieve access index count", newIndexItemsCountTest(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 count", newIndexItemsCountTest(db.pullIndex, 0))
|
||||
t.Run("pull index count", newItemsCountTest(db.pullIndex, 0))
|
||||
|
||||
t.Run("gc index count", newIndexItemsCountTest(db.gcIndex, 0))
|
||||
t.Run("gc index count", newItemsCountTest(db.gcIndex, 0))
|
||||
|
||||
t.Run("gc size", newIndexGCSizeTest(db))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue