mirror of
https://github.com/status-im/nim-stew.git
synced 2025-02-10 03:04:33 +00:00
Fix iterator edge cases for [high(P),high(P)] (#129)
also: cascaded `if` in rbtree (for unrelated troubleshooting)
This commit is contained in:
parent
f173efc500
commit
8a9816ac02
@ -849,13 +849,17 @@ iterator increasing*[P,S](
|
||||
## any interval already visited. Intervals not visited yet must not be
|
||||
## deleted as the loop would become unpredictable.
|
||||
var rc = ds.leftPos.ge(minPt)
|
||||
while rc.isOk:
|
||||
let key = rc.value.key
|
||||
if high(P) <= rc.value.right and ds.lastHigh:
|
||||
yield Interval[P,S].new(rc.value.left,high(P))
|
||||
else:
|
||||
yield Interval[P,S].new(rc.value)
|
||||
rc = ds.leftPos.gt(key)
|
||||
if rc.isErr:
|
||||
if ds.lastHigh:
|
||||
yield Interval[P,S].new(high(P),high(P))
|
||||
else:
|
||||
while rc.isOk:
|
||||
let key = rc.value.key
|
||||
if high(P) <= rc.value.right and ds.lastHigh:
|
||||
yield Interval[P,S].new(rc.value.left,high(P))
|
||||
else:
|
||||
yield Interval[P,S].new(rc.value)
|
||||
rc = ds.leftPos.gt(key)
|
||||
|
||||
iterator decreasing*[P,S](
|
||||
ds: IntervalSetRef[P,S];
|
||||
@ -866,8 +870,10 @@ iterator decreasing*[P,S](
|
||||
##
|
||||
## See the note at the `increasing()` function comment about deleting items.
|
||||
var rc = ds.leftPos.le(maxPt)
|
||||
|
||||
if rc.isOk:
|
||||
if rc.isErr:
|
||||
if ds.lastHigh:
|
||||
yield Interval[P,S].new(high(P),high(P))
|
||||
else:
|
||||
let key = rc.value.key
|
||||
# last entry: check for additional point
|
||||
if high(P) <= rc.value.right and ds.lastHigh:
|
||||
@ -877,10 +883,10 @@ iterator decreasing*[P,S](
|
||||
# find the next smaller one
|
||||
rc = ds.leftPos.lt(key)
|
||||
|
||||
while rc.isOk:
|
||||
let key = rc.value.key
|
||||
yield Interval[P,S].new(rc.value)
|
||||
rc = ds.leftPos.lt(key)
|
||||
while rc.isOk:
|
||||
let key = rc.value.key
|
||||
yield Interval[P,S].new(rc.value)
|
||||
rc = ds.leftPos.lt(key)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public interval operators
|
||||
|
@ -119,8 +119,9 @@ proc rbTreeDelete*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] =
|
||||
dirY = q.linkLeft.isNil.toDir
|
||||
parent.link[dirX] = q.link[dirY];
|
||||
# clear node cache if this was the one to be deleted
|
||||
if not rbt.cache.isNil and rbt.cmp(rbt.cache.casket,key) == 0:
|
||||
rbt.cache = nil
|
||||
if not rbt.cache.isNil:
|
||||
if rbt.cmp(rbt.cache.casket,key) == 0:
|
||||
rbt.cache = nil
|
||||
q = nil # some hint for the GC to recycle that node
|
||||
|
||||
rbt.size.dec
|
||||
|
@ -31,8 +31,9 @@ proc rbTreeFindEq*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] =
|
||||
if rbt.root.isNil:
|
||||
return err(rbEmptyTree)
|
||||
|
||||
if not rbt.cache.isNil and rbt.cmp(rbt.cache.casket,key) == 0:
|
||||
return ok(rbt.cache.casket)
|
||||
if not rbt.cache.isNil:
|
||||
if rbt.cmp(rbt.cache.casket,key) == 0:
|
||||
return ok(rbt.cache.casket)
|
||||
|
||||
var
|
||||
q = rbt.root
|
||||
|
@ -177,6 +177,24 @@ suite "IntervalSet: Intervals of FancyPoint entries over FancyScalar":
|
||||
check br.total.truncate(uint64) == (uHigh - 10000000) + 1
|
||||
check br.verify.isOk
|
||||
|
||||
br.clear()
|
||||
check br.total == 0 and br.chunks == 0
|
||||
check br.merge(uHigh,uHigh) == 1
|
||||
|
||||
block:
|
||||
var (ivVal, ivSet) = (iv(0,0), false)
|
||||
for iv in br.increasing:
|
||||
check ivSet == false
|
||||
(ivVal, ivSet) = (iv, true)
|
||||
check ivVal == iv(uHigh,uHigh)
|
||||
|
||||
block:
|
||||
var (ivVal, ivSet) = (iv(0,0), false)
|
||||
for iv in br.decreasing:
|
||||
check ivSet == false
|
||||
(ivVal, ivSet) = (iv, true)
|
||||
check ivVal == iv(uHigh,uHigh)
|
||||
|
||||
test "Merge disjunct intervals on 1st set":
|
||||
br.clear()
|
||||
check br.merge( 0, 99) == 100
|
||||
|
Loading…
x
Reference in New Issue
Block a user