[#1691] blobovniczatree: Fix active blobovnicza caching

Maintain an invariant that any blobovnicza is present either
in `opened` or in `active` map. Otherwise, the logic becomes too
complicate because it is not obvious when we should close the blobovnicza.

Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-08-30 09:15:16 +03:00 committed by fyrchik
parent dfac4e1c0b
commit d8a00c365a
3 changed files with 97 additions and 26 deletions

View file

@ -179,19 +179,26 @@ func (b *Blobovniczas) updateAndGet(p string, old *uint64) (blobovniczaWithIndex
defer b.activeMtx.Unlock()
// check 2nd time to find out if it blobovnicza was activated while thread was locked
if tryActive, ok := b.active[p]; ok && tryActive.blz == active.blz {
tryActive, ok := b.active[p]
if ok && tryActive.blz == active.blz {
return tryActive, nil
}
// remove from opened cache (active blobovnicza should always be opened)
b.lruMtx.Lock()
b.opened.Remove(p)
b.lruMtx.Unlock()
// Remove from opened cache (active blobovnicza should always be opened).
// Because `onEvict` callback is called in `Remove`, we need to update
// active map beforehand.
b.active[p] = active
activePath := filepath.Join(p, u64ToHexString(active.ind))
b.lruMtx.Lock()
b.opened.Remove(activePath)
if ok {
b.opened.Add(filepath.Join(p, u64ToHexString(tryActive.ind)), tryActive.blz)
}
b.lruMtx.Unlock()
b.log.Debug("blobovnicza successfully activated",
zap.String("path", filepath.Join(p, u64ToHexString(active.ind))),
)
zap.String("path", activePath))
return active, nil
}