aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYang Song <songy23@users.noreply.github.com>2017-09-04 14:52:57 -0700
committerGitHub <noreply@github.com>2017-09-04 14:52:57 -0700
commit8b19f6e3a6cf88ee2661df86e2415cea8fee0609 (patch)
tree9e836cb7c76c3889a3146785c4e06f6d56b98f50
parente24096c600bd57969a38099c36abeca72f2aa517 (diff)
downloadplatform_external_opencensus-java-8b19f6e3a6cf88ee2661df86e2415cea8fee0609.tar.gz
platform_external_opencensus-java-8b19f6e3a6cf88ee2661df86e2415cea8fee0609.tar.bz2
platform_external_opencensus-java-8b19f6e3a6cf88ee2661df86e2415cea8fee0609.zip
Add IntervalBucket and tests. (#537)
-rw-r--r--api/src/main/java/io/opencensus/common/Duration.java1
-rw-r--r--core_impl/src/main/java/io/opencensus/implcore/stats/IntervalBucket.java82
-rw-r--r--core_impl/src/test/java/io/opencensus/implcore/stats/IntervalBucketTest.java137
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin54712 -> 54712 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties2
5 files changed, 221 insertions, 1 deletions
diff --git a/api/src/main/java/io/opencensus/common/Duration.java b/api/src/main/java/io/opencensus/common/Duration.java
index e355d7ed..b69416e8 100644
--- a/api/src/main/java/io/opencensus/common/Duration.java
+++ b/api/src/main/java/io/opencensus/common/Duration.java
@@ -31,6 +31,7 @@ import javax.annotation.concurrent.Immutable;
*/
@Immutable
@AutoValue
+// TODO(songya): implements Comparable<Duration>
public abstract class Duration {
private static final Duration ZERO = create(0, 0);
diff --git a/core_impl/src/main/java/io/opencensus/implcore/stats/IntervalBucket.java b/core_impl/src/main/java/io/opencensus/implcore/stats/IntervalBucket.java
new file mode 100644
index 00000000..9d8c96be
--- /dev/null
+++ b/core_impl/src/main/java/io/opencensus/implcore/stats/IntervalBucket.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.implcore.stats;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static io.opencensus.implcore.stats.MutableViewData.toMillis;
+
+import com.google.common.collect.Maps;
+import io.opencensus.common.Duration;
+import io.opencensus.common.Timestamp;
+import io.opencensus.stats.Aggregation;
+import io.opencensus.tags.TagValue;
+import java.util.List;
+import java.util.Map;
+
+/** The bucket with aggregated {@code MeasureValue}s used for {@code IntervalViewData}. */
+final class IntervalBucket {
+
+ private final Timestamp start;
+ private final Duration duration;
+ private final List<Aggregation> aggregations;
+ private final Map<List<TagValue>, List<MutableAggregation>> tagValueAggregationMap =
+ Maps.newHashMap();
+
+ IntervalBucket(Timestamp start, Duration duration, List<Aggregation> aggregations) {
+ checkNotNull(start, "Start");
+ checkNotNull(duration, "Duration");
+ checkNotNull(aggregations, "Aggregations");
+ this.start = start;
+ this.duration = duration;
+ this.aggregations = aggregations;
+ }
+
+ Map<List<TagValue>, List<MutableAggregation>> getTagValueAggregationMap() {
+ return tagValueAggregationMap;
+ }
+
+ Timestamp getStart() {
+ return start;
+ }
+
+ // Puts a new value into the internal MutableAggregations, based on the TagValues.
+ void record(List<TagValue> tagValues, double value) {
+ if (!tagValueAggregationMap.containsKey(tagValues)) {
+ tagValueAggregationMap.put(
+ tagValues, MutableViewData.createMutableAggregations(aggregations));
+ }
+ for (MutableAggregation aggregation : tagValueAggregationMap.get(tagValues)) {
+ aggregation.add(value);
+ }
+ }
+
+ /*
+ * Returns how much fraction of duration has passed in this IntervalBucket. For example, if this
+ * bucket starts at 10s and has a duration of 20s, and now is 15s, then getFraction() should
+ * return (15 - 10) / 20 = 0.25.
+ *
+ * This IntervalBucket must be current, i.e. the current timestamp must be within
+ * [this.start, this.start + this.duration).
+ */
+ double getFraction(Timestamp now) {
+ Duration elapsedTime = now.subtractTimestamp(start);
+ checkArgument(toMillis(elapsedTime) >= 0 && toMillis(elapsedTime) < toMillis(duration),
+ "This bucket must be current.");
+ return ((double) toMillis(elapsedTime)) / toMillis(duration);
+ }
+}
diff --git a/core_impl/src/test/java/io/opencensus/implcore/stats/IntervalBucketTest.java b/core_impl/src/test/java/io/opencensus/implcore/stats/IntervalBucketTest.java
new file mode 100644
index 00000000..0eaf08f8
--- /dev/null
+++ b/core_impl/src/test/java/io/opencensus/implcore/stats/IntervalBucketTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.opencensus.implcore.stats;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import io.opencensus.common.Duration;
+import io.opencensus.common.Timestamp;
+import io.opencensus.implcore.stats.MutableAggregation.MutableCount;
+import io.opencensus.implcore.stats.MutableAggregation.MutableHistogram;
+import io.opencensus.implcore.stats.MutableAggregation.MutableSum;
+import io.opencensus.stats.Aggregation;
+import io.opencensus.stats.Aggregation.Count;
+import io.opencensus.stats.Aggregation.Histogram;
+import io.opencensus.stats.Aggregation.Sum;
+import io.opencensus.stats.BucketBoundaries;
+import io.opencensus.tags.TagValue;
+import io.opencensus.tags.TagValue.TagValueString;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link IntervalBucket}. */
+@RunWith(JUnit4.class)
+public class IntervalBucketTest {
+
+ @Rule public final ExpectedException thrown = ExpectedException.none();
+
+ private static final double TOLERANCE = 1e-6;
+ private static final Duration MINUTE = Duration.create(60, 0);
+ private static final Timestamp START = Timestamp.create(60, 0);
+ private static final BucketBoundaries BUCKET_BOUNDARIES =
+ BucketBoundaries.create(Arrays.asList(-10.0, 0.0, 10.0));
+ private static final List<Aggregation> AGGREGATIONS_V1 =
+ Collections.unmodifiableList(Arrays.asList(
+ Sum.create(), Count.create(), Histogram.create(BUCKET_BOUNDARIES)));
+
+ @Test
+ public void preventNullStartTime() {
+ thrown.expect(NullPointerException.class);
+ new IntervalBucket(null, MINUTE, AGGREGATIONS_V1);
+ }
+
+ @Test
+ public void preventNullDuration() {
+ thrown.expect(NullPointerException.class);
+ new IntervalBucket(START, null, AGGREGATIONS_V1);
+ }
+
+ @Test
+ public void preventNullAggregationList() {
+ thrown.expect(NullPointerException.class);
+ new IntervalBucket(START, MINUTE, null);
+ }
+
+ @Test
+ public void testGetTagValueAggregationMap_empty() {
+ assertThat(new IntervalBucket(START, MINUTE, AGGREGATIONS_V1).getTagValueAggregationMap())
+ .isEmpty();
+ }
+
+ @Test
+ public void testGetStart() {
+ assertThat(new IntervalBucket(START, MINUTE, AGGREGATIONS_V1).getStart()).isEqualTo(START);
+ }
+
+ @Test
+ public void testRecord() {
+ IntervalBucket bucket = new IntervalBucket(START, MINUTE, AGGREGATIONS_V1);
+ List<TagValue> tagValues1 = Arrays.<TagValue>asList(TagValueString.create("VALUE1"));
+ List<TagValue> tagValues2 = Arrays.<TagValue>asList(TagValueString.create("VALUE2"));
+ bucket.record(tagValues1, 5.0);
+ bucket.record(tagValues1, 15.0);
+ bucket.record(tagValues2, 10.0);
+ assertThat(bucket.getTagValueAggregationMap()).containsKey(tagValues1);
+ verifyMutableAggregations(bucket.getTagValueAggregationMap().get(tagValues1),
+ 20.0, 2, new long[]{0, 0, 1, 1}, TOLERANCE);
+ assertThat(bucket.getTagValueAggregationMap()).containsKey(tagValues2);
+ verifyMutableAggregations(bucket.getTagValueAggregationMap().get(tagValues2),
+ 10.0, 1, new long[]{0, 0, 0, 1}, TOLERANCE);
+ }
+
+ private static void verifyMutableAggregations(
+ List<MutableAggregation> aggregations, double sum, long count, long[] bucketCounts,
+ double tolerance) {
+ assertThat(aggregations).hasSize(3);
+ assertThat(aggregations.get(0)).isInstanceOf(MutableSum.class);
+ assertThat(((MutableSum) aggregations.get(0)).getSum()).isWithin(tolerance).of(sum);
+ assertThat(aggregations.get(1)).isInstanceOf(MutableCount.class);
+ assertThat(((MutableCount) aggregations.get(1)).getCount()).isEqualTo(count);
+ assertThat(aggregations.get(2)).isInstanceOf(MutableHistogram.class);
+ assertThat(((MutableHistogram) aggregations.get(2)).getBucketCounts()).isEqualTo(bucketCounts);
+ }
+
+ @Test
+ public void testGetFraction() {
+ Timestamp thirtySecondsAfterStart = Timestamp.create(90, 0);
+ assertThat(
+ new IntervalBucket(START, MINUTE, AGGREGATIONS_V1).getFraction(thirtySecondsAfterStart))
+ .isWithin(TOLERANCE).of(0.5);
+ }
+
+ @Test
+ public void preventCallingGetFractionOnPastBuckets() {
+ IntervalBucket bucket = new IntervalBucket(START, MINUTE, AGGREGATIONS_V1);
+ Timestamp twoMinutesAfterStart = Timestamp.create(180, 0);
+ thrown.expect(IllegalArgumentException.class);
+ bucket.getFraction(twoMinutesAfterStart);
+ }
+
+ @Test
+ public void preventCallingGetFractionOnFutureBuckets() {
+ IntervalBucket bucket = new IntervalBucket(START, MINUTE, AGGREGATIONS_V1);
+ Timestamp thirtySecondsBeforeStart = Timestamp.create(30, 0);
+ thrown.expect(IllegalArgumentException.class);
+ bucket.getFraction(thirtySecondsBeforeStart);
+ }
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index cb893cbb..480539d4 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1b1cd980..fc5988a7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Tue Jul 11 16:36:46 PDT 2017
+#Sun Sep 03 20:39:13 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME