package meta import ( cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "go.etcd.io/bbolt" ) type bucketCache struct { locked *bbolt.Bucket graveyard *bbolt.Bucket garbage *bbolt.Bucket expired map[cid.ID]*bbolt.Bucket primary map[cid.ID]*bbolt.Bucket } func newBucketCache() *bucketCache { return &bucketCache{} } func getLockedBucket(bc *bucketCache, tx *bbolt.Tx) *bbolt.Bucket { if bc == nil { return tx.Bucket(bucketNameLocked) } return getBucket(&bc.locked, tx, bucketNameLocked) } func getGraveyardBucket(bc *bucketCache, tx *bbolt.Tx) *bbolt.Bucket { if bc == nil { return tx.Bucket(graveyardBucketName) } return getBucket(&bc.graveyard, tx, graveyardBucketName) } func getGarbageBucket(bc *bucketCache, tx *bbolt.Tx) *bbolt.Bucket { if bc == nil { return tx.Bucket(garbageBucketName) } return getBucket(&bc.garbage, tx, garbageBucketName) } func getBucket(cache **bbolt.Bucket, tx *bbolt.Tx, name []byte) *bbolt.Bucket { if *cache != nil { return *cache } *cache = tx.Bucket(name) return *cache } func getExpiredBucket(bc *bucketCache, tx *bbolt.Tx, cnr cid.ID) *bbolt.Bucket { if bc == nil { bucketName := make([]byte, bucketKeySize) bucketName = objectToExpirationEpochBucketName(cnr, bucketName) return tx.Bucket(bucketName) } 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 { return value } if *m == nil { *m = make(map[cid.ID]*bbolt.Bucket, 1) } bucketName := make([]byte, bucketKeySize) bucketName = nameFunc(cnr, bucketName) (*m)[cnr] = getBucket(&value, tx, bucketName) return value }