aboutsummaryrefslogtreecommitdiff
path: root/api/src/main/java/io/opencensus/stats/NoopStats.java
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/main/java/io/opencensus/stats/NoopStats.java')
-rw-r--r--api/src/main/java/io/opencensus/stats/NoopStats.java221
1 files changed, 221 insertions, 0 deletions
diff --git a/api/src/main/java/io/opencensus/stats/NoopStats.java b/api/src/main/java/io/opencensus/stats/NoopStats.java
new file mode 100644
index 00000000..e7e94a38
--- /dev/null
+++ b/api/src/main/java/io/opencensus/stats/NoopStats.java
@@ -0,0 +1,221 @@
+/*
+ * 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.stats;
+
+import io.opencensus.common.Functions;
+import io.opencensus.common.Timestamp;
+import io.opencensus.internal.Utils;
+import io.opencensus.stats.Measure.MeasureDouble;
+import io.opencensus.stats.Measure.MeasureLong;
+import io.opencensus.tags.TagContext;
+import io.opencensus.tags.TagValue;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.Immutable;
+import javax.annotation.concurrent.ThreadSafe;
+
+/*>>>
+import org.checkerframework.checker.nullness.qual.Nullable;
+*/
+
+/** No-op implementations of stats classes. */
+final class NoopStats {
+
+ private NoopStats() {}
+
+ /**
+ * Returns a {@code StatsComponent} that has a no-op implementation for {@link StatsRecorder}.
+ *
+ * @return a {@code StatsComponent} that has a no-op implementation for {@code StatsRecorder}.
+ */
+ static StatsComponent newNoopStatsComponent() {
+ return new NoopStatsComponent();
+ }
+
+ /**
+ * Returns a {@code StatsRecorder} that does not record any data.
+ *
+ * @return a {@code StatsRecorder} that does not record any data.
+ */
+ static StatsRecorder getNoopStatsRecorder() {
+ return NoopStatsRecorder.INSTANCE;
+ }
+
+ /**
+ * Returns a {@code MeasureMap} that ignores all calls to {@link MeasureMap#put}.
+ *
+ * @return a {@code MeasureMap} that ignores all calls to {@code MeasureMap#put}.
+ */
+ static MeasureMap getNoopMeasureMap() {
+ return NoopMeasureMap.INSTANCE;
+ }
+
+ /**
+ * Returns a {@code ViewManager} that maintains a map of views, but always returns empty {@link
+ * ViewData}s.
+ *
+ * @return a {@code ViewManager} that maintains a map of views, but always returns empty {@code
+ * ViewData}s.
+ */
+ static ViewManager newNoopViewManager() {
+ return new NoopViewManager();
+ }
+
+ @ThreadSafe
+ private static final class NoopStatsComponent extends StatsComponent {
+ private final ViewManager viewManager = newNoopViewManager();
+ private volatile boolean isRead;
+
+ @Override
+ public ViewManager getViewManager() {
+ return viewManager;
+ }
+
+ @Override
+ public StatsRecorder getStatsRecorder() {
+ return getNoopStatsRecorder();
+ }
+
+ @Override
+ public StatsCollectionState getState() {
+ isRead = true;
+ return StatsCollectionState.DISABLED;
+ }
+
+ @Override
+ @Deprecated
+ public void setState(StatsCollectionState state) {
+ Utils.checkNotNull(state, "state");
+ Utils.checkState(!isRead, "State was already read, cannot set state.");
+ }
+ }
+
+ @Immutable
+ private static final class NoopStatsRecorder extends StatsRecorder {
+ static final StatsRecorder INSTANCE = new NoopStatsRecorder();
+
+ @Override
+ public MeasureMap newMeasureMap() {
+ return getNoopMeasureMap();
+ }
+ }
+
+ @Immutable
+ private static final class NoopMeasureMap extends MeasureMap {
+ static final MeasureMap INSTANCE = new NoopMeasureMap();
+
+ @Override
+ public MeasureMap put(MeasureDouble measure, double value) {
+ return this;
+ }
+
+ @Override
+ public MeasureMap put(MeasureLong measure, long value) {
+ return this;
+ }
+
+ @Override
+ public void record() {}
+
+ @Override
+ public void record(TagContext tags) {
+ Utils.checkNotNull(tags, "tags");
+ }
+ }
+
+ @ThreadSafe
+ private static final class NoopViewManager extends ViewManager {
+ private static final Timestamp ZERO_TIMESTAMP = Timestamp.create(0, 0);
+
+ @GuardedBy("registeredViews")
+ private final Map<View.Name, View> registeredViews = new HashMap<View.Name, View>();
+
+ // Cached set of exported views. It must be set to null whenever a view is registered or
+ // unregistered.
+ @javax.annotation.Nullable private volatile Set<View> exportedViews;
+
+ @Override
+ public void registerView(View newView) {
+ Utils.checkNotNull(newView, "newView");
+ synchronized (registeredViews) {
+ exportedViews = null;
+ View existing = registeredViews.get(newView.getName());
+ Utils.checkArgument(
+ existing == null || newView.equals(existing),
+ "A different view with the same name already exists.");
+ if (existing == null) {
+ registeredViews.put(newView.getName(), newView);
+ }
+ }
+ }
+
+ @Override
+ @javax.annotation.Nullable
+ @SuppressWarnings("deprecation")
+ public ViewData getView(View.Name name) {
+ Utils.checkNotNull(name, "name");
+ synchronized (registeredViews) {
+ View view = registeredViews.get(name);
+ if (view == null) {
+ return null;
+ } else {
+ return ViewData.create(
+ view,
+ Collections.<List</*@Nullable*/ TagValue>, AggregationData>emptyMap(),
+ view.getWindow()
+ .match(
+ Functions.<ViewData.AggregationWindowData>returnConstant(
+ ViewData.AggregationWindowData.CumulativeData.create(
+ ZERO_TIMESTAMP, ZERO_TIMESTAMP)),
+ Functions.<ViewData.AggregationWindowData>returnConstant(
+ ViewData.AggregationWindowData.IntervalData.create(ZERO_TIMESTAMP)),
+ Functions.<ViewData.AggregationWindowData>throwAssertionError()));
+ }
+ }
+ }
+
+ @Override
+ public Set<View> getAllExportedViews() {
+ Set<View> views = exportedViews;
+ if (views == null) {
+ synchronized (registeredViews) {
+ exportedViews = views = filterExportedViews(registeredViews.values());
+ }
+ }
+ return views;
+ }
+
+ // Returns the subset of the given views that should be exported
+ @SuppressWarnings("deprecation")
+ private static Set<View> filterExportedViews(Collection<View> allViews) {
+ Set<View> views = new HashSet<View>();
+ for (View view : allViews) {
+ if (view.getWindow() instanceof View.AggregationWindow.Interval) {
+ continue;
+ }
+ views.add(view);
+ }
+ return Collections.unmodifiableSet(views);
+ }
+ }
+}