correctly precalculate the minimum free prefix length on alloc, so recalculation can be skipped for deeply nested inserts

This commit is contained in:
Johannes Kimmel 2023-11-13 23:50:26 +01:00
parent c124d3c614
commit b7216e783d
1 changed files with 15 additions and 12 deletions

View File

@ -112,12 +112,14 @@ func (t *tree) Alloc(bits int) *tree {
return nil
}
tofix := best
// the first insert can be into a new hi branch
if best.lo != nil {
best.hi = &tree{
prefix: SplitPrefixHi(best.prefix),
parent: best,
minfreelen: best.prefix.Bits() + 1,
minfreelen: best.prefix.Bits() + 2,
}
best = best.hi
}
@ -127,12 +129,14 @@ func (t *tree) Alloc(bits int) *tree {
best.lo = &tree{
prefix: SplitPrefixLo(best.prefix),
parent: best,
minfreelen: best.prefix.Bits() + 1,
minfreelen: best.prefix.Bits() + 2,
}
best = best.lo
}
best.fixMinFreeAll()
best.fixMinFree()
tofix.fixMinFreeAll()
return best
}
@ -142,26 +146,25 @@ func (t *tree) fixMinFree() {
}
if t.Leaf() {
t.minfreelen = t.prefix.Addr().BitLen() + 1
return
}
lofree := t.lo.calcfreelen(t)
hifree := t.hi.calcfreelen(t)
minfreelen := max(min(lofree, hifree), t.prefix.Bits()+1)
if t.minfreelen != minfreelen {
//log.Printf("lo:%v, hi:%v\n", fixfree.lo == nil, fixfree.hi == nil)
//log.Printf("Fixing space for %q, lo: %d, hi: %d, old: %d, new: %d", fixfree.prefix, lofree, hifree, fixfree.minfreelen, minfreelen)
t.minfreelen = minfreelen
}
//if t.minfreelen != minfreelen {
// log.Printf("lo:%v, hi:%v\n", t.lo == nil, t.hi == nil)
// log.Printf("Fixing space for %q, lo: %d, hi: %d, old: %d, new: %d", t.prefix, lofree, hifree, t.minfreelen, minfreelen)
//}
t.minfreelen = minfreelen
}
func (t *tree) fixMinFreeAll() {
if t == nil {
return
}
if t.Leaf() {
t.minfreelen = t.prefix.Addr().BitLen() + 1
}
fixfree := t.parent
fixfree := t
for fixfree != nil {
fixfree.fixMinFree()