[#1685] metabase: Cache primary bucket
Some checks failed
Build / Build Components (push) Has been cancelled
OCI image / Build container images (push) Has been cancelled
Pre-commit hooks / Pre-commit (push) Has been cancelled
Tests and linters / Lint (push) Has been cancelled
Tests and linters / Tests (push) Has been cancelled
Tests and linters / Tests with -race (push) Has been cancelled
Tests and linters / Staticcheck (push) Has been cancelled
Tests and linters / gopls check (push) Has been cancelled
Tests and linters / Run gofumpt (push) Has been cancelled
Vulncheck / Vulncheck (push) Successful in 1m32s
Some checks failed
Build / Build Components (push) Has been cancelled
OCI image / Build container images (push) Has been cancelled
Pre-commit hooks / Pre-commit (push) Has been cancelled
Tests and linters / Lint (push) Has been cancelled
Tests and linters / Tests (push) Has been cancelled
Tests and linters / Tests with -race (push) Has been cancelled
Tests and linters / Staticcheck (push) Has been cancelled
Tests and linters / gopls check (push) Has been cancelled
Tests and linters / Run gofumpt (push) Has been cancelled
Vulncheck / Vulncheck (push) Successful in 1m32s
``` goos: linux goarch: amd64 pkg: git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz │ expired │ primary │ │ sec/op │ sec/op vs base │ Select/string_equal-8 3.529m ± 11% 3.689m ± 7% +4.55% (p=0.023 n=10) Select/string_not_equal-8 3.440m ± 7% 3.543m ± 13% ~ (p=0.190 n=10) Select/common_prefix-8 3.240m ± 6% 3.050m ± 5% -5.85% (p=0.005 n=10) Select/unknown-8 3.198m ± 6% 2.928m ± 8% -8.44% (p=0.003 n=10) geomean 3.349m 3.287m -1.84% │ expired │ primary │ │ B/op │ B/op vs base │ Select/string_equal-8 1.885Mi ± 0% 1.786Mi ± 0% -5.23% (p=0.000 n=10) Select/string_not_equal-8 1.885Mi ± 0% 1.786Mi ± 0% -5.23% (p=0.000 n=10) Select/common_prefix-8 1.885Mi ± 0% 1.786Mi ± 0% -5.23% (p=0.000 n=10) Select/unknown-8 1.877Mi ± 0% 1.779Mi ± 0% -5.26% (p=0.000 n=10) geomean 1.883Mi 1.784Mi -5.24% │ expired │ primary │ │ allocs/op │ allocs/op vs base │ Select/string_equal-8 46.04k ± 0% 43.04k ± 0% -6.50% (p=0.000 n=10) Select/string_not_equal-8 46.04k ± 0% 43.04k ± 0% -6.50% (p=0.000 n=10) Select/common_prefix-8 46.04k ± 0% 43.04k ± 0% -6.50% (p=0.000 n=10) Select/unknown-8 45.05k ± 0% 42.05k ± 0% -6.65% (p=0.000 n=10) geomean 45.79k 42.79k -6.54% ``` Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
21bed3362c
commit
eb9df85b98
3 changed files with 30 additions and 12 deletions
|
@ -10,10 +10,14 @@ type bucketCache struct {
|
|||
graveyard *bbolt.Bucket
|
||||
garbage *bbolt.Bucket
|
||||
expired map[cid.ID]*bbolt.Bucket
|
||||
primary map[cid.ID]*bbolt.Bucket
|
||||
}
|
||||
|
||||
func newBucketCache() *bucketCache {
|
||||
return &bucketCache{expired: make(map[cid.ID]*bbolt.Bucket)}
|
||||
return &bucketCache{
|
||||
expired: make(map[cid.ID]*bbolt.Bucket),
|
||||
primary: make(map[cid.ID]*bbolt.Bucket),
|
||||
}
|
||||
}
|
||||
|
||||
func getLockedBucket(bc *bucketCache, tx *bbolt.Tx) *bbolt.Bucket {
|
||||
|
@ -55,6 +59,15 @@ func getExpiredBucket(bc *bucketCache, tx *bbolt.Tx, cnr cid.ID) *bbolt.Bucket {
|
|||
return getMappedBucket(bc.expired, tx, objectToExpirationEpochBucketName, cnr)
|
||||
}
|
||||
|
||||
func getPrimaryBucket(bc *bucketCache, tx *bbolt.Tx, cnr cid.ID) *bbolt.Bucket {
|
||||
if bc == nil {
|
||||
bucketName := make([]byte, bucketKeySize)
|
||||
bucketName = primaryBucketName(cnr, bucketName)
|
||||
return tx.Bucket(bucketName)
|
||||
}
|
||||
return getMappedBucket(bc.primary, tx, primaryBucketName, cnr)
|
||||
}
|
||||
|
||||
func getMappedBucket(m map[cid.ID]*bbolt.Bucket, tx *bbolt.Tx, nameFunc func(cid.ID, []byte) []byte, cnr cid.ID) *bbolt.Bucket {
|
||||
value, ok := m[cnr]
|
||||
if ok {
|
||||
|
|
|
@ -88,8 +88,12 @@ func (db *DB) Get(ctx context.Context, prm GetPrm) (res GetRes, err error) {
|
|||
}
|
||||
|
||||
func (db *DB) get(tx *bbolt.Tx, addr oid.Address, key []byte, checkStatus, raw bool, currEpoch uint64) (*objectSDK.Object, error) {
|
||||
return db.getWithCache(nil, tx, addr, key, checkStatus, raw, currEpoch)
|
||||
}
|
||||
|
||||
func (db *DB) getWithCache(bc *bucketCache, tx *bbolt.Tx, addr oid.Address, key []byte, checkStatus, raw bool, currEpoch uint64) (*objectSDK.Object, error) {
|
||||
if checkStatus {
|
||||
st, err := objectStatus(tx, addr, currEpoch)
|
||||
st, err := objectStatusWithCache(bc, tx, addr, currEpoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -109,12 +113,13 @@ func (db *DB) get(tx *bbolt.Tx, addr oid.Address, key []byte, checkStatus, raw b
|
|||
bucketName := make([]byte, bucketKeySize)
|
||||
|
||||
// check in primary index
|
||||
data := getFromBucket(tx, primaryBucketName(cnr, bucketName), key)
|
||||
if len(data) != 0 {
|
||||
return obj, obj.Unmarshal(data)
|
||||
if b := getPrimaryBucket(bc, tx, cnr); b != nil {
|
||||
if data := b.Get(key); len(data) != 0 {
|
||||
return obj, obj.Unmarshal(data)
|
||||
}
|
||||
}
|
||||
|
||||
data = getFromBucket(tx, ecInfoBucketName(cnr, bucketName), key)
|
||||
data := getFromBucket(tx, ecInfoBucketName(cnr, bucketName), key)
|
||||
if len(data) != 0 {
|
||||
return nil, getECInfoError(tx, cnr, data)
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ func (db *DB) selectObjects(tx *bbolt.Tx, cnr cid.ID, fs objectSDK.SearchFilters
|
|||
continue // ignore removed objects
|
||||
}
|
||||
|
||||
addr, match := db.matchSlowFilters(tx, addr, group.slowFilters, currEpoch)
|
||||
addr, match := db.matchSlowFilters(bc, tx, addr, group.slowFilters, currEpoch)
|
||||
if !match {
|
||||
continue // ignore objects with unmatched slow filters
|
||||
}
|
||||
|
@ -452,13 +452,13 @@ func (db *DB) selectObjectID(
|
|||
}
|
||||
|
||||
// matchSlowFilters return true if object header is matched by all slow filters.
|
||||
func (db *DB) matchSlowFilters(tx *bbolt.Tx, addr oid.Address, f objectSDK.SearchFilters, currEpoch uint64) (oid.Address, bool) {
|
||||
func (db *DB) matchSlowFilters(bc *bucketCache, tx *bbolt.Tx, addr oid.Address, f objectSDK.SearchFilters, currEpoch uint64) (oid.Address, bool) {
|
||||
result := addr
|
||||
if len(f) == 0 {
|
||||
return result, true
|
||||
}
|
||||
|
||||
obj, isECChunk, err := db.getObjectForSlowFilters(tx, addr, currEpoch)
|
||||
obj, isECChunk, err := db.getObjectForSlowFilters(bc, tx, addr, currEpoch)
|
||||
if err != nil {
|
||||
return result, false
|
||||
}
|
||||
|
@ -516,9 +516,9 @@ func (db *DB) matchSlowFilters(tx *bbolt.Tx, addr oid.Address, f objectSDK.Searc
|
|||
return result, true
|
||||
}
|
||||
|
||||
func (db *DB) getObjectForSlowFilters(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (*objectSDK.Object, bool, error) {
|
||||
func (db *DB) getObjectForSlowFilters(bc *bucketCache, tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (*objectSDK.Object, bool, error) {
|
||||
buf := make([]byte, addressKeySize)
|
||||
obj, err := db.get(tx, addr, buf, false, false, currEpoch)
|
||||
obj, err := db.getWithCache(bc, tx, addr, buf, false, false, currEpoch)
|
||||
if err != nil {
|
||||
var ecInfoError *objectSDK.ECInfoError
|
||||
if errors.As(err, &ecInfoError) {
|
||||
|
@ -528,7 +528,7 @@ func (db *DB) getObjectForSlowFilters(tx *bbolt.Tx, addr oid.Address, currEpoch
|
|||
continue
|
||||
}
|
||||
addr.SetObject(objID)
|
||||
obj, err = db.get(tx, addr, buf, true, false, currEpoch)
|
||||
obj, err = db.getWithCache(bc, tx, addr, buf, true, false, currEpoch)
|
||||
if err == nil {
|
||||
return obj, true, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue