mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-06 06:06:49 +00:00
[NOD-885] Use database.Key and database.Bucket instead of byte slices (#692)
* [NOD-885] Create database.Key type * [NOD-885] Rename FullKey()->FullKeyBytes() and Key()->KeyBytes() * [NOD-885] Make Key.String return a hex string * [NOD-885] Rename key parts * [NOD-885] Rename separator->bucketSeparator * [NOD-885] Rename SuffixBytes->Suffix and PrefixBytes->Prefix * [NOD-885] Change comments * [NOD-885] Change key prefix to bucket * [NOD-885] Don't use database.NewKey inside dbaccess * [NOD-885] Fix nil bug in Bucket.Path() * [NOD-885] Rename helpers.go -> keys.go * [NOD-885] Unexport database.NewKey * [NOD-885] Remove redundant code in Bucket.Path()
This commit is contained in:
parent
df934990d7
commit
7609c50641
@ -324,7 +324,7 @@ func (dag *BlockDAG) initUTXOSet() (fullUTXOCollection utxoCollection, err error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outpoint, err := deserializeOutpoint(bytes.NewReader(key))
|
||||
outpoint, err := deserializeOutpoint(bytes.NewReader(key.Suffix()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -639,7 +639,7 @@ func (dag *BlockDAG) BlockHashesFrom(lowHash *daghash.Hash, limit int) ([]*dagha
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockHash, err := blockHashFromBlockIndexKey(key)
|
||||
blockHash, err := blockHashFromBlockIndexKey(key.Suffix())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func (store *multisetStore) init(dbContext dbaccess.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := daghash.NewHash(key)
|
||||
hash, err := daghash.NewHash(key.Suffix())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ func (store *reachabilityStore) initReachabilityData(cursor database.Cursor) err
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := daghash.NewHash(key)
|
||||
hash, err := daghash.NewHash(key.Suffix())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -155,7 +155,7 @@ func (store *reachabilityStore) loadReachabilityDataFromCursor(cursor database.C
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := daghash.NewHash(key)
|
||||
hash, err := daghash.NewHash(key.Suffix())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
package database
|
||||
|
||||
import "bytes"
|
||||
|
||||
var separator = []byte("/")
|
||||
|
||||
// Bucket is a helper type meant to combine buckets,
|
||||
// sub-buckets, and keys into a single full key-value
|
||||
// database key.
|
||||
type Bucket struct {
|
||||
path [][]byte
|
||||
}
|
||||
|
||||
// MakeBucket creates a new Bucket using the given path
|
||||
// of buckets.
|
||||
func MakeBucket(path ...[]byte) *Bucket {
|
||||
return &Bucket{path: path}
|
||||
}
|
||||
|
||||
// Bucket returns the sub-bucket of the current bucket
|
||||
// defined by bucketBytes.
|
||||
func (b *Bucket) Bucket(bucketBytes []byte) *Bucket {
|
||||
newPath := make([][]byte, len(b.path)+1)
|
||||
copy(newPath, b.path)
|
||||
copy(newPath[len(b.path):], [][]byte{bucketBytes})
|
||||
|
||||
return MakeBucket(newPath...)
|
||||
}
|
||||
|
||||
// Key returns the key inside of the current bucket.
|
||||
func (b *Bucket) Key(key []byte) []byte {
|
||||
bucketPath := b.Path()
|
||||
|
||||
fullKeyLength := len(bucketPath) + len(key)
|
||||
fullKey := make([]byte, fullKeyLength)
|
||||
copy(fullKey, bucketPath)
|
||||
copy(fullKey[len(bucketPath):], key)
|
||||
|
||||
return fullKey
|
||||
}
|
||||
|
||||
// Path returns the full path of the current bucket.
|
||||
func (b *Bucket) Path() []byte {
|
||||
bucketPath := bytes.Join(b.path, separator)
|
||||
|
||||
bucketPathWithFinalSeparator := make([]byte, len(bucketPath)+len(separator))
|
||||
copy(bucketPathWithFinalSeparator, bucketPath)
|
||||
copy(bucketPathWithFinalSeparator[len(bucketPath):], separator)
|
||||
|
||||
return bucketPathWithFinalSeparator
|
||||
}
|
@ -13,13 +13,13 @@ type Cursor interface {
|
||||
// Seek moves the iterator to the first key/value pair whose key is greater
|
||||
// than or equal to the given key. It returns ErrNotFound if such pair does not
|
||||
// exist.
|
||||
Seek(key []byte) error
|
||||
Seek(key *Key) error
|
||||
|
||||
// Key returns the key of the current key/value pair, or ErrNotFound if done.
|
||||
// Note that the key is trimmed to not include the prefix the cursor was opened
|
||||
// with. The caller should not modify the contents of the returned slice, and
|
||||
// its contents may change on the next call to Next.
|
||||
Key() ([]byte, error)
|
||||
Key() (*Key, error)
|
||||
|
||||
// Value returns the value of the current key/value pair, or ErrNotFound if done.
|
||||
// The caller should not modify the contents of the returned slice, and its
|
||||
|
@ -5,19 +5,19 @@ package database
|
||||
type DataAccessor interface {
|
||||
// Put sets the value for the given key. It overwrites
|
||||
// any previous value for that key.
|
||||
Put(key []byte, value []byte) error
|
||||
Put(key *Key, value []byte) error
|
||||
|
||||
// Get gets the value for the given key. It returns
|
||||
// ErrNotFound if the given key does not exist.
|
||||
Get(key []byte) ([]byte, error)
|
||||
Get(key *Key) ([]byte, error)
|
||||
|
||||
// Has returns true if the database does contains the
|
||||
// given key.
|
||||
Has(key []byte) (bool, error)
|
||||
Has(key *Key) (bool, error)
|
||||
|
||||
// Delete deletes the value for the given key. Will not
|
||||
// return an error if the key doesn't exist.
|
||||
Delete(key []byte) error
|
||||
Delete(key *Key) error
|
||||
|
||||
// AppendToStore appends the given data to the store
|
||||
// defined by storeName. This function returns a serialized
|
||||
@ -32,5 +32,5 @@ type DataAccessor interface {
|
||||
RetrieveFromStore(storeName string, location []byte) ([]byte, error)
|
||||
|
||||
// Cursor begins a new cursor over the given bucket.
|
||||
Cursor(bucket []byte) (Cursor, error)
|
||||
Cursor(bucket *Bucket) (Cursor, error)
|
||||
}
|
||||
|
@ -59,28 +59,28 @@ func (db *ffldb) Close() error {
|
||||
// Put sets the value for the given key. It overwrites
|
||||
// any previous value for that key.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (db *ffldb) Put(key []byte, value []byte) error {
|
||||
func (db *ffldb) Put(key *database.Key, value []byte) error {
|
||||
return db.levelDB.Put(key, value)
|
||||
}
|
||||
|
||||
// Get gets the value for the given key. It returns
|
||||
// ErrNotFound if the given key does not exist.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (db *ffldb) Get(key []byte) ([]byte, error) {
|
||||
func (db *ffldb) Get(key *database.Key) ([]byte, error) {
|
||||
return db.levelDB.Get(key)
|
||||
}
|
||||
|
||||
// Has returns true if the database does contains the
|
||||
// given key.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (db *ffldb) Has(key []byte) (bool, error) {
|
||||
func (db *ffldb) Has(key *database.Key) (bool, error) {
|
||||
return db.levelDB.Has(key)
|
||||
}
|
||||
|
||||
// Delete deletes the value for the given key. Will not
|
||||
// return an error if the key doesn't exist.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (db *ffldb) Delete(key []byte) error {
|
||||
func (db *ffldb) Delete(key *database.Key) error {
|
||||
return db.levelDB.Delete(key)
|
||||
}
|
||||
|
||||
@ -155,8 +155,8 @@ func (db *ffldb) RetrieveFromStore(storeName string, location []byte) ([]byte, e
|
||||
|
||||
// Cursor begins a new cursor over the given bucket.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (db *ffldb) Cursor(bucket []byte) (database.Cursor, error) {
|
||||
ldbCursor := db.levelDB.Cursor(bucket)
|
||||
func (db *ffldb) Cursor(bucket *database.Bucket) (database.Cursor, error) {
|
||||
ldbCursor := db.levelDB.Cursor(bucket.Path())
|
||||
|
||||
return ldbCursor, nil
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func (db *ffldb) flatFiles() (map[string][]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storeName := string(storeNameKey)
|
||||
storeName := string(storeNameKey.Suffix())
|
||||
|
||||
currentLocation, err := flatFilesCursor.Value()
|
||||
if err != nil {
|
||||
|
@ -2,7 +2,6 @@ package ldb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"github.com/kaspanet/kaspad/database"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb/iterator"
|
||||
@ -48,14 +47,14 @@ func (c *LevelDBCursor) First() bool {
|
||||
// Seek moves the iterator to the first key/value pair whose key is greater
|
||||
// than or equal to the given key. It returns ErrNotFound if such pair does not
|
||||
// exist.
|
||||
func (c *LevelDBCursor) Seek(key []byte) error {
|
||||
func (c *LevelDBCursor) Seek(key *database.Key) error {
|
||||
if c.isClosed {
|
||||
return errors.New("cannot seek a closed cursor")
|
||||
}
|
||||
|
||||
notFoundErr := errors.Wrapf(database.ErrNotFound, "key %s not "+
|
||||
"found", hex.EncodeToString(key))
|
||||
found := c.ldbIterator.Seek(key)
|
||||
"found", key)
|
||||
found := c.ldbIterator.Seek(key.Bytes())
|
||||
if !found {
|
||||
return notFoundErr
|
||||
}
|
||||
@ -65,7 +64,7 @@ func (c *LevelDBCursor) Seek(key []byte) error {
|
||||
if currentKey == nil {
|
||||
return notFoundErr
|
||||
}
|
||||
if !bytes.Equal(currentKey, key) {
|
||||
if !bytes.Equal(currentKey, key.Bytes()) {
|
||||
return notFoundErr
|
||||
}
|
||||
|
||||
@ -76,7 +75,7 @@ func (c *LevelDBCursor) Seek(key []byte) error {
|
||||
// Note that the key is trimmed to not include the prefix the cursor was opened
|
||||
// with. The caller should not modify the contents of the returned slice, and
|
||||
// its contents may change on the next call to Next.
|
||||
func (c *LevelDBCursor) Key() ([]byte, error) {
|
||||
func (c *LevelDBCursor) Key() (*database.Key, error) {
|
||||
if c.isClosed {
|
||||
return nil, errors.New("cannot get the key of a closed cursor")
|
||||
}
|
||||
@ -85,8 +84,8 @@ func (c *LevelDBCursor) Key() ([]byte, error) {
|
||||
return nil, errors.Wrapf(database.ErrNotFound, "cannot get the "+
|
||||
"key of a done cursor")
|
||||
}
|
||||
key := bytes.TrimPrefix(fullKeyPath, c.prefix)
|
||||
return key, nil
|
||||
suffix := bytes.TrimPrefix(fullKeyPath, c.prefix)
|
||||
return database.MakeBucket(c.prefix).Key(suffix), nil
|
||||
}
|
||||
|
||||
// Value returns the value of the current key/value pair, or ErrNotFound if done.
|
||||
|
@ -1,7 +1,6 @@
|
||||
package ldb
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"github.com/kaspanet/kaspad/database"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
@ -52,19 +51,19 @@ func (db *LevelDB) Close() error {
|
||||
|
||||
// Put sets the value for the given key. It overwrites
|
||||
// any previous value for that key.
|
||||
func (db *LevelDB) Put(key []byte, value []byte) error {
|
||||
err := db.ldb.Put(key, value, nil)
|
||||
func (db *LevelDB) Put(key *database.Key, value []byte) error {
|
||||
err := db.ldb.Put(key.Bytes(), value, nil)
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// Get gets the value for the given key. It returns
|
||||
// ErrNotFound if the given key does not exist.
|
||||
func (db *LevelDB) Get(key []byte) ([]byte, error) {
|
||||
data, err := db.ldb.Get(key, nil)
|
||||
func (db *LevelDB) Get(key *database.Key) ([]byte, error) {
|
||||
data, err := db.ldb.Get(key.Bytes(), nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, leveldb.ErrNotFound) {
|
||||
return nil, errors.Wrapf(database.ErrNotFound,
|
||||
"key %s not found", hex.EncodeToString(key))
|
||||
"key %s not found", key)
|
||||
}
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
@ -73,8 +72,8 @@ func (db *LevelDB) Get(key []byte) ([]byte, error) {
|
||||
|
||||
// Has returns true if the database does contains the
|
||||
// given key.
|
||||
func (db *LevelDB) Has(key []byte) (bool, error) {
|
||||
exists, err := db.ldb.Has(key, nil)
|
||||
func (db *LevelDB) Has(key *database.Key) (bool, error) {
|
||||
exists, err := db.ldb.Has(key.Bytes(), nil)
|
||||
if err != nil {
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
@ -83,7 +82,7 @@ func (db *LevelDB) Has(key []byte) (bool, error) {
|
||||
|
||||
// Delete deletes the value for the given key. Will not
|
||||
// return an error if the key doesn't exist.
|
||||
func (db *LevelDB) Delete(key []byte) error {
|
||||
err := db.ldb.Delete(key, nil)
|
||||
func (db *LevelDB) Delete(key *database.Key) error {
|
||||
err := db.ldb.Delete(key.Bytes(), nil)
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func TestLevelDBSanity(t *testing.T) {
|
||||
}()
|
||||
|
||||
// Put something into the db
|
||||
key := []byte("key")
|
||||
key := database.MakeBucket().Key([]byte("key"))
|
||||
putData := []byte("Hello world!")
|
||||
err = ldb.Put(key, putData)
|
||||
if err != nil {
|
||||
@ -80,7 +80,7 @@ func TestLevelDBTransactionSanity(t *testing.T) {
|
||||
}
|
||||
|
||||
// Put something into the transaction
|
||||
key := []byte("key")
|
||||
key := database.MakeBucket().Key([]byte("key"))
|
||||
putData := []byte("Hello world!")
|
||||
err = tx.Put(key, putData)
|
||||
if err != nil {
|
||||
@ -124,7 +124,7 @@ func TestLevelDBTransactionSanity(t *testing.T) {
|
||||
|
||||
// Case 2. Write directly to the DB and then read from a tx
|
||||
// Put something into the db
|
||||
key = []byte("key2")
|
||||
key = database.MakeBucket().Key([]byte("key2"))
|
||||
putData = []byte("Goodbye world!")
|
||||
err = ldb.Put(key, putData)
|
||||
if err != nil {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package ldb
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"github.com/kaspanet/kaspad/database"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
@ -82,27 +81,27 @@ func (tx *LevelDBTransaction) RollbackUnlessClosed() error {
|
||||
|
||||
// Put sets the value for the given key. It overwrites
|
||||
// any previous value for that key.
|
||||
func (tx *LevelDBTransaction) Put(key []byte, value []byte) error {
|
||||
func (tx *LevelDBTransaction) Put(key *database.Key, value []byte) error {
|
||||
if tx.isClosed {
|
||||
return errors.New("cannot put into a closed transaction")
|
||||
}
|
||||
|
||||
tx.batch.Put(key, value)
|
||||
tx.batch.Put(key.Bytes(), value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get gets the value for the given key. It returns
|
||||
// ErrNotFound if the given key does not exist.
|
||||
func (tx *LevelDBTransaction) Get(key []byte) ([]byte, error) {
|
||||
func (tx *LevelDBTransaction) Get(key *database.Key) ([]byte, error) {
|
||||
if tx.isClosed {
|
||||
return nil, errors.New("cannot get from a closed transaction")
|
||||
}
|
||||
|
||||
data, err := tx.snapshot.Get(key, nil)
|
||||
data, err := tx.snapshot.Get(key.Bytes(), nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, leveldb.ErrNotFound) {
|
||||
return nil, errors.Wrapf(database.ErrNotFound,
|
||||
"key %s not found", hex.EncodeToString(key))
|
||||
"key %s not found", key)
|
||||
}
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
@ -111,30 +110,30 @@ func (tx *LevelDBTransaction) Get(key []byte) ([]byte, error) {
|
||||
|
||||
// Has returns true if the database does contains the
|
||||
// given key.
|
||||
func (tx *LevelDBTransaction) Has(key []byte) (bool, error) {
|
||||
func (tx *LevelDBTransaction) Has(key *database.Key) (bool, error) {
|
||||
if tx.isClosed {
|
||||
return false, errors.New("cannot has from a closed transaction")
|
||||
}
|
||||
|
||||
return tx.snapshot.Has(key, nil)
|
||||
return tx.snapshot.Has(key.Bytes(), nil)
|
||||
}
|
||||
|
||||
// Delete deletes the value for the given key. Will not
|
||||
// return an error if the key doesn't exist.
|
||||
func (tx *LevelDBTransaction) Delete(key []byte) error {
|
||||
func (tx *LevelDBTransaction) Delete(key *database.Key) error {
|
||||
if tx.isClosed {
|
||||
return errors.New("cannot delete from a closed transaction")
|
||||
}
|
||||
|
||||
tx.batch.Delete(key)
|
||||
tx.batch.Delete(key.Bytes())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Cursor begins a new cursor over the given bucket.
|
||||
func (tx *LevelDBTransaction) Cursor(bucket []byte) (*LevelDBCursor, error) {
|
||||
func (tx *LevelDBTransaction) Cursor(bucket *database.Bucket) (*LevelDBCursor, error) {
|
||||
if tx.isClosed {
|
||||
return nil, errors.New("cannot open a cursor from a closed transaction")
|
||||
}
|
||||
|
||||
return tx.db.Cursor(bucket), nil
|
||||
return tx.db.Cursor(bucket.Path()), nil
|
||||
}
|
||||
|
@ -20,28 +20,28 @@ type transaction struct {
|
||||
// Put sets the value for the given key. It overwrites
|
||||
// any previous value for that key.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (tx *transaction) Put(key []byte, value []byte) error {
|
||||
func (tx *transaction) Put(key *database.Key, value []byte) error {
|
||||
return tx.ldbTx.Put(key, value)
|
||||
}
|
||||
|
||||
// Get gets the value for the given key. It returns
|
||||
// ErrNotFound if the given key does not exist.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (tx *transaction) Get(key []byte) ([]byte, error) {
|
||||
func (tx *transaction) Get(key *database.Key) ([]byte, error) {
|
||||
return tx.ldbTx.Get(key)
|
||||
}
|
||||
|
||||
// Has returns true if the database does contains the
|
||||
// given key.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (tx *transaction) Has(key []byte) (bool, error) {
|
||||
func (tx *transaction) Has(key *database.Key) (bool, error) {
|
||||
return tx.ldbTx.Has(key)
|
||||
}
|
||||
|
||||
// Delete deletes the value for the given key. Will not
|
||||
// return an error if the key doesn't exist.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (tx *transaction) Delete(key []byte) error {
|
||||
func (tx *transaction) Delete(key *database.Key) error {
|
||||
return tx.ldbTx.Delete(key)
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ func (tx *transaction) RetrieveFromStore(storeName string, location []byte) ([]b
|
||||
|
||||
// Cursor begins a new cursor over the given bucket.
|
||||
// This method is part of the DataAccessor interface.
|
||||
func (tx *transaction) Cursor(bucket []byte) (database.Cursor, error) {
|
||||
func (tx *transaction) Cursor(bucket *database.Bucket) (database.Cursor, error) {
|
||||
return tx.ldbTx.Cursor(bucket)
|
||||
}
|
||||
|
||||
|
85
database/keys.go
Normal file
85
database/keys.go
Normal file
@ -0,0 +1,85 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
var bucketSeparator = []byte("/")
|
||||
|
||||
// Key is a helper type meant to combine prefix
|
||||
// and suffix into a single database key.
|
||||
type Key struct {
|
||||
bucket *Bucket
|
||||
suffix []byte
|
||||
}
|
||||
|
||||
// Bytes returns the full key bytes that are consisted
|
||||
// from the bucket path concatenated to the suffix.
|
||||
func (k *Key) Bytes() []byte {
|
||||
bucketPath := k.bucket.Path()
|
||||
keyBytes := make([]byte, len(bucketPath)+len(k.suffix))
|
||||
copy(keyBytes, bucketPath)
|
||||
copy(keyBytes[len(bucketPath):], k.suffix)
|
||||
return keyBytes
|
||||
}
|
||||
|
||||
func (k *Key) String() string {
|
||||
return hex.EncodeToString(k.Bytes())
|
||||
}
|
||||
|
||||
// Bucket returns the key bucket.
|
||||
func (k *Key) Bucket() *Bucket {
|
||||
return k.bucket
|
||||
}
|
||||
|
||||
// Suffix returns the key suffix.
|
||||
func (k *Key) Suffix() []byte {
|
||||
return k.suffix
|
||||
}
|
||||
|
||||
// newKey returns a new key composed
|
||||
// of the given bucket and suffix
|
||||
func newKey(bucket *Bucket, suffix []byte) *Key {
|
||||
return &Key{bucket: bucket, suffix: suffix}
|
||||
}
|
||||
|
||||
// Bucket is a helper type meant to combine buckets
|
||||
// and sub-buckets that can be used to create database
|
||||
// keys and prefix-based cursors.
|
||||
type Bucket struct {
|
||||
path [][]byte
|
||||
}
|
||||
|
||||
// MakeBucket creates a new Bucket using the given path
|
||||
// of buckets.
|
||||
func MakeBucket(path ...[]byte) *Bucket {
|
||||
return &Bucket{path: path}
|
||||
}
|
||||
|
||||
// Bucket returns the sub-bucket of the current bucket
|
||||
// defined by bucketBytes.
|
||||
func (b *Bucket) Bucket(bucketBytes []byte) *Bucket {
|
||||
newPath := make([][]byte, len(b.path)+1)
|
||||
copy(newPath, b.path)
|
||||
copy(newPath[len(b.path):], [][]byte{bucketBytes})
|
||||
|
||||
return MakeBucket(newPath...)
|
||||
}
|
||||
|
||||
// Key returns a key in the current bucket with the
|
||||
// given suffix.
|
||||
func (b *Bucket) Key(suffix []byte) *Key {
|
||||
return newKey(b, suffix)
|
||||
}
|
||||
|
||||
// Path returns the full path of the current bucket.
|
||||
func (b *Bucket) Path() []byte {
|
||||
bucketPath := bytes.Join(b.path, bucketSeparator)
|
||||
|
||||
bucketPathWithFinalSeparator := make([]byte, len(bucketPath)+len(bucketSeparator))
|
||||
copy(bucketPathWithFinalSeparator, bucketPath)
|
||||
copy(bucketPathWithFinalSeparator[len(bucketPath):], bucketSeparator)
|
||||
|
||||
return bucketPathWithFinalSeparator
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -45,17 +46,26 @@ func TestBucketKey(t *testing.T) {
|
||||
tests := []struct {
|
||||
bucketByteSlices [][]byte
|
||||
key []byte
|
||||
expectedKey []byte
|
||||
expectedKeyBytes []byte
|
||||
expectedKey *Key
|
||||
}{
|
||||
{
|
||||
bucketByteSlices: [][]byte{[]byte("hello")},
|
||||
key: []byte("test"),
|
||||
expectedKey: []byte("hello/test"),
|
||||
expectedKeyBytes: []byte("hello/test"),
|
||||
expectedKey: &Key{
|
||||
bucket: MakeBucket([]byte("hello")),
|
||||
suffix: []byte("test"),
|
||||
},
|
||||
},
|
||||
{
|
||||
bucketByteSlices: [][]byte{[]byte("hello"), []byte("world")},
|
||||
key: []byte("test"),
|
||||
expectedKey: []byte("hello/world/test"),
|
||||
expectedKeyBytes: []byte("hello/world/test"),
|
||||
expectedKey: &Key{
|
||||
bucket: MakeBucket([]byte("hello"), []byte("world")),
|
||||
suffix: []byte("test"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -63,7 +73,11 @@ func TestBucketKey(t *testing.T) {
|
||||
resultKey := MakeBucket(test.bucketByteSlices...).Key(test.key)
|
||||
if !reflect.DeepEqual(resultKey, test.expectedKey) {
|
||||
t.Errorf("TestBucketKey: got wrong key. Want: %s, got: %s",
|
||||
string(test.expectedKey), string(resultKey))
|
||||
test.expectedKeyBytes, resultKey)
|
||||
}
|
||||
if !bytes.Equal(resultKey.Bytes(), test.expectedKeyBytes) {
|
||||
t.Errorf("TestBucketKey: got wrong key bytes. Want: %s, got: %s",
|
||||
test.expectedKeyBytes, resultKey.Bytes())
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ var (
|
||||
acceptanceIndexBucket = database.MakeBucket([]byte("acceptance-index"))
|
||||
)
|
||||
|
||||
func acceptanceIndexKey(hash *daghash.Hash) []byte {
|
||||
func acceptanceIndexKey(hash *daghash.Hash) *database.Key {
|
||||
return acceptanceIndexBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ var (
|
||||
blockLocationsBucket = database.MakeBucket([]byte("block-locations"))
|
||||
)
|
||||
|
||||
func blockLocationKey(hash *daghash.Hash) []byte {
|
||||
func blockLocationKey(hash *daghash.Hash) *database.Key {
|
||||
return blockLocationsBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ func BlockIndexCursor(context Context) (database.Cursor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor.Cursor(blockIndexBucket.Path())
|
||||
return accessor.Cursor(blockIndexBucket)
|
||||
}
|
||||
|
||||
// BlockIndexCursorFrom opens a cursor over blocks-index blocks
|
||||
|
@ -11,8 +11,8 @@ func clearBucket(dbTx *TxContext, bucket *database.Bucket) error {
|
||||
// Collect all of the keys before deleting them. We do this
|
||||
// as to not modify the cursor while we're still iterating
|
||||
// over it.
|
||||
keys := make([][]byte, 0)
|
||||
cursor, err := accessor.Cursor(bucket.Path())
|
||||
keys := make([]*database.Key, 0)
|
||||
cursor, err := accessor.Cursor(bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package dbaccess
|
||||
|
||||
import "github.com/kaspanet/kaspad/database"
|
||||
|
||||
var (
|
||||
dagStateKey = []byte("dag-state")
|
||||
dagStateKey = database.MakeBucket().Key([]byte("dag-state"))
|
||||
)
|
||||
|
||||
// StoreDAGState stores the DAG state in the database.
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
var feeBucket = database.MakeBucket([]byte("fees"))
|
||||
|
||||
func feeDataKey(hash *daghash.Hash) []byte {
|
||||
func feeDataKey(hash *daghash.Hash) *database.Key {
|
||||
return feeBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
var multisetBucket = database.MakeBucket([]byte("multiset"))
|
||||
|
||||
func multisetKey(hash *daghash.Hash) []byte {
|
||||
func multisetKey(hash *daghash.Hash) *database.Key {
|
||||
return multisetBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ func MultisetCursor(context Context) (database.Cursor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor.Cursor(multisetBucket.Path())
|
||||
return accessor.Cursor(multisetBucket)
|
||||
}
|
||||
|
||||
// StoreMultiset stores the multiset of a block by its hash.
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
var reachabilityDataBucket = database.MakeBucket([]byte("reachability"))
|
||||
|
||||
func reachabilityKey(hash *daghash.Hash) []byte {
|
||||
func reachabilityKey(hash *daghash.Hash) *database.Key {
|
||||
return reachabilityDataBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ func ReachabilityDataCursor(context Context) (database.Cursor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor.Cursor(reachabilityDataBucket.Path())
|
||||
return accessor.Cursor(reachabilityDataBucket)
|
||||
}
|
||||
|
||||
// StoreReachabilityData stores the reachability data of a block by its hash.
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
var subnetworkBucket = database.MakeBucket([]byte("subnetworks"))
|
||||
|
||||
func subnetworkKey(subnetworkID *subnetworkid.SubnetworkID) []byte {
|
||||
func subnetworkKey(subnetworkID *subnetworkid.SubnetworkID) *database.Key {
|
||||
return subnetworkBucket.Key(subnetworkID[:])
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ var (
|
||||
utxoBucket = database.MakeBucket([]byte("utxo"))
|
||||
)
|
||||
|
||||
func utxoKey(outpointKey []byte) []byte {
|
||||
func utxoKey(outpointKey []byte) *database.Key {
|
||||
return utxoBucket.Key(outpointKey)
|
||||
}
|
||||
|
||||
@ -44,5 +44,5 @@ func UTXOSetCursor(context Context) (database.Cursor, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor.Cursor(utxoBucket.Path())
|
||||
return accessor.Cursor(utxoBucket)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
var utxoDiffsBucket = database.MakeBucket([]byte("utxo-diffs"))
|
||||
|
||||
func utxoDiffKey(hash *daghash.Hash) []byte {
|
||||
func utxoDiffKey(hash *daghash.Hash) *database.Key {
|
||||
return utxoDiffsBucket.Key(hash[:])
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user