Fix ge() fringe case (#135)
why: The point `high(P)` is treated separately and added to the top adjacent interval or is treated as a sigle point interval.
This commit is contained in:
parent
598246620d
commit
c020fd80f1
|
@ -779,7 +779,9 @@ proc ge*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] =
|
||||||
return ok(Interval[P,S].new(rc.value.left, high(P)))
|
return ok(Interval[P,S].new(rc.value.left, high(P)))
|
||||||
return ok(Interval[P,S].new(rc.value))
|
return ok(Interval[P,S].new(rc.value))
|
||||||
if ds.lastHigh:
|
if ds.lastHigh:
|
||||||
return ok(Interval[P,S].new(high(P),high(P)))
|
const preHigh = high(P) - scalarOne
|
||||||
|
if ds.covered(preHigh,preHigh) == scalarZero:
|
||||||
|
return ok(Interval[P,S].new(high(P),high(P)))
|
||||||
err()
|
err()
|
||||||
|
|
||||||
proc ge*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] =
|
proc ge*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] =
|
||||||
|
@ -793,13 +795,18 @@ proc le*[P,S](ds: IntervalSetRef[P,S]; maxPt: P): IntervalRc[P,S] =
|
||||||
if rc.isOk:
|
if rc.isOk:
|
||||||
# only the left end of segment [left,right) is guaranteed to be <= maxPt
|
# only the left end of segment [left,right) is guaranteed to be <= maxPt
|
||||||
if rc.value.right - scalarOne <= maxPt:
|
if rc.value.right - scalarOne <= maxPt:
|
||||||
if high(P) <= maxPt and ds.lastHigh:
|
if ds.lastHigh:
|
||||||
# Check for fringe case intervals [a,b] gap [high(P),high(P)] <= maxPt
|
if high(P) <= maxPt:
|
||||||
if rc.value.right < high(P):
|
# Check for fringe case intervals [a,b] gap [high(P),high(P)] <= maxPt
|
||||||
return ok(Interval[P,S].new(high(P),high(P)))
|
if rc.value.right < high(P):
|
||||||
# Check for fringe case intervals [a,b] + [high(P),high(P)] <= maxPt
|
return ok(Interval[P,S].new(high(P),high(P)))
|
||||||
|
# Check for fringe case intervals [a,b] + [high(P),high(P)] <= maxPt
|
||||||
|
if high(P) <= rc.value.right:
|
||||||
|
return ok(Interval[P,S].new(rc.value.left,high(P)))
|
||||||
|
# So maxPt < high(P)
|
||||||
if high(P) <= rc.value.right:
|
if high(P) <= rc.value.right:
|
||||||
return ok(Interval[P,S].new(rc.value.left,high(P)))
|
# Now `maxPt` is fully within the inner part of `[left,high(P)]`
|
||||||
|
return err()
|
||||||
return ok(Interval[P,S].new(rc.value))
|
return ok(Interval[P,S].new(rc.value))
|
||||||
# find the next smaller one
|
# find the next smaller one
|
||||||
let xc = ds.leftPos.lt(rc.value.key)
|
let xc = ds.leftPos.lt(rc.value.key)
|
||||||
|
|
|
@ -177,6 +177,7 @@ suite "IntervalSet: Intervals of FancyPoint entries over FancyScalar":
|
||||||
check br.total.truncate(uint64) == (uHigh - 10000000) + 1
|
check br.total.truncate(uint64) == (uHigh - 10000000) + 1
|
||||||
check br.verify.isOk
|
check br.verify.isOk
|
||||||
|
|
||||||
|
test "More edge cases detected and fixed":
|
||||||
br.clear()
|
br.clear()
|
||||||
check br.total == 0 and br.chunks == 0
|
check br.total == 0 and br.chunks == 0
|
||||||
check br.merge(uHigh,uHigh) == 1
|
check br.merge(uHigh,uHigh) == 1
|
||||||
|
@ -187,7 +188,6 @@ suite "IntervalSet: Intervals of FancyPoint entries over FancyScalar":
|
||||||
check ivSet == false
|
check ivSet == false
|
||||||
(ivVal, ivSet) = (iv, true)
|
(ivVal, ivSet) = (iv, true)
|
||||||
check ivVal == iv(uHigh,uHigh)
|
check ivVal == iv(uHigh,uHigh)
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var (ivVal, ivSet) = (iv(0,0), false)
|
var (ivVal, ivSet) = (iv(0,0), false)
|
||||||
for iv in br.decreasing:
|
for iv in br.decreasing:
|
||||||
|
@ -200,6 +200,25 @@ suite "IntervalSet: Intervals of FancyPoint entries over FancyScalar":
|
||||||
check br.merge(1477152,uHigh) == uHigh - 1477151
|
check br.merge(1477152,uHigh) == uHigh - 1477151
|
||||||
check br.merge(1477151,1477151) == 1
|
check br.merge(1477151,1477151) == 1
|
||||||
|
|
||||||
|
br.clear() # from blockchain snap sync odd behaviour
|
||||||
|
check br.merge(0,uHigh) == 0
|
||||||
|
check br.chunks == 1
|
||||||
|
check br.total == 0
|
||||||
|
check br.ge(1000) == ivError
|
||||||
|
check 0 < br.reduce(99999,uHigh-1)
|
||||||
|
check br.ge(1000) == iv(uHigh,uHigh)
|
||||||
|
|
||||||
|
br.clear()
|
||||||
|
check br.merge(0,uHigh) == 0
|
||||||
|
check br.chunks == 1
|
||||||
|
check br.total == 0
|
||||||
|
check br.le(uHigh) == iv(0,uHigh)
|
||||||
|
check br.le(uHigh-1) == ivError
|
||||||
|
check 0 < br.reduce(99999,uHigh-1)
|
||||||
|
check br.le(uHigh) == iv(uHigh,uHigh)
|
||||||
|
check br.le(uHigh-1) == iv(0,99998)
|
||||||
|
check br.le(uHigh-2) == iv(0,99998)
|
||||||
|
|
||||||
test "Merge disjunct intervals on 1st set":
|
test "Merge disjunct intervals on 1st set":
|
||||||
br.clear()
|
br.clear()
|
||||||
check br.merge( 0, 99) == 100
|
check br.merge( 0, 99) == 100
|
||||||
|
|
Loading…
Reference in New Issue