forked from TrueCloudLab/frostfs-node
95 lines
1.6 KiB
Go
95 lines
1.6 KiB
Go
|
package blobtree
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type rootDispatcher struct {
|
||
|
dispatchers map[string]*dirDispatcher
|
||
|
guard sync.Mutex
|
||
|
}
|
||
|
|
||
|
func newRootDispatcher() *rootDispatcher {
|
||
|
return &rootDispatcher{
|
||
|
dispatchers: make(map[string]*dirDispatcher),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *rootDispatcher) GetIdxForWrite(dir string) uint64 {
|
||
|
return d.getDirDispatcher(dir).GetIdxForWrite()
|
||
|
}
|
||
|
|
||
|
func (d *rootDispatcher) ReturnIdx(dir string, idx uint64) {
|
||
|
d.getDirDispatcher(dir).ReturnIdx(idx)
|
||
|
}
|
||
|
|
||
|
func (d *rootDispatcher) Init(dir string, idx uint64) {
|
||
|
d.getDirDispatcher(dir).Init(idx)
|
||
|
}
|
||
|
|
||
|
func (d *rootDispatcher) getDirDispatcher(dir string) *dirDispatcher {
|
||
|
d.guard.Lock()
|
||
|
defer d.guard.Unlock()
|
||
|
|
||
|
if result, ok := d.dispatchers[dir]; ok {
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
result := newDirDispatcher(dir)
|
||
|
d.dispatchers[dir] = result
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
type dirDispatcher struct {
|
||
|
dir string
|
||
|
guard sync.Mutex
|
||
|
indicies map[uint64]struct{}
|
||
|
nextIndex uint64
|
||
|
}
|
||
|
|
||
|
func newDirDispatcher(dir string) *dirDispatcher {
|
||
|
return &dirDispatcher{
|
||
|
dir: dir,
|
||
|
indicies: make(map[uint64]struct{}),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *dirDispatcher) GetIdxForWrite() uint64 {
|
||
|
d.guard.Lock()
|
||
|
defer d.guard.Unlock()
|
||
|
|
||
|
var result uint64
|
||
|
var found bool
|
||
|
|
||
|
for idx := range d.indicies {
|
||
|
result = idx
|
||
|
found = true
|
||
|
break
|
||
|
}
|
||
|
|
||
|
if found {
|
||
|
delete(d.indicies, result)
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
result = d.nextIndex
|
||
|
d.nextIndex++
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func (d *dirDispatcher) ReturnIdx(idx uint64) {
|
||
|
d.guard.Lock()
|
||
|
defer d.guard.Unlock()
|
||
|
|
||
|
d.indicies[idx] = struct{}{}
|
||
|
}
|
||
|
|
||
|
func (d *dirDispatcher) Init(idx uint64) {
|
||
|
d.guard.Lock()
|
||
|
defer d.guard.Unlock()
|
||
|
|
||
|
if d.nextIndex <= idx {
|
||
|
d.nextIndex = idx + 1
|
||
|
}
|
||
|
}
|