package writecachebbolt import ( "fmt" "sync/atomic" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "go.etcd.io/bbolt" "go.uber.org/zap" "golang.org/x/sync/errgroup" ) func (c *cache) estimateCacheSize() uint64 { db := c.objCounters.DB() * c.smallObjectSize fstree := c.objCounters.FS() * c.maxObjectSize c.metrics.SetEstimateSize(db, fstree) return db + fstree } func (c *cache) incSizeDB(sz uint64) uint64 { return sz + c.smallObjectSize } func (c *cache) incSizeFS(sz uint64) uint64 { return sz + c.maxObjectSize } 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() } func (c *cache) setCounters() error { var inDB uint64 var inFS uint64 var eg errgroup.Group eg.Go(func() error { 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) return nil }) eg.Go(func() error { var err error inFS, err = c.fsTree.NumberOfObjects() if err != nil { return fmt.Errorf("could not read write-cache FS counter: %w", err) } if inFS > 0 { inFS-- //small.bolt DB file } c.objCounters.cFS.Store(inFS) return nil }) if err := eg.Wait(); err != nil { return err } c.metrics.SetActualCounters(inDB, inFS) return nil } func (c *cache) runDBCounterLoop() { go func() { t := time.NewTicker(time.Second * 30) defer t.Stop() for { select { case <-t.C: err := c.setCounters() if err != nil { c.log.Warn(logs.FailedToCountWritecacheItems, zap.Error(err)) } case <-c.closeCh: return } } }() }