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{ expired: make(map[cid.ID]*bbolt.Bucket), primary: make(map[cid.ID]*bbolt.Bucket), } } 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 } bucketName := make([]byte, bucketKeySize) bucketName = nameFunc(cnr, bucketName) m[cnr] = getBucket(&value, tx, bucketName) return value }