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 return nil } func (b *BlobTree) Init() error { if err := b.createDir(b.cfg.rootPath); err != nil { return err } var eg errgroup.Group eg.SetLimit(b.cfg.initWorkersCount) eg.Go(func() error { return b.initDir(&eg, b.cfg.rootPath, 0) }) return eg.Wait() } func (b *BlobTree) initDir(eg *errgroup.Group, dir string, depth uint64) error { entities, err := os.ReadDir(dir) if err != nil { return err } for _, entity := range entities { if depth < b.cfg.depth && entity.IsDir() { eg.Go(func() error { return b.initDir(eg, filepath.Join(dir, entity.Name()), depth+1) }) continue } if depth != b.cfg.depth { continue } if b.isTempFile(entity.Name()) { if err = os.Remove(filepath.Join(dir, entity.Name())); err != nil { return err } continue } idx, err := b.parseIdx(entity.Name()) if err != nil { continue } b.dispatcher.Init(dir, idx) stat, err := os.Stat(filepath.Join(dir, entity.Name())) 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(name, 16, 64) } func (b *BlobTree) Close() error { 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(_ string) {}