Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 36a87b8

Browse files
authored
Implement Duration.compareTo() (#582)
* Update Duration.compareTo() * Add check for negative duration for interval
1 parent 67528c1 commit 36a87b8

File tree

9 files changed

+64
-10
lines changed

9 files changed

+64
-10
lines changed

api/src/main/java/io/opencensus/common/Duration.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static io.opencensus.common.TimeUtil.NANOS_PER_MILLI;
2323

2424
import com.google.auto.value.AutoValue;
25+
import com.google.common.primitives.Longs;
2526
import javax.annotation.concurrent.Immutable;
2627

2728
/**
@@ -31,8 +32,7 @@
3132
*/
3233
@Immutable
3334
@AutoValue
34-
// TODO(songya): implements Comparable<Duration>
35-
public abstract class Duration {
35+
public abstract class Duration implements Comparable<Duration> {
3636
private static final Duration ZERO = create(0, 0);
3737

3838
/**
@@ -88,5 +88,22 @@ public static Duration fromMillis(long millis) {
8888
*/
8989
public abstract int getNanos();
9090

91+
/**
92+
* Compares this {@code Duration} to the specified {@code Duration}.
93+
*
94+
* @param otherDuration the other {@code Duration} to compare to, not {@code null}.
95+
* @return the comparator value: zero if equal, negative if this duration is smaller
96+
* than otherDuration, positive if larger.
97+
* @throws NullPointerException if otherDuration is {@code null}.
98+
*/
99+
@Override
100+
public int compareTo(Duration otherDuration) {
101+
int cmp = Longs.compare(getSeconds(), otherDuration.getSeconds());
102+
if (cmp != 0) {
103+
return cmp;
104+
}
105+
return Longs.compare(getNanos(), otherDuration.getNanos());
106+
}
107+
91108
Duration() {}
92109
}

api/src/main/java/io/opencensus/common/TimeUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package io.opencensus.common;
1818

19-
/** Created by bdrutu on 6/14/17. */
19+
/** Util class for {@link Timestamp} and {@link Duration}. */
2020
final class TimeUtil {
2121
static final long MAX_SECONDS = 315576000000L;
2222
static final int MAX_NANOS = 999999999;

api/src/main/java/io/opencensus/common/Timestamp.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.google.auto.value.AutoValue;
2626
import com.google.common.math.LongMath;
27+
import com.google.common.primitives.Longs;
2728
import java.math.RoundingMode;
2829
import javax.annotation.concurrent.Immutable;
2930

@@ -143,15 +144,11 @@ public Duration subtractTimestamp(Timestamp timestamp) {
143144
*/
144145
@Override
145146
public int compareTo(Timestamp otherTimestamp) {
146-
int cmp = compareLong(getSeconds(), otherTimestamp.getSeconds());
147+
int cmp = Longs.compare(getSeconds(), otherTimestamp.getSeconds());
147148
if (cmp != 0) {
148149
return cmp;
149150
}
150-
return compareLong(getNanos(), otherTimestamp.getNanos());
151-
}
152-
153-
private static int compareLong(long x, long y) {
154-
return (x < y) ? -1 : ((x == y) ? 0 : 1);
151+
return Longs.compare(getNanos(), otherTimestamp.getNanos());
155152
}
156153

157154
// Returns a Timestamp with the specified duration added.

api/src/test/java/io/opencensus/common/DurationTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ public void testDurationFromMillisNegative() {
6262
assertThat(Duration.fromMillis(-3456)).isEqualTo(Duration.create(-3, -456000000));
6363
}
6464

65+
@Test
66+
public void duration_CompareLength() {
67+
assertThat(Duration.create(0, 0).compareTo(Duration.create(0, 0))).isEqualTo(0);
68+
assertThat(Duration.create(24, 42).compareTo(Duration.create(24, 42))).isEqualTo(0);
69+
assertThat(Duration.create(-24, -42).compareTo(Duration.create(-24, -42))).isEqualTo(0);
70+
assertThat(Duration.create(25, 42).compareTo(Duration.create(24, 42))).isEqualTo(1);
71+
assertThat(Duration.create(24, 45).compareTo(Duration.create(24, 42))).isEqualTo(1);
72+
assertThat(Duration.create(24, 42).compareTo(Duration.create(25, 42))).isEqualTo(-1);
73+
assertThat(Duration.create(24, 42).compareTo(Duration.create(24, 45))).isEqualTo(-1);
74+
assertThat(Duration.create(-24, -45).compareTo(Duration.create(-24, -42))).isEqualTo(-1);
75+
assertThat(Duration.create(-24, -42).compareTo(Duration.create(-25, -42))).isEqualTo(1);
76+
assertThat(Duration.create(24, 42).compareTo(Duration.create(-24, -42))).isEqualTo(1);
77+
78+
}
79+
6580
@Test
6681
public void testDurationEqual() {
6782
// Positive tests.

core/src/main/java/io/opencensus/stats/View.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ public final <T> T match(
195195
@AutoValue
196196
public abstract static class Interval extends AggregationWindow {
197197

198+
private static final Duration ZERO = Duration.create(0, 0);
199+
198200
Interval() {}
199201

200202
/**
@@ -215,6 +217,7 @@ public abstract static class Interval extends AggregationWindow {
215217
* @return an interval {@code AggregationWindow}.
216218
*/
217219
public static Interval create(Duration duration) {
220+
checkArgument(duration.compareTo(ZERO) > 0, "Duration must be positive");
218221
return new AutoValue_View_AggregationWindow_Interval(duration);
219222
}
220223

core/src/test/java/io/opencensus/stats/ViewTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ public void preventNullNameString() {
140140
View.Name.create(null);
141141
}
142142

143+
@Test(expected = IllegalArgumentException.class)
144+
public void preventNegativeIntervalDuration() {
145+
Interval.create(negativeTenSeconds);
146+
}
147+
143148
@Test
144149
public void testViewNameEquals() {
145150
new EqualsTester()
@@ -159,4 +164,5 @@ public void testViewNameEquals() {
159164
private final List<Aggregation> aggregations = Arrays.asList(Sum.create(), Count.create());
160165
private final Duration minute = Duration.create(60, 0);
161166
private final Duration twoMinutes = Duration.create(120, 0);
167+
private final Duration negativeTenSeconds = Duration.create(-10, 0);
162168
}

core_impl/src/main/java/io/opencensus/implcore/stats/IntervalBucket.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
/** The bucket with aggregated {@code MeasureValue}s used for {@code IntervalViewData}. */
3232
final class IntervalBucket {
3333

34+
private static final Duration ZERO = Duration.create(0, 0);
35+
3436
private final Timestamp start;
3537
private final Duration duration;
3638
private final List<Aggregation> aggregations;
@@ -40,6 +42,7 @@ final class IntervalBucket {
4042
IntervalBucket(Timestamp start, Duration duration, List<Aggregation> aggregations) {
4143
checkNotNull(start, "Start");
4244
checkNotNull(duration, "Duration");
45+
checkArgument(duration.compareTo(ZERO) > 0, "Duration must be positive");
4346
checkNotNull(aggregations, "Aggregations");
4447
this.start = start;
4548
this.duration = duration;
@@ -75,7 +78,7 @@ void record(List<TagValue> tagValues, double value) {
7578
*/
7679
double getFraction(Timestamp now) {
7780
Duration elapsedTime = now.subtractTimestamp(start);
78-
checkArgument(toMillis(elapsedTime) >= 0 && toMillis(elapsedTime) < toMillis(duration),
81+
checkArgument(elapsedTime.compareTo(ZERO) >= 0 && elapsedTime.compareTo(duration) < 0,
7982
"This bucket must be current.");
8083
return ((double) toMillis(elapsedTime)) / toMillis(duration);
8184
}

core_impl/src/test/java/io/opencensus/implcore/stats/IntervalBucketTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class IntervalBucketTest {
4747

4848
private static final double TOLERANCE = 1e-6;
4949
private static final Duration MINUTE = Duration.create(60, 0);
50+
private static final Duration NEGATIVE_TEN_SEC = Duration.create(-10, 0);
5051
private static final Timestamp START = Timestamp.create(60, 0);
5152
private static final BucketBoundaries BUCKET_BOUNDARIES =
5253
BucketBoundaries.create(Arrays.asList(-10.0, 0.0, 10.0));
@@ -66,6 +67,12 @@ public void preventNullDuration() {
6667
new IntervalBucket(START, null, AGGREGATIONS_V1);
6768
}
6869

70+
@Test
71+
public void preventNegativeDuration() {
72+
thrown.expect(IllegalArgumentException.class);
73+
new IntervalBucket(START, NEGATIVE_TEN_SEC, AGGREGATIONS_V1);
74+
}
75+
6976
@Test
7077
public void preventNullAggregationList() {
7178
thrown.expect(NullPointerException.class);

findbugs-exclude.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,11 @@
1111
<Class name="io.opencensus.common.Timestamp" />
1212
<Method name="compareTo" />
1313
</Match>
14+
<Match>
15+
<!-- Reason: Equal is implemented in the AutoValue generated class. -->
16+
<Bug pattern="EQ_COMPARETO_USE_OBJECT_EQUALS"/>
17+
<Class name="io.opencensus.common.Duration" />
18+
<Method name="compareTo" />
19+
</Match>
1420

1521
</FindBugsFilter>

0 commit comments

Comments
 (0)