Skip to content

Commit

Permalink
Fix and test detect edges
Browse files Browse the repository at this point in the history
  • Loading branch information
JoelCourtney committed Feb 16, 2024
1 parent 8af0665 commit a460311
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ data class Interval(
fun compareEnds(other: Interval): Int {
val timeComparison: Int = end.compareTo(other.end)
return if (timeComparison != 0) timeComparison
else if (startInclusivity == other.startInclusivity) 0
else if (startInclusivity == Inclusivity.Inclusive) 1
else if (endInclusivity == other.endInclusivity) 0
else if (endInclusivity == Inclusivity.Inclusive) 1
else -1
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface SerialConstantOps<V: Any, THIS: SerialConstantOps<V, THIS>>: SerialOps

/** [(DOC)][notEqualTo] Returns a [Windows] that is `true` when this and another profile are not equal. */
fun <OTHER: SerialConstantOps<V, OTHER>> notEqualTo(other: OTHER) =
map2Values(::Windows, other, BinaryOperation.combineOrNull { l, r, _ -> l == r })
map2Values(::Windows, other, BinaryOperation.combineOrNull { l, r, _ -> l != r })

override fun changes() = detectEdges(BinaryOperation.combineOrNull { l, r, _-> l != r })

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package gov.nasa.jpl.aerie.timeline.ops

import gov.nasa.jpl.aerie.timeline.*
import gov.nasa.jpl.aerie.timeline.Interval.Companion.at
import gov.nasa.jpl.aerie.timeline.collections.profiles.Windows
import gov.nasa.jpl.aerie.timeline.util.coalesceList
import gov.nasa.jpl.aerie.timeline.util.map2Serial
import gov.nasa.jpl.aerie.timeline.util.truncateList

Expand Down Expand Up @@ -108,34 +110,19 @@ interface SerialOps<V : Any, THIS: SerialOps<V, THIS>>: SegmentOps<V, THIS> {
var buffer: Segment<V>? = null
val result = collect(CollectOptions(bounds, false))
.flatMap { currentSegment ->
val leftEdge: Boolean?
val rightEdge: Boolean?

val previous = buffer
buffer = currentSegment
val currentInterval = currentSegment.interval

val leftEdgeInterval = Interval.at(currentInterval.start)
val rightEdgeInterval = Interval.at(currentInterval.end)
val leftEdgeInterval = at(currentInterval.start)
val rightEdgeInterval = at(currentInterval.end)

rightEdge = if (currentInterval.end.isEqualTo(bounds.end) && currentInterval.endInclusivity == bounds.endInclusivity) {
if (bounds.includesEnd()) false else null
} else {
edgePredicate.invoke(currentSegment.value, null, rightEdgeInterval)
}
val rightEdge = edgePredicate(currentSegment.value, null, rightEdgeInterval)

leftEdge = if (previous != null) {
if (previous.interval.compareEndToStart(currentInterval) == 0) {
edgePredicate.invoke(previous.value, currentSegment.value, leftEdgeInterval)
} else {
edgePredicate.invoke(null, currentSegment.value, leftEdgeInterval)
}
val leftEdge = if (previous == null || previous.interval.compareEndToStart(currentInterval) == -1) {
edgePredicate(null, currentSegment.value, leftEdgeInterval)
} else {
if (currentInterval.start.isEqualTo(bounds.start) && currentInterval.startInclusivity == bounds.startInclusivity) {
if (bounds.includesStart()) false else null
} else {
edgePredicate.invoke(null, currentSegment.value, leftEdgeInterval)
}
edgePredicate(previous.value, currentSegment.value, leftEdgeInterval)
}

listOfNotNull(
Expand All @@ -147,7 +134,7 @@ interface SerialOps<V : Any, THIS: SerialOps<V, THIS>>: SegmentOps<V, THIS> {
Segment(rightEdgeInterval, rightEdge).transpose()
)
}
truncateList(result, opts)
truncateList(coalesceList(result, Segment<Boolean>::valueEquals), opts)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class IntervalTest {
assertEquals(1, between(seconds(0), seconds(1)).compareEnds(at(seconds(0))))
assertEquals(-1, between(seconds(0), seconds(1), Exclusive).compareEnds(at(seconds(1))))
assertEquals(0, between(seconds(0), seconds(1)).compareEnds(at(seconds(1))))
assertEquals(-1, betweenClosedOpen(seconds(0), seconds(1)).compareEnds(at(seconds(1))))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gov.nasa.jpl.aerie.timeline.ops

import gov.nasa.jpl.aerie.merlin.protocol.types.Duration
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration.milliseconds
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration.seconds
import gov.nasa.jpl.aerie.timeline.*
import gov.nasa.jpl.aerie.timeline.Interval.Companion.at
Expand All @@ -17,4 +18,36 @@ class SerialOpsTest {

// set, assignGaps, and map2Values are not tested here because they are trivial delegations to map2Serial.
// see Map2SerialTest.kt

@Test
fun detectEdges() {
val result = Discrete(
Segment(betweenClosedOpen(seconds(0), seconds(1)), "hello"),
Segment(between(seconds(1), seconds(2)), "oooo"),
Segment(between(seconds(2), seconds(3), Interval.Inclusivity.Exclusive), "aaaa"),
Segment(between(seconds(5), seconds(6)), "ao")
).detectEdges(BinaryOperation.cases(
{ l, _ -> l.endsWith('o') },
{ r, _ -> r.startsWith('o') },
{ l, r, _ -> l.endsWith(r.first()) }
))

assertIterableEquals(
listOf(
Segment(betweenClosedOpen(seconds(0), seconds(1)), false),
Segment(at(seconds(1)), true),
Segment(between(seconds(1), seconds(3), Interval.Inclusivity.Exclusive, Interval.Inclusivity.Inclusive), false),
Segment(betweenClosedOpen(seconds(5), seconds(6)), false),
Segment(at(seconds(6)), true)
),
result.collect()
)

// collecting on smaller bounds that start in the middle of "oooo" to make sure it does not get truncated
// and count the bounds start as the segment start.
assertIterableEquals(
listOf(Segment(between(milliseconds(1500), seconds(3)), false)),
result.collect(between(milliseconds(1500), seconds(4)))
)
}
}

0 comments on commit a460311

Please sign in to comment.