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 } }