package blobtree import ( "os" "path/filepath" "strconv" "strings" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression" "golang.org/x/sync/errgroup" ) var Type = "blobtree" func (b *BlobTree) Open(readOnly bool) error { b.cfg.readOnly = readOnly b.cfg.metrics.SetMode(readOnly) return nil } func (b *BlobTree) Init() error { if err := b.createDir(b.cfg.rootPath, true); err != nil { return err } var eg errgroup.Group eg.SetLimit(b.cfg.initWorkersCount) eg.Go(func() error { return b.initDir(&eg, "") }) return eg.Wait() } func (b *BlobTree) initDir(eg *errgroup.Group, dir string) error { entities, err := os.ReadDir(b.getSystemPath(dir)) if err != nil { return err } for _, entity := range entities { if entity.IsDir() { eg.Go(func() error { return b.initDir(eg, filepath.Join(dir, entity.Name())) }) continue } path := filepath.Join(dir, entity.Name()) if b.isTempFile(entity.Name()) { if err = os.Remove(b.getSystemPath(path)); err != nil { return err } continue } idx, err := b.parseIdx(entity.Name()) if err != nil { return err } b.dispatcher.Init(dir, idx) b.cfg.metrics.IncFilesCount() stat, err := os.Stat(b.getSystemPath(path)) if err != nil { return err } if stat.Size() < int64(b.cfg.targetFileSizeBytes) { b.dispatcher.ReturnIdx(dir, idx) } } return nil } func (b *BlobTree) isTempFile(name string) bool { return strings.Contains(name, tempFileSymbols) } func (b *BlobTree) parseIdx(name string) (uint64, error) { return strconv.ParseUint(strings.TrimSuffix(name, dataExtension), 16, 64) } func (b *BlobTree) Close() error { b.cfg.metrics.Close() return nil } func (b *BlobTree) Type() string { return Type } func (b *BlobTree) Path() string { return b.cfg.rootPath } func (b *BlobTree) SetCompressor(cc *compression.Config) { b.compressor = cc } func (b *BlobTree) Compressor() *compression.Config { return b.compressor } func (b *BlobTree) SetReportErrorFunc(_ func(string, error)) {} func (b *BlobTree) SetParentID(parentID string) { b.cfg.metrics.SetParentID(parentID) }