forked from TrueCloudLab/frostfs-node
[#661] blobovniczatree: Allow to change depth or width
Now it is possible to change depth or with of blobovniczatree. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
484eb59893
commit
c1667a11d2
10 changed files with 355 additions and 27 deletions
|
@ -3,6 +3,7 @@ package blobovniczatree
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -70,7 +71,7 @@ func (b *Blobovniczas) Iterate(ctx context.Context, prm common.IteratePrm) (comm
|
|||
|
||||
// iterator over all Blobovniczas in unsorted order. Break on f's error return.
|
||||
func (b *Blobovniczas) iterateBlobovniczas(ctx context.Context, ignoreErrors bool, f func(string, *blobovnicza.Blobovnicza) error) error {
|
||||
return b.iterateLeaves(ctx, func(p string) (bool, error) {
|
||||
return b.iterateExistingDBPaths(ctx, func(p string) (bool, error) {
|
||||
shBlz := b.getBlobovnicza(p)
|
||||
blz, err := shBlz.Open()
|
||||
if err != nil {
|
||||
|
@ -91,7 +92,9 @@ func (b *Blobovniczas) iterateBlobovniczas(ctx context.Context, ignoreErrors boo
|
|||
})
|
||||
}
|
||||
|
||||
// iterator over the paths of Blobovniczas sorted by weight.
|
||||
// iterateSortedLeaves iterates over the paths of Blobovniczas sorted by weight.
|
||||
//
|
||||
// Uses depth, width and leaf width for iteration.
|
||||
func (b *Blobovniczas) iterateSortedLeaves(ctx context.Context, addr *oid.Address, f func(string) (bool, error)) error {
|
||||
_, err := b.iterateSorted(
|
||||
ctx,
|
||||
|
@ -169,9 +172,105 @@ func (b *Blobovniczas) iterateSorted(ctx context.Context, addr *oid.Address, cur
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// iterator over the paths of Blobovniczas in random order.
|
||||
func (b *Blobovniczas) iterateLeaves(ctx context.Context, f func(string) (bool, error)) error {
|
||||
return b.iterateSortedLeaves(ctx, nil, f)
|
||||
// iterateExistingDBPaths iterates over the paths of Blobovniczas without any order.
|
||||
//
|
||||
// Uses existed blobovnicza files for iteration.
|
||||
func (b *Blobovniczas) iterateExistingDBPaths(ctx context.Context, f func(string) (bool, error)) error {
|
||||
_, err := b.iterateExistingDBPathsDFS(ctx, "", f)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *Blobovniczas) iterateExistingDBPathsDFS(ctx context.Context, path string, f func(string) (bool, error)) (bool, error) {
|
||||
sysPath := filepath.Join(b.rootPath, path)
|
||||
entries, err := os.ReadDir(sysPath)
|
||||
if os.IsNotExist(err) && b.readOnly && path == "" { // non initialized tree in read only mode
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false, ctx.Err()
|
||||
default:
|
||||
}
|
||||
if entry.IsDir() {
|
||||
stop, err := b.iterateExistingDBPathsDFS(ctx, filepath.Join(path, entry.Name()), f)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if stop {
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
stop, err := f(filepath.Join(path, entry.Name()))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if stop {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (b *Blobovniczas) iterateSortedDBPaths(ctx context.Context, addr oid.Address, f func(string) (bool, error)) error {
|
||||
_, err := b.iterateSordedDBPathsInternal(ctx, "", addr, f)
|
||||
return err
|
||||
}
|
||||
|
||||
func (b *Blobovniczas) iterateSordedDBPathsInternal(ctx context.Context, path string, addr oid.Address, f func(string) (bool, error)) (bool, error) {
|
||||
sysPath := filepath.Join(b.rootPath, path)
|
||||
entries, err := os.ReadDir(sysPath)
|
||||
if os.IsNotExist(err) && b.readOnly && path == "" { // non initialized tree in read only mode
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
var dbIdxs []uint64
|
||||
var dirIdxs []uint64
|
||||
|
||||
for _, entry := range entries {
|
||||
idx := u64FromHexString(entry.Name())
|
||||
if entry.IsDir() {
|
||||
dirIdxs = append(dirIdxs, idx)
|
||||
} else {
|
||||
dbIdxs = append(dbIdxs, idx)
|
||||
}
|
||||
}
|
||||
|
||||
if len(dbIdxs) > 0 {
|
||||
hrw.SortSliceByValue(dbIdxs, addressHash(&addr, path))
|
||||
for _, dbIdx := range dbIdxs {
|
||||
dbPath := filepath.Join(path, u64ToHexStringExt(dbIdx))
|
||||
stop, err := f(dbPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if stop {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(dirIdxs) > 0 {
|
||||
hrw.SortSliceByValue(dirIdxs, addressHash(&addr, path))
|
||||
for _, dirIdx := range dirIdxs {
|
||||
dirPath := filepath.Join(path, u64ToHexString(dirIdx))
|
||||
stop, err := b.iterateSordedDBPathsInternal(ctx, dirPath, addr, f)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if stop {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// makes slice of uint64 values from 0 to number-1.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue