package writecache import ( "fmt" "math" "sync/atomic" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree" "go.etcd.io/bbolt" ) func (c *cache) estimateCacheSize() (uint64, uint64) { dbCount := c.objCounters.DB() fsCount := c.objCounters.FS() if fsCount > 0 { fsCount-- // db file } dbSize := dbCount * c.smallObjectSize fsSize := fsCount * c.maxObjectSize c.metrics.SetEstimateSize(dbSize, fsSize) c.metrics.SetActualCounters(dbCount, fsCount) return dbCount + fsCount, dbSize + fsSize } func (c *cache) hasEnoughSpaceDB() bool { return c.hasEnoughSpace(c.smallObjectSize) } func (c *cache) hasEnoughSpaceFS() bool { return c.hasEnoughSpace(c.maxObjectSize) } func (c *cache) hasEnoughSpace(objectSize uint64) bool { count, size := c.estimateCacheSize() if c.maxCacheCount > 0 && count+1 > c.maxCacheCount { return false } return c.maxCacheSize >= size+objectSize } var _ fstree.FileCounter = &counters{} type counters struct { cDB, cFS atomic.Uint64 } func (x *counters) DB() uint64 { return x.cDB.Load() } func (x *counters) FS() uint64 { return x.cFS.Load() } // Set implements fstree.ObjectCounter. func (x *counters) Set(v uint64) { x.cFS.Store(v) } // Inc implements fstree.ObjectCounter. func (x *counters) Inc() { x.cFS.Add(1) } // Dec implements fstree.ObjectCounter. func (x *counters) Dec() { x.cFS.Add(math.MaxUint64) } func (c *cache) initCounters() error { var inDB uint64 err := c.db.View(func(tx *bbolt.Tx) error { b := tx.Bucket(defaultBucket) if b != nil { inDB = uint64(b.Stats().KeyN) } return nil }) if err != nil { return fmt.Errorf("could not read write-cache DB counter: %w", err) } c.objCounters.cDB.Store(inDB) c.estimateCacheSize() return nil }