[#602] blobovnicza: Add leaf width implementation

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-08-18 09:08:26 +03:00
parent d3904ec599
commit 354a92ea2c
4 changed files with 26 additions and 5 deletions

View file

@ -776,6 +776,7 @@ func (c *cfg) getSubstorageOpts(shCfg shardCfg) []blobstor.SubStorage {
blobovniczatree.WithBlobovniczaSize(sRead.size), blobovniczatree.WithBlobovniczaSize(sRead.size),
blobovniczatree.WithBlobovniczaShallowDepth(sRead.depth), blobovniczatree.WithBlobovniczaShallowDepth(sRead.depth),
blobovniczatree.WithBlobovniczaShallowWidth(sRead.width), blobovniczatree.WithBlobovniczaShallowWidth(sRead.width),
blobovniczatree.WithBlobovniczaLeafWidth(sRead.leafWidth),
blobovniczatree.WithOpenedCacheSize(sRead.openedCacheSize), blobovniczatree.WithOpenedCacheSize(sRead.openedCacheSize),
blobovniczatree.WithLogger(c.log), blobovniczatree.WithLogger(c.log),
} }

View file

@ -98,6 +98,10 @@ func NewBlobovniczaTree(opts ...Option) (blz *Blobovniczas) {
opts[i](&blz.cfg) opts[i](&blz.cfg)
} }
if blz.blzLeafWidth == 0 {
blz.blzLeafWidth = blz.blzShallowWidth
}
cache, err := simplelru.NewLRU[string, *blobovnicza.Blobovnicza](blz.openedCacheSize, func(p string, value *blobovnicza.Blobovnicza) { cache, err := simplelru.NewLRU[string, *blobovnicza.Blobovnicza](blz.openedCacheSize, func(p string, value *blobovnicza.Blobovnicza) {
lvlPath := filepath.Dir(p) lvlPath := filepath.Dir(p)
if b, ok := blz.active[lvlPath]; ok && b.ind == u64FromHexString(filepath.Base(p)) { if b, ok := blz.active[lvlPath]; ok && b.ind == u64FromHexString(filepath.Base(p)) {
@ -120,13 +124,17 @@ func NewBlobovniczaTree(opts ...Option) (blz *Blobovniczas) {
panic(fmt.Errorf("could not create LRU cache of size %d: %w", blz.openedCacheSize, err)) panic(fmt.Errorf("could not create LRU cache of size %d: %w", blz.openedCacheSize, err))
} }
cp := uint64(1) activeMapCapacity := uint64(1)
for i := uint64(0); i < blz.blzShallowDepth; i++ { for i := uint64(0); i < blz.blzShallowDepth; i++ {
cp *= blz.blzShallowWidth if i+1 == blz.blzShallowDepth {
activeMapCapacity *= blz.blzLeafWidth
} else {
activeMapCapacity *= blz.blzShallowWidth
}
} }
blz.opened = cache blz.opened = cache
blz.active = make(map[string]blobovniczaWithIndex, cp) blz.active = make(map[string]blobovniczaWithIndex, activeMapCapacity)
return blz return blz
} }
@ -161,7 +169,7 @@ func (b *Blobovniczas) updateAndGet(lvlPath string, old *uint64) (blobovniczaWit
if ok { if ok {
if old != nil { if old != nil {
if active.ind == b.blzShallowWidth-1 { if active.ind == b.blzLeafWidth-1 {
return active, logicerr.New("no more Blobovniczas") return active, logicerr.New("no more Blobovniczas")
} else if active.ind != *old { } else if active.ind != *old {
// sort of CAS in order to control concurrent // sort of CAS in order to control concurrent

View file

@ -115,7 +115,12 @@ func (b *Blobovniczas) iterateDeepest(ctx context.Context, addr oid.Address, f f
// iterator over particular level of directories. // iterator over particular level of directories.
func (b *Blobovniczas) iterateSorted(ctx context.Context, addr *oid.Address, curPath []string, execDepth uint64, f func([]string) (bool, error)) (bool, error) { func (b *Blobovniczas) iterateSorted(ctx context.Context, addr *oid.Address, curPath []string, execDepth uint64, f func([]string) (bool, error)) (bool, error) {
indices := indexSlice(b.blzShallowWidth) isLeafLevel := uint64(len(curPath)) == b.blzShallowDepth
levelWidth := b.blzShallowWidth
if isLeafLevel {
levelWidth = b.blzLeafWidth
}
indices := indexSlice(levelWidth)
hrw.SortSliceByValue(indices, addressHash(addr, filepath.Join(curPath...))) hrw.SortSliceByValue(indices, addressHash(addr, filepath.Join(curPath...)))

View file

@ -17,6 +17,7 @@ type cfg struct {
openedCacheSize int openedCacheSize int
blzShallowDepth uint64 blzShallowDepth uint64
blzShallowWidth uint64 blzShallowWidth uint64
blzLeafWidth uint64
compression *compression.Config compression *compression.Config
blzOpts []blobovnicza.Option blzOpts []blobovnicza.Option
// reportError is the function called when encountering disk errors. // reportError is the function called when encountering disk errors.
@ -64,6 +65,12 @@ func WithBlobovniczaShallowWidth(width uint64) Option {
} }
} }
func WithBlobovniczaLeafWidth(w uint64) Option {
return func(c *cfg) {
c.blzLeafWidth = w
}
}
func WithBlobovniczaShallowDepth(depth uint64) Option { func WithBlobovniczaShallowDepth(depth uint64) Option {
return func(c *cfg) { return func(c *cfg) {
c.blzShallowDepth = depth c.blzShallowDepth = depth