Skip to content

Commit 1c3a7db

Browse files
committed
fix bug by canonicalizing to closed-closed
1 parent 260544f commit 1c3a7db

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

src/interop.jl

+30-22
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@
22
##### Intervals -> AlignedSpan
33
#####
44

5-
is_start_exclusive(::Interval{T,L,R}) where {T,L,R} = L == Open
6-
is_stop_exclusive(::Interval{T,L,R}) where {T,L,R} = R == Open
7-
85
# Interface methods:
96
duration(interval::Interval{<:TimePeriod}) = last(interval) - first(interval)
107

11-
function start_index_from_time(sample_rate, interval::Interval,
8+
function start_index_from_time(sample_rate, interval::Interval{Nanosecond,Closed,Closed},
129
mode::Union{RoundingMode{:Up},RoundingMode{:Down}})
13-
first_index, err = index_and_error_from_time(sample_rate, first(interval), mode)
14-
if is_start_exclusive(interval) && mode == RoundUp && iszero(err)
15-
first_index += 1
16-
end
10+
first_index, _ = index_and_error_from_time(sample_rate, first(interval), mode)
1711

1812
if mode == RoundUp
1913
t = time_from_index(sample_rate, first_index)
@@ -23,6 +17,9 @@ function start_index_from_time(sample_rate, interval::Interval,
2317
msg = """
2418
[AlignedSpans] Unexpected error in `start_index_from_time`:
2519
20+
- `sample_rate = $(sample_rate)`
21+
- `interval = $(interval)`
22+
- `mode = $(mode)`
2623
- `time_from_index(sample_rate, first_index) = $(t)`
2724
- `first(interval) = $(first(interval))`
2825
- Expected `time_from_index(sample_rate, first_index) >= first(interval)`
@@ -33,28 +30,28 @@ function start_index_from_time(sample_rate, interval::Interval,
3330
if ASSERTS_ON[]
3431
error(msg)
3532
else
36-
@warn msg
33+
@warn msg maxlog = 100
3734
end
3835
end
3936
end
4037
return first_index
4138
end
4239

43-
function stop_index_from_time(sample_rate, interval::Interval,
40+
function stop_index_from_time(sample_rate, interval::Interval{Nanosecond,Closed,Closed},
4441
mode::Union{RoundingMode{:Up},RoundingMode{:Down}})
45-
last_index, err = index_and_error_from_time(sample_rate, last(interval), mode)
46-
if is_stop_exclusive(interval) && mode == RoundDown && iszero(err)
47-
last_index -= 1
48-
end
42+
last_index, _ = index_and_error_from_time(sample_rate, last(interval), mode)
4943

5044
if mode == RoundDown
5145
t = time_from_index(sample_rate, last_index)
5246
# this should *always* be true by construction, and we promise it in the docstring.
53-
# let's add an check to verify.
54-
if !(t <= last(interval))
47+
# let's add an check to verify. Note here we add 1ns to make it an open span again, since we've converted to closed
48+
if !(t <= last(interval) + Nanosecond(1))
5549
msg = """
5650
[AlignedSpans] Unexpected error in `stop_index_from_time`:
5751
52+
- `sample_rate = $(sample_rate)`
53+
- `interval = $(interval)`
54+
- `mode = $(mode)`
5855
- `time_from_index(sample_rate, last_index) = $(t)`
5956
- `last(interval) = $(last(interval))`
6057
- Expected `time_from_index(sample_rate, last_index) <= last(interval)`
@@ -65,15 +62,15 @@ function stop_index_from_time(sample_rate, interval::Interval,
6562
if ASSERTS_ON[]
6663
error(msg)
6764
else
68-
@warn msg
65+
@warn msg maxlog = 100
6966
end
7067
end
7168
end
7269
return last_index
7370
end
7471

75-
function stop_index_from_time(sample_rate, interval::Interval,
76-
::RoundingModeFullyContainedSampleSpans)
72+
function stop_index_from_time(sample_rate, interval::Interval{Nanosecond,Closed,Closed},
73+
mode::RoundingModeFullyContainedSampleSpans)
7774
# here we are in `RoundingModeFullyContainedSampleSpans` which means we treat each sample
7875
# as a closed-open span starting from each sample to just before the next sample,
7976
# and we are trying to round down to the last fully-enclosed sample span
@@ -94,6 +91,9 @@ function stop_index_from_time(sample_rate, interval::Interval,
9491
msg = """
9592
[AlignedSpans] Unexpected error in `stop_index_from_time` with `RoundFullyContainedSampleSpans`:
9693
94+
- `sample_rate = $(sample_rate)`
95+
- `interval = $(interval)`
96+
- `mode = $(mode)`
9797
- `end_of_span_time = $(end_of_span_time)`
9898
- `interval = $(interval)`
9999
- Expected `end_of_span_time in interval`
@@ -103,7 +103,7 @@ function stop_index_from_time(sample_rate, interval::Interval,
103103
if ASSERTS_ON[]
104104
error(msg)
105105
else
106-
@warn msg
106+
@warn msg maxlog = 100
107107
end
108108
end
109109

@@ -129,8 +129,16 @@ TimeSpans.start(span::AlignedSpan) = time_from_index(span.sample_rate, span.firs
129129
TimeSpans.stop(span::AlignedSpan) = time_from_index(span.sample_rate, span.last_index + 1)
130130

131131
# TimeSpan -> AlignedSpan is supported by passing to Intervals
132-
to_interval(span) = Interval{Nanosecond,Closed,Open}(start(span), stop(span))
133-
to_interval(span::Interval) = span
132+
function to_interval(span)
133+
# we could return clopen intervals, but it's easier to work with closed-closed ones
134+
# Interval{Nanosecond,Closed,Open}(start(span), stop(span))
135+
# convert from open endpoint to closed by removing last ns
136+
return Interval{Nanosecond,Closed,Closed}(start(span), stop(span) - Nanosecond(1))
137+
end
138+
to_interval(span::Interval{Nanosecond,Closed,Closed}) = span
139+
function to_interval(span::Interval{Nanosecond,Closed,Open})
140+
return Interval{Nanosecond,Closed,Closed}(first(span), last(span) - Nanosecond(1))
141+
end
134142

135143
# Interface methods:
136144

test/time_index_conversions.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ end
3636
# Check against `stop_index_from_time`. Note here we add 1ns bc on the left-hand side, `index`
3737
# is computed as the last sample that has occurred before or at `sample_time`, so when translated
3838
# into timespans, we want an inclusive right endpoint
39-
# @test index ==
40-
# AlignedSpans.stop_index_from_time(rate,
41-
# Interval{Nanosecond,Closed,Closed}(Nanosecond(0),
42-
# sample_time),
43-
# RoundDown)[1]
39+
@test index ==
40+
AlignedSpans.stop_index_from_time(rate,
41+
Interval{Nanosecond,Closed,Closed}(Nanosecond(0),
42+
sample_time),
43+
RoundDown)[1]
4444
# for TimeSpans, we add 1 to be inclusive
4545
@test index ==
4646
AlignedSpans.stop_index_from_time(rate,

0 commit comments

Comments
 (0)