Flavio Castro
Committed by Gerrit Code Review

ONOS-2456 Added usage metrics to Atomic Counter and Distributed Queue plus refactored the code a bit

Refactored code plus instrumented AtomicValue and DistributedSet

Change-Id: I9c5f7c9f23d530131f15d3c98250ea33238dd2ec
Showing 18 changed files with 452 additions and 148 deletions
...@@ -59,6 +59,14 @@ public interface AtomicCounterBuilder { ...@@ -59,6 +59,14 @@ public interface AtomicCounterBuilder {
59 AtomicCounterBuilder withRetryOnFailure(); 59 AtomicCounterBuilder withRetryOnFailure();
60 60
61 /** 61 /**
62 + * Instantiates Metering service to gather usage and performance metrics.
63 + * By default, usage data will be stored.
64 + *
65 + * @return this AtomicCounterBuilder
66 + */
67 + AtomicCounterBuilder withMeteringDisabled();
68 +
69 + /**
62 * Sets the executor service to use for retrying failed operations. 70 * Sets the executor service to use for retrying failed operations.
63 * <p> 71 * <p>
64 * Note: Must be set when retries are enabled 72 * Note: Must be set when retries are enabled
......
...@@ -60,6 +60,14 @@ public interface AtomicValueBuilder<V> { ...@@ -60,6 +60,14 @@ public interface AtomicValueBuilder<V> {
60 AtomicValueBuilder<V> withPartitionsDisabled(); 60 AtomicValueBuilder<V> withPartitionsDisabled();
61 61
62 /** 62 /**
63 + * Instantiates Metering service to gather usage and performance metrics.
64 + * By default, usage data will be stored.
65 + *
66 + * @return this AtomicValueBuilder for method chaining
67 + */
68 + AtomicValueBuilder<V> withMeteringDisabled();
69 +
70 + /**
63 * Builds a AtomicValue based on the configuration options 71 * Builds a AtomicValue based on the configuration options
64 * supplied to this builder. 72 * supplied to this builder.
65 * 73 *
......
...@@ -105,6 +105,14 @@ public interface ConsistentMapBuilder<K, V> { ...@@ -105,6 +105,14 @@ public interface ConsistentMapBuilder<K, V> {
105 ConsistentMapBuilder<K, V> withPurgeOnUninstall(); 105 ConsistentMapBuilder<K, V> withPurgeOnUninstall();
106 106
107 /** 107 /**
108 + * Instantiates Metering service to gather usage and performance metrics.
109 + * By default, usage data will be stored.
110 + *
111 + * @return this ConsistentMapBuilder
112 + */
113 + ConsistentMapBuilder<K, V> withMeteringDisabled();
114 +
115 + /**
108 * Builds an consistent map based on the configuration options 116 * Builds an consistent map based on the configuration options
109 * supplied to this builder. 117 * supplied to this builder.
110 * 118 *
......
...@@ -51,6 +51,14 @@ public interface DistributedQueueBuilder<E> { ...@@ -51,6 +51,14 @@ public interface DistributedQueueBuilder<E> {
51 DistributedQueueBuilder<E> withSerializer(Serializer serializer); 51 DistributedQueueBuilder<E> withSerializer(Serializer serializer);
52 52
53 /** 53 /**
54 + *
55 + *
56 + * @return this DistributedQueueBuilder for method chaining
57 + */
58 + DistributedQueueBuilder<E> withMeteringDisabled();
59 +
60 +
61 + /**
54 * Disables persistence of queues entries. 62 * Disables persistence of queues entries.
55 * <p> 63 * <p>
56 * When persistence is disabled, a full cluster restart will wipe out all 64 * When persistence is disabled, a full cluster restart will wipe out all
......
...@@ -92,6 +92,13 @@ public interface DistributedSetBuilder<E> { ...@@ -92,6 +92,13 @@ public interface DistributedSetBuilder<E> {
92 DistributedSetBuilder<E> withPartitionsDisabled(); 92 DistributedSetBuilder<E> withPartitionsDisabled();
93 93
94 /** 94 /**
95 + * Instantiate Metrics service to gather usage and performance metrics.
96 + * By default usage information is enabled
97 + * @return this DistributedSetBuilder
98 + */
99 + DistributedSetBuilder<E> withMeteringDisabled();
100 +
101 + /**
95 * Purges set contents when the application owning the set is uninstalled. 102 * Purges set contents when the application owning the set is uninstalled.
96 * <p> 103 * <p>
97 * When this option is enabled, the caller must provide a applicationId via 104 * When this option is enabled, the caller must provide a applicationId via
......
...@@ -247,6 +247,11 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> { ...@@ -247,6 +247,11 @@ public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
247 } 247 }
248 248
249 @Override 249 @Override
250 + public ConsistentMapBuilder<K, V> withMeteringDisabled() {
251 + return this;
252 + }
253 +
254 + @Override
250 public ConsistentMap<K, V> build() { 255 public ConsistentMap<K, V> build() {
251 return new TestConsistentMap<>(mapName); 256 return new TestConsistentMap<>(mapName);
252 } 257 }
......
...@@ -15,20 +15,15 @@ ...@@ -15,20 +15,15 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 +import org.onosproject.store.service.AsyncAtomicCounter;
19 +import org.slf4j.Logger;
20 +
18 import java.util.concurrent.CompletableFuture; 21 import java.util.concurrent.CompletableFuture;
19 import java.util.concurrent.ScheduledExecutorService; 22 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.TimeUnit; 23 import java.util.concurrent.TimeUnit;
21 import java.util.function.BiFunction; 24 import java.util.function.BiFunction;
22 25
23 -import org.onosproject.store.service.AsyncAtomicCounter; 26 +import static com.google.common.base.Preconditions.checkNotNull;
24 -
25 -
26 -
27 -
28 -
29 -import org.slf4j.Logger;
30 -
31 -import static com.google.common.base.Preconditions.*;
32 import static org.slf4j.LoggerFactory.getLogger; 27 import static org.slf4j.LoggerFactory.getLogger;
33 28
34 /** 29 /**
...@@ -46,41 +41,61 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter { ...@@ -46,41 +41,61 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter {
46 // TODO: configure delay via builder 41 // TODO: configure delay via builder
47 private static final int DELAY_BETWEEN_RETRY_SEC = 1; 42 private static final int DELAY_BETWEEN_RETRY_SEC = 1;
48 private final Logger log = getLogger(getClass()); 43 private final Logger log = getLogger(getClass());
44 + private final MeteringAgent monitor;
45 +
46 + private static final String PRIMITIVE_NAME = "atomicCounter";
47 + private static final String INCREMENT_AND_GET = "incrementAndGet";
48 + private static final String GET_AND_INCREMENT = "getAndIncrement";
49 + private static final String GET_AND_ADD = "getAndAdd";
50 + private static final String ADD_AND_GET = "addAndGet";
51 + private static final String GET = "get";
49 52
50 public DefaultAsyncAtomicCounter(String name, 53 public DefaultAsyncAtomicCounter(String name,
51 Database database, 54 Database database,
52 boolean retryOnException, 55 boolean retryOnException,
56 + boolean meteringEnabled,
53 ScheduledExecutorService retryExecutor) { 57 ScheduledExecutorService retryExecutor) {
54 this.name = checkNotNull(name); 58 this.name = checkNotNull(name);
55 this.database = checkNotNull(database); 59 this.database = checkNotNull(database);
56 this.retryOnFailure = retryOnException; 60 this.retryOnFailure = retryOnException;
57 this.retryExecutor = retryExecutor; 61 this.retryExecutor = retryExecutor;
62 + this.monitor = new MeteringAgent(PRIMITIVE_NAME, name, meteringEnabled);
58 } 63 }
59 64
60 @Override 65 @Override
61 public CompletableFuture<Long> incrementAndGet() { 66 public CompletableFuture<Long> incrementAndGet() {
62 - return addAndGet(1L); 67 + final MeteringAgent.Context timer = monitor.startTimer(INCREMENT_AND_GET);
68 + return addAndGet(1L)
69 + .whenComplete((r, e) -> timer.stop());
63 } 70 }
64 71
65 @Override 72 @Override
66 public CompletableFuture<Long> get() { 73 public CompletableFuture<Long> get() {
67 - return database.counterGet(name); 74 + final MeteringAgent.Context timer = monitor.startTimer(GET);
75 + return database.counterGet(name)
76 + .whenComplete((r, e) -> timer.stop());
68 } 77 }
69 78
70 @Override 79 @Override
71 public CompletableFuture<Long> getAndIncrement() { 80 public CompletableFuture<Long> getAndIncrement() {
72 - return getAndAdd(1L); 81 + final MeteringAgent.Context timer = monitor.startTimer(GET_AND_INCREMENT);
82 + return getAndAdd(1L)
83 + .whenComplete((r, e) -> timer.stop());
73 } 84 }
74 85
75 @Override 86 @Override
76 public CompletableFuture<Long> getAndAdd(long delta) { 87 public CompletableFuture<Long> getAndAdd(long delta) {
88 + final MeteringAgent.Context timer = monitor.startTimer(GET_AND_ADD);
77 CompletableFuture<Long> result = database.counterGetAndAdd(name, delta); 89 CompletableFuture<Long> result = database.counterGetAndAdd(name, delta);
78 if (!retryOnFailure) { 90 if (!retryOnFailure) {
79 - return result; 91 + return result
92 + .whenComplete((r, e) -> timer.stop());
80 } 93 }
81 94
82 CompletableFuture<Long> future = new CompletableFuture<>(); 95 CompletableFuture<Long> future = new CompletableFuture<>();
83 return result.whenComplete((r, e) -> { 96 return result.whenComplete((r, e) -> {
97 + timer.stop();
98 + // TODO : Account for retries
84 if (e != null) { 99 if (e != null) {
85 log.warn("getAndAdd failed due to {}. Will retry", e.getMessage()); 100 log.warn("getAndAdd failed due to {}. Will retry", e.getMessage());
86 retryExecutor.schedule(new RetryTask(database::counterGetAndAdd, delta, future), 101 retryExecutor.schedule(new RetryTask(database::counterGetAndAdd, delta, future),
...@@ -94,13 +109,17 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter { ...@@ -94,13 +109,17 @@ public class DefaultAsyncAtomicCounter implements AsyncAtomicCounter {
94 109
95 @Override 110 @Override
96 public CompletableFuture<Long> addAndGet(long delta) { 111 public CompletableFuture<Long> addAndGet(long delta) {
112 + final MeteringAgent.Context timer = monitor.startTimer(ADD_AND_GET);
97 CompletableFuture<Long> result = database.counterAddAndGet(name, delta); 113 CompletableFuture<Long> result = database.counterAddAndGet(name, delta);
98 if (!retryOnFailure) { 114 if (!retryOnFailure) {
99 - return result; 115 + return result
116 + .whenComplete((r, e) -> timer.stop());
100 } 117 }
101 118
102 CompletableFuture<Long> future = new CompletableFuture<>(); 119 CompletableFuture<Long> future = new CompletableFuture<>();
103 return result.whenComplete((r, e) -> { 120 return result.whenComplete((r, e) -> {
121 + timer.stop();
122 + // TODO : Account for retries
104 if (e != null) { 123 if (e != null) {
105 log.warn("addAndGet failed due to {}. Will retry", e.getMessage()); 124 log.warn("addAndGet failed due to {}. Will retry", e.getMessage());
106 retryExecutor.schedule(new RetryTask(database::counterAddAndGet, delta, future), 125 retryExecutor.schedule(new RetryTask(database::counterAddAndGet, delta, future),
......
...@@ -16,47 +16,38 @@ ...@@ -16,47 +16,38 @@
16 16
17 package org.onosproject.store.consistent.impl; 17 package org.onosproject.store.consistent.impl;
18 18
19 -import static com.google.common.base.Preconditions.*; 19 +import com.google.common.cache.CacheBuilder;
20 -import static org.slf4j.LoggerFactory.getLogger; 20 +import com.google.common.cache.CacheLoader;
21 +import com.google.common.cache.LoadingCache;
22 +import com.google.common.collect.Maps;
23 +import org.onlab.util.HexString;
24 +import org.onlab.util.SharedExecutors;
25 +import org.onlab.util.Tools;
26 +import org.onosproject.core.ApplicationId;
27 +import org.onosproject.store.service.AsyncConsistentMap;
28 +import org.onosproject.store.service.ConsistentMapException;
29 +import org.onosproject.store.service.MapEvent;
30 +import org.onosproject.store.service.MapEventListener;
31 +import org.onosproject.store.service.Serializer;
32 +import org.onosproject.store.service.Versioned;
33 +import org.slf4j.Logger;
21 34
22 import java.util.Collection; 35 import java.util.Collection;
23 import java.util.Map; 36 import java.util.Map;
24 import java.util.Map.Entry; 37 import java.util.Map.Entry;
25 import java.util.Objects; 38 import java.util.Objects;
39 +import java.util.Set;
26 import java.util.concurrent.CompletableFuture; 40 import java.util.concurrent.CompletableFuture;
27 import java.util.concurrent.CopyOnWriteArraySet; 41 import java.util.concurrent.CopyOnWriteArraySet;
28 -import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.atomic.AtomicReference; 42 import java.util.concurrent.atomic.AtomicReference;
30 import java.util.function.BiFunction; 43 import java.util.function.BiFunction;
31 import java.util.function.Function; 44 import java.util.function.Function;
32 import java.util.function.Predicate; 45 import java.util.function.Predicate;
33 import java.util.stream.Collectors; 46 import java.util.stream.Collectors;
34 -import java.util.Set;
35 -
36 -import com.codahale.metrics.Timer;
37 -import org.onlab.metrics.MetricsComponent;
38 -import org.onlab.metrics.MetricsFeature;
39 -import org.onlab.metrics.MetricsService;
40 -import org.onlab.osgi.DefaultServiceDirectory;
41 -import org.onlab.util.HexString;
42 -import org.onlab.util.SharedExecutors;
43 -import org.onlab.util.Tools;
44 -import org.onosproject.core.ApplicationId;
45 47
48 +import static com.google.common.base.Preconditions.checkNotNull;
46 import static org.onosproject.store.consistent.impl.StateMachineUpdate.Target.MAP; 49 import static org.onosproject.store.consistent.impl.StateMachineUpdate.Target.MAP;
47 - 50 +import static org.slf4j.LoggerFactory.getLogger;
48 -import org.onosproject.store.service.AsyncConsistentMap;
49 -import org.onosproject.store.service.ConsistentMapException;
50 -import org.onosproject.store.service.MapEvent;
51 -import org.onosproject.store.service.MapEventListener;
52 -import org.onosproject.store.service.Serializer;
53 -import org.onosproject.store.service.Versioned;
54 -import org.slf4j.Logger;
55 -
56 -import com.google.common.cache.CacheBuilder;
57 -import com.google.common.cache.CacheLoader;
58 -import com.google.common.cache.LoadingCache;
59 -import com.google.common.collect.Maps;
60 51
61 /** 52 /**
62 * AsyncConsistentMap implementation that is backed by a Raft consensus 53 * AsyncConsistentMap implementation that is backed by a Raft consensus
...@@ -74,16 +65,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -74,16 +65,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
74 private final boolean readOnly; 65 private final boolean readOnly;
75 private final boolean purgeOnUninstall; 66 private final boolean purgeOnUninstall;
76 67
77 - private final MetricsService metricsService; 68 + private static final String PRIMITIVE_NAME = "consistentMap";
78 - private final MetricsComponent metricsComponent;
79 - private final MetricsFeature metricsFeature;
80 - private final Map<String, Timer> perMapOpTimers = Maps.newConcurrentMap();
81 - private final Map<String, Timer> perOpTimers = Maps.newConcurrentMap();
82 - private final Timer cMapTimer;
83 - private final Timer perMapTimer;
84 - private final MetricsFeature wildcard;
85 -
86 - private static final String COMPONENT_NAME = "consistentMap";
87 private static final String SIZE = "size"; 69 private static final String SIZE = "size";
88 private static final String IS_EMPTY = "isEmpty"; 70 private static final String IS_EMPTY = "isEmpty";
89 private static final String CONTAINS_KEY = "containsKey"; 71 private static final String CONTAINS_KEY = "containsKey";
...@@ -105,6 +87,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -105,6 +87,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
105 private final Set<MapEventListener<K, V>> listeners = new CopyOnWriteArraySet<>(); 87 private final Set<MapEventListener<K, V>> listeners = new CopyOnWriteArraySet<>();
106 88
107 private final Logger log = getLogger(getClass()); 89 private final Logger log = getLogger(getClass());
90 + private final MeteringAgent monitor;
108 91
109 private static final String ERROR_NULL_KEY = "Key cannot be null"; 92 private static final String ERROR_NULL_KEY = "Key cannot be null";
110 private static final String ERROR_NULL_VALUE = "Null values are not allowed"; 93 private static final String ERROR_NULL_VALUE = "Null values are not allowed";
...@@ -128,7 +111,8 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -128,7 +111,8 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
128 Database database, 111 Database database,
129 Serializer serializer, 112 Serializer serializer,
130 boolean readOnly, 113 boolean readOnly,
131 - boolean purgeOnUninstall) { 114 + boolean purgeOnUninstall,
115 + boolean meteringEnabled) {
132 this.name = checkNotNull(name, "map name cannot be null"); 116 this.name = checkNotNull(name, "map name cannot be null");
133 this.applicationId = applicationId; 117 this.applicationId = applicationId;
134 this.database = checkNotNull(database, "database cannot be null"); 118 this.database = checkNotNull(database, "database cannot be null");
...@@ -146,13 +130,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -146,13 +130,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
146 } 130 }
147 }); 131 });
148 }); 132 });
149 - this.metricsService = DefaultServiceDirectory.getService(MetricsService.class); 133 + this.monitor = new MeteringAgent(PRIMITIVE_NAME, name, meteringEnabled);
150 - this.metricsComponent = metricsService.registerComponent(COMPONENT_NAME);
151 - this.metricsFeature = metricsComponent.registerFeature(name);
152 - this.wildcard = metricsComponent.registerFeature("*");
153 - this.perMapTimer = metricsService.createTimer(metricsComponent, metricsFeature, "*");
154 - this.cMapTimer = metricsService.createTimer(metricsComponent, wildcard, "*");
155 -
156 } 134 }
157 135
158 /** 136 /**
...@@ -190,14 +168,14 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -190,14 +168,14 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
190 168
191 @Override 169 @Override
192 public CompletableFuture<Integer> size() { 170 public CompletableFuture<Integer> size() {
193 - final OperationTimer timer = startTimer(SIZE); 171 + final MeteringAgent.Context timer = monitor.startTimer(SIZE);
194 return database.mapSize(name) 172 return database.mapSize(name)
195 .whenComplete((r, e) -> timer.stop()); 173 .whenComplete((r, e) -> timer.stop());
196 } 174 }
197 175
198 @Override 176 @Override
199 public CompletableFuture<Boolean> isEmpty() { 177 public CompletableFuture<Boolean> isEmpty() {
200 - final OperationTimer timer = startTimer(IS_EMPTY); 178 + final MeteringAgent.Context timer = monitor.startTimer(IS_EMPTY);
201 return database.mapIsEmpty(name) 179 return database.mapIsEmpty(name)
202 .whenComplete((r, e) -> timer.stop()); 180 .whenComplete((r, e) -> timer.stop());
203 } 181 }
...@@ -205,7 +183,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -205,7 +183,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
205 @Override 183 @Override
206 public CompletableFuture<Boolean> containsKey(K key) { 184 public CompletableFuture<Boolean> containsKey(K key) {
207 checkNotNull(key, ERROR_NULL_KEY); 185 checkNotNull(key, ERROR_NULL_KEY);
208 - final OperationTimer timer = startTimer(CONTAINS_KEY); 186 + final MeteringAgent.Context timer = monitor.startTimer(CONTAINS_KEY);
209 return database.mapContainsKey(name, keyCache.getUnchecked(key)) 187 return database.mapContainsKey(name, keyCache.getUnchecked(key))
210 .whenComplete((r, e) -> timer.stop()); 188 .whenComplete((r, e) -> timer.stop());
211 } 189 }
...@@ -213,7 +191,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -213,7 +191,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
213 @Override 191 @Override
214 public CompletableFuture<Boolean> containsValue(V value) { 192 public CompletableFuture<Boolean> containsValue(V value) {
215 checkNotNull(value, ERROR_NULL_VALUE); 193 checkNotNull(value, ERROR_NULL_VALUE);
216 - final OperationTimer timer = startTimer(CONTAINS_VALUE); 194 + final MeteringAgent.Context timer = monitor.startTimer(CONTAINS_VALUE);
217 return database.mapContainsValue(name, serializer.encode(value)) 195 return database.mapContainsValue(name, serializer.encode(value))
218 .whenComplete((r, e) -> timer.stop()); 196 .whenComplete((r, e) -> timer.stop());
219 } 197 }
...@@ -221,7 +199,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -221,7 +199,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
221 @Override 199 @Override
222 public CompletableFuture<Versioned<V>> get(K key) { 200 public CompletableFuture<Versioned<V>> get(K key) {
223 checkNotNull(key, ERROR_NULL_KEY); 201 checkNotNull(key, ERROR_NULL_KEY);
224 - final OperationTimer timer = startTimer(GET); 202 + final MeteringAgent.Context timer = monitor.startTimer(GET);
225 return database.mapGet(name, keyCache.getUnchecked(key)) 203 return database.mapGet(name, keyCache.getUnchecked(key))
226 .whenComplete((r, e) -> timer.stop()) 204 .whenComplete((r, e) -> timer.stop())
227 .thenApply(v -> v != null ? v.map(serializer::decode) : null); 205 .thenApply(v -> v != null ? v.map(serializer::decode) : null);
...@@ -232,7 +210,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -232,7 +210,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
232 Function<? super K, ? extends V> mappingFunction) { 210 Function<? super K, ? extends V> mappingFunction) {
233 checkNotNull(key, ERROR_NULL_KEY); 211 checkNotNull(key, ERROR_NULL_KEY);
234 checkNotNull(mappingFunction, "Mapping function cannot be null"); 212 checkNotNull(mappingFunction, "Mapping function cannot be null");
235 - final OperationTimer timer = startTimer(COMPUTE_IF_ABSENT); 213 + final MeteringAgent.Context timer = monitor.startTimer(COMPUTE_IF_ABSENT);
236 return updateAndGet(key, Match.ifNull(), Match.any(), mappingFunction.apply(key)) 214 return updateAndGet(key, Match.ifNull(), Match.any(), mappingFunction.apply(key))
237 .whenComplete((r, e) -> timer.stop()) 215 .whenComplete((r, e) -> timer.stop())
238 .thenApply(v -> v.newValue()); 216 .thenApply(v -> v.newValue());
...@@ -257,7 +235,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -257,7 +235,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
257 checkNotNull(key, ERROR_NULL_KEY); 235 checkNotNull(key, ERROR_NULL_KEY);
258 checkNotNull(condition, "predicate function cannot be null"); 236 checkNotNull(condition, "predicate function cannot be null");
259 checkNotNull(remappingFunction, "Remapping function cannot be null"); 237 checkNotNull(remappingFunction, "Remapping function cannot be null");
260 - final OperationTimer timer = startTimer(COMPUTE_IF); 238 + final MeteringAgent.Context timer = monitor.startTimer(COMPUTE_IF);
261 return get(key).thenCompose(r1 -> { 239 return get(key).thenCompose(r1 -> {
262 V existingValue = r1 == null ? null : r1.value(); 240 V existingValue = r1 == null ? null : r1.value();
263 // if the condition evaluates to false, return existing value. 241 // if the condition evaluates to false, return existing value.
...@@ -293,7 +271,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -293,7 +271,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
293 public CompletableFuture<Versioned<V>> put(K key, V value) { 271 public CompletableFuture<Versioned<V>> put(K key, V value) {
294 checkNotNull(key, ERROR_NULL_KEY); 272 checkNotNull(key, ERROR_NULL_KEY);
295 checkNotNull(value, ERROR_NULL_VALUE); 273 checkNotNull(value, ERROR_NULL_VALUE);
296 - final OperationTimer timer = startTimer(PUT); 274 + final MeteringAgent.Context timer = monitor.startTimer(PUT);
297 return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.oldValue()) 275 return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.oldValue())
298 .whenComplete((r, e) -> timer.stop()); 276 .whenComplete((r, e) -> timer.stop());
299 } 277 }
...@@ -302,7 +280,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -302,7 +280,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
302 public CompletableFuture<Versioned<V>> putAndGet(K key, V value) { 280 public CompletableFuture<Versioned<V>> putAndGet(K key, V value) {
303 checkNotNull(key, ERROR_NULL_KEY); 281 checkNotNull(key, ERROR_NULL_KEY);
304 checkNotNull(value, ERROR_NULL_VALUE); 282 checkNotNull(value, ERROR_NULL_VALUE);
305 - final OperationTimer timer = startTimer(PUT_AND_GET); 283 + final MeteringAgent.Context timer = monitor.startTimer(PUT_AND_GET);
306 return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.newValue()) 284 return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.newValue())
307 .whenComplete((r, e) -> timer.stop()); 285 .whenComplete((r, e) -> timer.stop());
308 } 286 }
...@@ -310,7 +288,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -310,7 +288,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
310 @Override 288 @Override
311 public CompletableFuture<Versioned<V>> remove(K key) { 289 public CompletableFuture<Versioned<V>> remove(K key) {
312 checkNotNull(key, ERROR_NULL_KEY); 290 checkNotNull(key, ERROR_NULL_KEY);
313 - final OperationTimer timer = startTimer(REMOVE); 291 + final MeteringAgent.Context timer = monitor.startTimer(REMOVE);
314 return updateAndGet(key, Match.any(), Match.any(), null).thenApply(v -> v.oldValue()) 292 return updateAndGet(key, Match.any(), Match.any(), null).thenApply(v -> v.oldValue())
315 .whenComplete((r, e) -> timer.stop()); 293 .whenComplete((r, e) -> timer.stop());
316 } 294 }
...@@ -318,14 +296,14 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -318,14 +296,14 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
318 @Override 296 @Override
319 public CompletableFuture<Void> clear() { 297 public CompletableFuture<Void> clear() {
320 checkIfUnmodifiable(); 298 checkIfUnmodifiable();
321 - final OperationTimer timer = startTimer(CLEAR); 299 + final MeteringAgent.Context timer = monitor.startTimer(CLEAR);
322 return database.mapClear(name).thenApply(this::unwrapResult) 300 return database.mapClear(name).thenApply(this::unwrapResult)
323 .whenComplete((r, e) -> timer.stop()); 301 .whenComplete((r, e) -> timer.stop());
324 } 302 }
325 303
326 @Override 304 @Override
327 public CompletableFuture<Set<K>> keySet() { 305 public CompletableFuture<Set<K>> keySet() {
328 - final OperationTimer timer = startTimer(KEY_SET); 306 + final MeteringAgent.Context timer = monitor.startTimer(KEY_SET);
329 return database.mapKeySet(name) 307 return database.mapKeySet(name)
330 .thenApply(s -> s 308 .thenApply(s -> s
331 .stream() 309 .stream()
...@@ -336,7 +314,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -336,7 +314,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
336 314
337 @Override 315 @Override
338 public CompletableFuture<Collection<Versioned<V>>> values() { 316 public CompletableFuture<Collection<Versioned<V>>> values() {
339 - final OperationTimer timer = startTimer(VALUES); 317 + final MeteringAgent.Context timer = monitor.startTimer(VALUES);
340 return database.mapValues(name) 318 return database.mapValues(name)
341 .whenComplete((r, e) -> timer.stop()) 319 .whenComplete((r, e) -> timer.stop())
342 .thenApply(c -> c 320 .thenApply(c -> c
...@@ -347,7 +325,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -347,7 +325,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
347 325
348 @Override 326 @Override
349 public CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet() { 327 public CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet() {
350 - final OperationTimer timer = startTimer(ENTRY_SET); 328 + final MeteringAgent.Context timer = monitor.startTimer(ENTRY_SET);
351 return database.mapEntrySet(name) 329 return database.mapEntrySet(name)
352 .whenComplete((r, e) -> timer.stop()) 330 .whenComplete((r, e) -> timer.stop())
353 .thenApply(s -> s 331 .thenApply(s -> s
...@@ -360,7 +338,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -360,7 +338,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
360 public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) { 338 public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) {
361 checkNotNull(key, ERROR_NULL_KEY); 339 checkNotNull(key, ERROR_NULL_KEY);
362 checkNotNull(value, ERROR_NULL_VALUE); 340 checkNotNull(value, ERROR_NULL_VALUE);
363 - final OperationTimer timer = startTimer(PUT_IF_ABSENT); 341 + final MeteringAgent.Context timer = monitor.startTimer(PUT_IF_ABSENT);
364 return updateAndGet(key, Match.ifNull(), Match.any(), value) 342 return updateAndGet(key, Match.ifNull(), Match.any(), value)
365 .whenComplete((r, e) -> timer.stop()) 343 .whenComplete((r, e) -> timer.stop())
366 .thenApply(v -> v.oldValue()); 344 .thenApply(v -> v.oldValue());
...@@ -370,7 +348,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -370,7 +348,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
370 public CompletableFuture<Boolean> remove(K key, V value) { 348 public CompletableFuture<Boolean> remove(K key, V value) {
371 checkNotNull(key, ERROR_NULL_KEY); 349 checkNotNull(key, ERROR_NULL_KEY);
372 checkNotNull(value, ERROR_NULL_VALUE); 350 checkNotNull(value, ERROR_NULL_VALUE);
373 - final OperationTimer timer = startTimer(REMOVE); 351 + final MeteringAgent.Context timer = monitor.startTimer(REMOVE);
374 return updateAndGet(key, Match.ifValue(value), Match.any(), null) 352 return updateAndGet(key, Match.ifValue(value), Match.any(), null)
375 .whenComplete((r, e) -> timer.stop()) 353 .whenComplete((r, e) -> timer.stop())
376 .thenApply(v -> v.updated()); 354 .thenApply(v -> v.updated());
...@@ -379,7 +357,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -379,7 +357,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
379 @Override 357 @Override
380 public CompletableFuture<Boolean> remove(K key, long version) { 358 public CompletableFuture<Boolean> remove(K key, long version) {
381 checkNotNull(key, ERROR_NULL_KEY); 359 checkNotNull(key, ERROR_NULL_KEY);
382 - final OperationTimer timer = startTimer(REMOVE); 360 + final MeteringAgent.Context timer = monitor.startTimer(REMOVE);
383 return updateAndGet(key, Match.any(), Match.ifValue(version), null) 361 return updateAndGet(key, Match.any(), Match.ifValue(version), null)
384 .whenComplete((r, e) -> timer.stop()) 362 .whenComplete((r, e) -> timer.stop())
385 .thenApply(v -> v.updated()); 363 .thenApply(v -> v.updated());
...@@ -390,7 +368,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -390,7 +368,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
390 checkNotNull(key, ERROR_NULL_KEY); 368 checkNotNull(key, ERROR_NULL_KEY);
391 checkNotNull(oldValue, ERROR_NULL_VALUE); 369 checkNotNull(oldValue, ERROR_NULL_VALUE);
392 checkNotNull(newValue, ERROR_NULL_VALUE); 370 checkNotNull(newValue, ERROR_NULL_VALUE);
393 - final OperationTimer timer = startTimer(REPLACE); 371 + final MeteringAgent.Context timer = monitor.startTimer(REPLACE);
394 return updateAndGet(key, Match.ifValue(oldValue), Match.any(), newValue) 372 return updateAndGet(key, Match.ifValue(oldValue), Match.any(), newValue)
395 .whenComplete((r, e) -> timer.stop()) 373 .whenComplete((r, e) -> timer.stop())
396 .thenApply(v -> v.updated()); 374 .thenApply(v -> v.updated());
...@@ -398,7 +376,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -398,7 +376,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
398 376
399 @Override 377 @Override
400 public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) { 378 public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) {
401 - final OperationTimer timer = startTimer(REPLACE); 379 + final MeteringAgent.Context timer = monitor.startTimer(REPLACE);
402 return updateAndGet(key, Match.any(), Match.ifValue(oldVersion), newValue) 380 return updateAndGet(key, Match.any(), Match.ifValue(oldVersion), newValue)
403 .whenComplete((r, e) -> timer.stop()) 381 .whenComplete((r, e) -> timer.stop())
404 .thenApply(v -> v.updated()); 382 .thenApply(v -> v.updated());
...@@ -461,33 +439,4 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -461,33 +439,4 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
461 }); 439 });
462 } 440 }
463 441
464 - private OperationTimer startTimer(String op) {
465 - //check if timer exist, if it doesn't creates it
466 - final Timer currTimer = perMapOpTimers.computeIfAbsent(op, timer ->
467 - metricsService.createTimer(metricsComponent, metricsFeature, op));
468 - perOpTimers.computeIfAbsent(op, timer -> metricsService.createTimer(metricsComponent, wildcard, op));
469 - //starts timer
470 - return new OperationTimer(currTimer.time(), op);
471 - }
472 -
473 - private class OperationTimer {
474 - private final Timer.Context context;
475 - private final String operation;
476 -
477 - public OperationTimer(Timer.Context context, String operation) {
478 - this.context = context;
479 - this.operation = operation;
480 - }
481 -
482 - public void stop() {
483 - //Stop and updates timer with specific measurements per map, per operation
484 - final long time = context.stop();
485 - //updates timer with aggregated measurements per map
486 - perOpTimers.get(operation).update(time, TimeUnit.NANOSECONDS);
487 - //updates timer with aggregated measurements per map
488 - perMapTimer.update(time, TimeUnit.NANOSECONDS);
489 - //updates timer with aggregated measurements per all Consistent Maps
490 - cMapTimer.update(time, TimeUnit.NANOSECONDS);
491 - }
492 - }
493 } 442 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -15,16 +15,16 @@ ...@@ -15,16 +15,16 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 +import org.onosproject.store.service.AsyncAtomicCounter;
19 +import org.onosproject.store.service.AtomicCounter;
20 +import org.onosproject.store.service.StorageException;
21 +
18 import java.util.concurrent.CompletableFuture; 22 import java.util.concurrent.CompletableFuture;
19 import java.util.concurrent.ExecutionException; 23 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.ScheduledExecutorService; 24 import java.util.concurrent.ScheduledExecutorService;
21 import java.util.concurrent.TimeUnit; 25 import java.util.concurrent.TimeUnit;
22 import java.util.concurrent.TimeoutException; 26 import java.util.concurrent.TimeoutException;
23 27
24 -import org.onosproject.store.service.AsyncAtomicCounter;
25 -import org.onosproject.store.service.AtomicCounter;
26 -import org.onosproject.store.service.StorageException;
27 -
28 /** 28 /**
29 * Default implementation for a distributed AtomicCounter backed by 29 * Default implementation for a distributed AtomicCounter backed by
30 * partitioned Raft DB. 30 * partitioned Raft DB.
...@@ -40,8 +40,9 @@ public class DefaultAtomicCounter implements AtomicCounter { ...@@ -40,8 +40,9 @@ public class DefaultAtomicCounter implements AtomicCounter {
40 public DefaultAtomicCounter(String name, 40 public DefaultAtomicCounter(String name,
41 Database database, 41 Database database,
42 boolean retryOnException, 42 boolean retryOnException,
43 + boolean meteringEnabled,
43 ScheduledExecutorService retryExecutor) { 44 ScheduledExecutorService retryExecutor) {
44 - asyncCounter = new DefaultAsyncAtomicCounter(name, database, retryOnException, retryExecutor); 45 + asyncCounter = new DefaultAsyncAtomicCounter(name, database, retryOnException, meteringEnabled, retryExecutor);
45 } 46 }
46 47
47 @Override 48 @Override
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import java.util.concurrent.ScheduledExecutorService;
19 -
20 import org.onosproject.store.service.AsyncAtomicCounter; 18 import org.onosproject.store.service.AsyncAtomicCounter;
21 import org.onosproject.store.service.AtomicCounter; 19 import org.onosproject.store.service.AtomicCounter;
22 import org.onosproject.store.service.AtomicCounterBuilder; 20 import org.onosproject.store.service.AtomicCounterBuilder;
23 21
22 +import java.util.concurrent.ScheduledExecutorService;
23 +
24 import static com.google.common.base.Preconditions.checkArgument; 24 import static com.google.common.base.Preconditions.checkArgument;
25 25
26 /** 26 /**
...@@ -33,6 +33,7 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder { ...@@ -33,6 +33,7 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder {
33 private final Database partitionedDatabase; 33 private final Database partitionedDatabase;
34 private final Database inMemoryDatabase; 34 private final Database inMemoryDatabase;
35 private boolean retryOnFailure = false; 35 private boolean retryOnFailure = false;
36 + private boolean metering = true;
36 private ScheduledExecutorService retryExecutor = null; 37 private ScheduledExecutorService retryExecutor = null;
37 38
38 public DefaultAtomicCounterBuilder(Database inMemoryDatabase, Database partitionedDatabase) { 39 public DefaultAtomicCounterBuilder(Database inMemoryDatabase, Database partitionedDatabase) {
...@@ -57,14 +58,14 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder { ...@@ -57,14 +58,14 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder {
57 public AtomicCounter build() { 58 public AtomicCounter build() {
58 validateInputs(); 59 validateInputs();
59 Database database = partitionsEnabled ? partitionedDatabase : inMemoryDatabase; 60 Database database = partitionsEnabled ? partitionedDatabase : inMemoryDatabase;
60 - return new DefaultAtomicCounter(name, database, retryOnFailure, retryExecutor); 61 + return new DefaultAtomicCounter(name, database, retryOnFailure, metering, retryExecutor);
61 } 62 }
62 63
63 @Override 64 @Override
64 public AsyncAtomicCounter buildAsyncCounter() { 65 public AsyncAtomicCounter buildAsyncCounter() {
65 validateInputs(); 66 validateInputs();
66 Database database = partitionsEnabled ? partitionedDatabase : inMemoryDatabase; 67 Database database = partitionsEnabled ? partitionedDatabase : inMemoryDatabase;
67 - return new DefaultAsyncAtomicCounter(name, database, retryOnFailure, retryExecutor); 68 + return new DefaultAsyncAtomicCounter(name, database, retryOnFailure, metering, retryExecutor);
68 } 69 }
69 70
70 @Override 71 @Override
...@@ -74,6 +75,12 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder { ...@@ -74,6 +75,12 @@ public class DefaultAtomicCounterBuilder implements AtomicCounterBuilder {
74 } 75 }
75 76
76 @Override 77 @Override
78 + public AtomicCounterBuilder withMeteringDisabled() {
79 + metering = false;
80 + return this;
81 + }
82 +
83 + @Override
77 public AtomicCounterBuilder withRetryExecutor(ScheduledExecutorService executor) { 84 public AtomicCounterBuilder withRetryExecutor(ScheduledExecutorService executor) {
78 this.retryExecutor = executor; 85 this.retryExecutor = executor;
79 return this; 86 return this;
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import java.util.Set;
19 -import java.util.concurrent.CopyOnWriteArraySet;
20 -
21 import org.onosproject.store.service.AtomicValue; 18 import org.onosproject.store.service.AtomicValue;
22 import org.onosproject.store.service.AtomicValueEvent; 19 import org.onosproject.store.service.AtomicValueEvent;
23 import org.onosproject.store.service.AtomicValueEventListener; 20 import org.onosproject.store.service.AtomicValueEventListener;
...@@ -27,6 +24,9 @@ import org.onosproject.store.service.MapEventListener; ...@@ -27,6 +24,9 @@ import org.onosproject.store.service.MapEventListener;
27 import org.onosproject.store.service.Serializer; 24 import org.onosproject.store.service.Serializer;
28 import org.onosproject.store.service.Versioned; 25 import org.onosproject.store.service.Versioned;
29 26
27 +import java.util.Set;
28 +import java.util.concurrent.CopyOnWriteArraySet;
29 +
30 /** 30 /**
31 * Default implementation of AtomicValue. 31 * Default implementation of AtomicValue.
32 * 32 *
...@@ -39,17 +39,27 @@ public class DefaultAtomicValue<V> implements AtomicValue<V> { ...@@ -39,17 +39,27 @@ public class DefaultAtomicValue<V> implements AtomicValue<V> {
39 private final String name; 39 private final String name;
40 private final Serializer serializer; 40 private final Serializer serializer;
41 private final MapEventListener<String, byte[]> mapEventListener = new InternalMapEventListener(); 41 private final MapEventListener<String, byte[]> mapEventListener = new InternalMapEventListener();
42 + private final MeteringAgent monitor;
43 +
44 + private static final String COMPONENT_NAME = "atomicValue";
45 + private static final String GET = "get";
46 + private static final String GET_AND_SET = "getAndSet";
47 + private static final String COMPARE_AND_SET = "compareAndSet";
42 48
43 public DefaultAtomicValue(ConsistentMap<String, byte[]> valueMap, 49 public DefaultAtomicValue(ConsistentMap<String, byte[]> valueMap,
44 String name, 50 String name,
51 + boolean meteringEnabled,
45 Serializer serializer) { 52 Serializer serializer) {
46 this.valueMap = valueMap; 53 this.valueMap = valueMap;
47 this.name = name; 54 this.name = name;
48 this.serializer = serializer; 55 this.serializer = serializer;
56 + this.monitor = new MeteringAgent(COMPONENT_NAME, name, meteringEnabled);
49 } 57 }
50 58
51 @Override 59 @Override
52 public boolean compareAndSet(V expect, V update) { 60 public boolean compareAndSet(V expect, V update) {
61 + final MeteringAgent.Context newTimer = monitor.startTimer(COMPARE_AND_SET);
62 + try {
53 if (expect == null) { 63 if (expect == null) {
54 if (update == null) { 64 if (update == null) {
55 return true; 65 return true;
...@@ -61,19 +71,32 @@ public class DefaultAtomicValue<V> implements AtomicValue<V> { ...@@ -61,19 +71,32 @@ public class DefaultAtomicValue<V> implements AtomicValue<V> {
61 } 71 }
62 return valueMap.replace(name, serializer.encode(expect), serializer.encode(update)); 72 return valueMap.replace(name, serializer.encode(expect), serializer.encode(update));
63 } 73 }
74 + } finally {
75 + newTimer.stop();
76 + }
64 } 77 }
65 78
66 @Override 79 @Override
67 public V get() { 80 public V get() {
81 + final MeteringAgent.Context newTimer = monitor.startTimer(GET);
82 + try {
68 Versioned<byte[]> rawValue = valueMap.get(name); 83 Versioned<byte[]> rawValue = valueMap.get(name);
69 return rawValue == null ? null : serializer.decode(rawValue.value()); 84 return rawValue == null ? null : serializer.decode(rawValue.value());
85 + } finally {
86 + newTimer.stop();
87 + }
70 } 88 }
71 89
72 @Override 90 @Override
73 public V getAndSet(V value) { 91 public V getAndSet(V value) {
92 + final MeteringAgent.Context newTimer = monitor.startTimer(GET_AND_SET);
93 + try {
74 Versioned<byte[]> previousValue = value == null ? 94 Versioned<byte[]> previousValue = value == null ?
75 valueMap.remove(name) : valueMap.put(name, serializer.encode(value)); 95 valueMap.remove(name) : valueMap.put(name, serializer.encode(value));
76 return previousValue == null ? null : serializer.decode(previousValue.value()); 96 return previousValue == null ? null : serializer.decode(previousValue.value());
97 + } finally {
98 + newTimer.stop();
99 + }
77 } 100 }
78 101
79 @Override 102 @Override
......
...@@ -31,10 +31,12 @@ public class DefaultAtomicValueBuilder<V> implements AtomicValueBuilder<V> { ...@@ -31,10 +31,12 @@ public class DefaultAtomicValueBuilder<V> implements AtomicValueBuilder<V> {
31 private Serializer serializer; 31 private Serializer serializer;
32 private String name; 32 private String name;
33 private ConsistentMapBuilder<String, byte[]> mapBuilder; 33 private ConsistentMapBuilder<String, byte[]> mapBuilder;
34 + private boolean metering = true;
34 35
35 public DefaultAtomicValueBuilder(DatabaseManager manager) { 36 public DefaultAtomicValueBuilder(DatabaseManager manager) {
36 mapBuilder = manager.<String, byte[]>consistentMapBuilder() 37 mapBuilder = manager.<String, byte[]>consistentMapBuilder()
37 .withName("onos-atomic-values") 38 .withName("onos-atomic-values")
39 + .withMeteringDisabled()
38 .withSerializer(Serializer.using(KryoNamespaces.BASIC)); 40 .withSerializer(Serializer.using(KryoNamespaces.BASIC));
39 } 41 }
40 42
...@@ -57,7 +59,13 @@ public class DefaultAtomicValueBuilder<V> implements AtomicValueBuilder<V> { ...@@ -57,7 +59,13 @@ public class DefaultAtomicValueBuilder<V> implements AtomicValueBuilder<V> {
57 } 59 }
58 60
59 @Override 61 @Override
62 + public AtomicValueBuilder<V> withMeteringDisabled() {
63 + metering = false;
64 + return this;
65 + }
66 +
67 + @Override
60 public AtomicValue<V> build() { 68 public AtomicValue<V> build() {
61 - return new DefaultAtomicValue<>(mapBuilder.build(), name, serializer); 69 + return new DefaultAtomicValue<>(mapBuilder.build(), name, metering, serializer);
62 } 70 }
63 } 71 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -15,15 +15,15 @@ ...@@ -15,15 +15,15 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import static com.google.common.base.Preconditions.checkArgument;
19 -import static com.google.common.base.Preconditions.checkState;
20 -
21 import org.onosproject.core.ApplicationId; 18 import org.onosproject.core.ApplicationId;
22 import org.onosproject.store.service.AsyncConsistentMap; 19 import org.onosproject.store.service.AsyncConsistentMap;
23 import org.onosproject.store.service.ConsistentMap; 20 import org.onosproject.store.service.ConsistentMap;
24 import org.onosproject.store.service.ConsistentMapBuilder; 21 import org.onosproject.store.service.ConsistentMapBuilder;
25 import org.onosproject.store.service.Serializer; 22 import org.onosproject.store.service.Serializer;
26 23
24 +import static com.google.common.base.Preconditions.checkArgument;
25 +import static com.google.common.base.Preconditions.checkState;
26 +
27 /** 27 /**
28 * Default Consistent Map builder. 28 * Default Consistent Map builder.
29 * 29 *
...@@ -38,6 +38,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -38,6 +38,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
38 private boolean purgeOnUninstall = false; 38 private boolean purgeOnUninstall = false;
39 private boolean partitionsEnabled = true; 39 private boolean partitionsEnabled = true;
40 private boolean readOnly = false; 40 private boolean readOnly = false;
41 + private boolean metering = true;
41 private final DatabaseManager manager; 42 private final DatabaseManager manager;
42 43
43 public DefaultConsistentMapBuilder(DatabaseManager manager) { 44 public DefaultConsistentMapBuilder(DatabaseManager manager) {
...@@ -65,6 +66,12 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -65,6 +66,12 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
65 } 66 }
66 67
67 @Override 68 @Override
69 + public ConsistentMapBuilder<K, V> withMeteringDisabled() {
70 + metering = false;
71 + return this;
72 + }
73 +
74 + @Override
68 public ConsistentMapBuilder<K, V> withSerializer(Serializer serializer) { 75 public ConsistentMapBuilder<K, V> withSerializer(Serializer serializer) {
69 checkArgument(serializer != null); 76 checkArgument(serializer != null);
70 this.serializer = serializer; 77 this.serializer = serializer;
...@@ -109,7 +116,8 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -109,7 +116,8 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
109 partitionsEnabled ? manager.partitionedDatabase : manager.inMemoryDatabase, 116 partitionsEnabled ? manager.partitionedDatabase : manager.inMemoryDatabase,
110 serializer, 117 serializer,
111 readOnly, 118 readOnly,
112 - purgeOnUninstall); 119 + purgeOnUninstall,
120 + metering);
113 return manager.registerMap(asyncMap); 121 return manager.registerMap(asyncMap);
114 } 122 }
115 } 123 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import static com.google.common.base.Preconditions.checkNotNull; 18 +import com.google.common.collect.Sets;
19 +import com.google.common.util.concurrent.Futures;
20 +import org.onosproject.cluster.NodeId;
21 +import org.onosproject.store.service.DistributedQueue;
22 +import org.onosproject.store.service.Serializer;
19 23
20 import java.util.Set; 24 import java.util.Set;
21 import java.util.concurrent.CompletableFuture; 25 import java.util.concurrent.CompletableFuture;
22 import java.util.function.Consumer; 26 import java.util.function.Consumer;
23 27
24 -import org.onosproject.cluster.NodeId; 28 +import static com.google.common.base.Preconditions.checkNotNull;
25 -import org.onosproject.store.service.DistributedQueue;
26 -import org.onosproject.store.service.Serializer;
27 -
28 -import com.google.common.collect.Sets;
29 -import com.google.common.util.concurrent.Futures;
30 29
31 /** 30 /**
32 * DistributedQueue implementation that provides FIFO ordering semantics. 31 * DistributedQueue implementation that provides FIFO ordering semantics.
...@@ -42,35 +41,56 @@ public class DefaultDistributedQueue<E> implements DistributedQueue<E> { ...@@ -42,35 +41,56 @@ public class DefaultDistributedQueue<E> implements DistributedQueue<E> {
42 private final Set<CompletableFuture<E>> pendingFutures = Sets.newIdentityHashSet(); 41 private final Set<CompletableFuture<E>> pendingFutures = Sets.newIdentityHashSet();
43 private final Consumer<Set<NodeId>> notifyConsumers; 42 private final Consumer<Set<NodeId>> notifyConsumers;
44 43
44 + private static final String PRIMITIVE_NAME = "distributedQueue";
45 + private static final String SIZE = "size";
46 + private static final String PUSH = "push";
47 + private static final String POP = "pop";
48 + private static final String PEEK = "peek";
49 +
45 private static final String ERROR_NULL_ENTRY = "Null entries are not allowed"; 50 private static final String ERROR_NULL_ENTRY = "Null entries are not allowed";
51 + private final MeteringAgent monitor;
46 52
47 public DefaultDistributedQueue(String name, 53 public DefaultDistributedQueue(String name,
48 Database database, 54 Database database,
49 Serializer serializer, 55 Serializer serializer,
50 NodeId localNodeId, 56 NodeId localNodeId,
57 + boolean meteringEnabled,
51 Consumer<Set<NodeId>> notifyConsumers) { 58 Consumer<Set<NodeId>> notifyConsumers) {
52 this.name = checkNotNull(name, "queue name cannot be null"); 59 this.name = checkNotNull(name, "queue name cannot be null");
53 this.database = checkNotNull(database, "database cannot be null"); 60 this.database = checkNotNull(database, "database cannot be null");
54 this.serializer = checkNotNull(serializer, "serializer cannot be null"); 61 this.serializer = checkNotNull(serializer, "serializer cannot be null");
55 this.localNodeId = localNodeId; 62 this.localNodeId = localNodeId;
56 this.notifyConsumers = notifyConsumers; 63 this.notifyConsumers = notifyConsumers;
64 + this.monitor = new MeteringAgent(PRIMITIVE_NAME, name, meteringEnabled);
65 +
57 } 66 }
58 67
59 @Override 68 @Override
60 public long size() { 69 public long size() {
70 + final MeteringAgent.Context timer = monitor.startTimer(SIZE);
71 + try {
61 return Futures.getUnchecked(database.queueSize(name)); 72 return Futures.getUnchecked(database.queueSize(name));
73 + } finally {
74 + timer.stop();
75 + }
62 } 76 }
63 77
64 @Override 78 @Override
65 public void push(E entry) { 79 public void push(E entry) {
80 + final MeteringAgent.Context timer = monitor.startTimer(PUSH);
81 + try {
66 checkNotNull(entry, ERROR_NULL_ENTRY); 82 checkNotNull(entry, ERROR_NULL_ENTRY);
67 Futures.getUnchecked(database.queuePush(name, serializer.encode(entry)) 83 Futures.getUnchecked(database.queuePush(name, serializer.encode(entry))
68 .thenAccept(notifyConsumers) 84 .thenAccept(notifyConsumers)
69 .thenApply(v -> null)); 85 .thenApply(v -> null));
86 + } finally {
87 + timer.stop();
88 + }
70 } 89 }
71 90
72 @Override 91 @Override
73 public CompletableFuture<E> pop() { 92 public CompletableFuture<E> pop() {
93 + final MeteringAgent.Context timer = monitor.startTimer(POP);
74 return database.queuePop(name, localNodeId) 94 return database.queuePop(name, localNodeId)
75 .thenCompose(v -> { 95 .thenCompose(v -> {
76 if (v != null) { 96 if (v != null) {
...@@ -80,13 +100,19 @@ public class DefaultDistributedQueue<E> implements DistributedQueue<E> { ...@@ -80,13 +100,19 @@ public class DefaultDistributedQueue<E> implements DistributedQueue<E> {
80 pendingFutures.add(newPendingFuture); 100 pendingFutures.add(newPendingFuture);
81 return newPendingFuture; 101 return newPendingFuture;
82 } 102 }
83 - }); 103 + })
104 + .whenComplete((r, e) -> timer.stop());
84 } 105 }
85 106
86 @Override 107 @Override
87 public E peek() { 108 public E peek() {
109 + final MeteringAgent.Context timer = monitor.startTimer(PEEK);
110 + try {
88 return Futures.getUnchecked(database.queuePeek(name) 111 return Futures.getUnchecked(database.queuePeek(name)
89 .thenApply(v -> v != null ? serializer.decode(v) : null)); 112 .thenApply(v -> v != null ? serializer.decode(v) : null));
113 + } finally {
114 + timer.stop();
115 + }
90 } 116 }
91 117
92 public String name() { 118 public String name() {
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import static com.google.common.base.Preconditions.checkArgument; 18 +import com.google.common.base.Charsets;
19 -import static com.google.common.base.Preconditions.checkState;
20 -
21 -import java.util.Set;
22 -import java.util.function.Consumer;
23 -
24 import org.onosproject.cluster.NodeId; 19 import org.onosproject.cluster.NodeId;
25 import org.onosproject.store.service.DistributedQueue; 20 import org.onosproject.store.service.DistributedQueue;
26 import org.onosproject.store.service.DistributedQueueBuilder; 21 import org.onosproject.store.service.DistributedQueueBuilder;
27 import org.onosproject.store.service.Serializer; 22 import org.onosproject.store.service.Serializer;
28 23
29 -import com.google.common.base.Charsets; 24 +import java.util.Set;
25 +import java.util.function.Consumer;
26 +
27 +import static com.google.common.base.Preconditions.checkArgument;
28 +import static com.google.common.base.Preconditions.checkState;
30 29
31 /** 30 /**
32 * Default implementation of a {@code DistributedQueueBuilder}. 31 * Default implementation of a {@code DistributedQueueBuilder}.
...@@ -39,6 +38,7 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde ...@@ -39,6 +38,7 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde
39 private String name; 38 private String name;
40 private boolean persistenceEnabled = true; 39 private boolean persistenceEnabled = true;
41 private final DatabaseManager databaseManager; 40 private final DatabaseManager databaseManager;
41 + private boolean metering = true;
42 42
43 public DefaultDistributedQueueBuilder( 43 public DefaultDistributedQueueBuilder(
44 DatabaseManager databaseManager) { 44 DatabaseManager databaseManager) {
...@@ -60,6 +60,12 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde ...@@ -60,6 +60,12 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde
60 } 60 }
61 61
62 @Override 62 @Override
63 + public DistributedQueueBuilder<E> withMeteringDisabled() {
64 + metering = false;
65 + return this;
66 + }
67 +
68 + @Override
63 public DistributedQueueBuilder<E> withPersistenceDisabled() { 69 public DistributedQueueBuilder<E> withPersistenceDisabled() {
64 persistenceEnabled = false; 70 persistenceEnabled = false;
65 return this; 71 return this;
...@@ -81,6 +87,7 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde ...@@ -81,6 +87,7 @@ public class DefaultDistributedQueueBuilder<E> implements DistributedQueueBuilde
81 persistenceEnabled ? databaseManager.partitionedDatabase : databaseManager.inMemoryDatabase, 87 persistenceEnabled ? databaseManager.partitionedDatabase : databaseManager.inMemoryDatabase,
82 serializer, 88 serializer,
83 databaseManager.localNodeId, 89 databaseManager.localNodeId,
90 + metering,
84 notifyOthers); 91 notifyOthers);
85 databaseManager.registerQueue(queue); 92 databaseManager.registerQueue(queue);
86 return queue; 93 return queue;
......
...@@ -15,11 +15,8 @@ ...@@ -15,11 +15,8 @@
15 */ 15 */
16 package org.onosproject.store.consistent.impl; 16 package org.onosproject.store.consistent.impl;
17 17
18 -import java.util.Collection; 18 +import com.google.common.collect.Maps;
19 -import java.util.Iterator; 19 +import com.google.common.collect.Sets;
20 -import java.util.Map;
21 -import java.util.Set;
22 -
23 import org.onosproject.store.service.ConsistentMap; 20 import org.onosproject.store.service.ConsistentMap;
24 import org.onosproject.store.service.DistributedSet; 21 import org.onosproject.store.service.DistributedSet;
25 import org.onosproject.store.service.MapEvent; 22 import org.onosproject.store.service.MapEvent;
...@@ -27,8 +24,10 @@ import org.onosproject.store.service.MapEventListener; ...@@ -27,8 +24,10 @@ import org.onosproject.store.service.MapEventListener;
27 import org.onosproject.store.service.SetEvent; 24 import org.onosproject.store.service.SetEvent;
28 import org.onosproject.store.service.SetEventListener; 25 import org.onosproject.store.service.SetEventListener;
29 26
30 -import com.google.common.collect.Maps; 27 +import java.util.Collection;
31 -import com.google.common.collect.Sets; 28 +import java.util.Iterator;
29 +import java.util.Map;
30 +import java.util.Set;
32 31
33 /** 32 /**
34 * Implementation of distributed set that is backed by a ConsistentMap. 33 * Implementation of distributed set that is backed by a ConsistentMap.
...@@ -37,73 +36,142 @@ import com.google.common.collect.Sets; ...@@ -37,73 +36,142 @@ import com.google.common.collect.Sets;
37 */ 36 */
38 public class DefaultDistributedSet<E> implements DistributedSet<E> { 37 public class DefaultDistributedSet<E> implements DistributedSet<E> {
39 38
39 + private static final String CONTAINS = "contains";
40 + private static final String PRIMITIVE_NAME = "distributedSet";
41 + private static final String SIZE = "size";
42 + private static final String IS_EMPTY = "isEmpty";
43 + private static final String ITERATOR = "iterator";
44 + private static final String TO_ARRAY = "toArray";
45 + private static final String ADD = "add";
46 + private static final String REMOVE = "remove";
47 + private static final String CONTAINS_ALL = "containsAll";
48 + private static final String ADD_ALL = "addAll";
49 + private static final String RETAIN_ALL = "retainAll";
50 + private static final String REMOVE_ALL = "removeAll";
51 + private static final String CLEAR = "clear";
52 +
40 private final String name; 53 private final String name;
41 private final ConsistentMap<E, Boolean> backingMap; 54 private final ConsistentMap<E, Boolean> backingMap;
42 private final Map<SetEventListener<E>, MapEventListener<E, Boolean>> listenerMapping = Maps.newIdentityHashMap(); 55 private final Map<SetEventListener<E>, MapEventListener<E, Boolean>> listenerMapping = Maps.newIdentityHashMap();
56 + private final MeteringAgent monitor;
43 57
44 - public DefaultDistributedSet(String name, ConsistentMap<E, Boolean> backingMap) { 58 + public DefaultDistributedSet(String name, boolean meteringEnabled, ConsistentMap<E, Boolean> backingMap) {
45 this.name = name; 59 this.name = name;
46 this.backingMap = backingMap; 60 this.backingMap = backingMap;
61 + monitor = new MeteringAgent(PRIMITIVE_NAME, name, meteringEnabled);
47 } 62 }
48 63
49 @Override 64 @Override
50 public int size() { 65 public int size() {
66 + final MeteringAgent.Context timer = monitor.startTimer(SIZE);
67 + try {
51 return backingMap.size(); 68 return backingMap.size();
69 + } finally {
70 + timer.stop();
71 + }
52 } 72 }
53 73
54 @Override 74 @Override
55 public boolean isEmpty() { 75 public boolean isEmpty() {
76 + final MeteringAgent.Context timer = monitor.startTimer(IS_EMPTY);
77 + try {
56 return backingMap.isEmpty(); 78 return backingMap.isEmpty();
79 + } finally {
80 + timer.stop();
81 + }
57 } 82 }
58 83
59 @SuppressWarnings("unchecked") 84 @SuppressWarnings("unchecked")
60 @Override 85 @Override
61 public boolean contains(Object o) { 86 public boolean contains(Object o) {
87 + final MeteringAgent.Context timer = monitor.startTimer(CONTAINS);
88 + try {
62 return backingMap.containsKey((E) o); 89 return backingMap.containsKey((E) o);
90 + } finally {
91 + timer.stop();
92 + }
63 } 93 }
64 94
65 @Override 95 @Override
66 public Iterator<E> iterator() { 96 public Iterator<E> iterator() {
97 + final MeteringAgent.Context timer = monitor.startTimer(ITERATOR);
98 + //Do we have to measure this guy?
99 + try {
67 return backingMap.keySet().iterator(); 100 return backingMap.keySet().iterator();
101 + } finally {
102 + timer.stop();
103 + }
68 } 104 }
69 105
70 @Override 106 @Override
71 public Object[] toArray() { 107 public Object[] toArray() {
108 + final MeteringAgent.Context timer = monitor.startTimer(TO_ARRAY);
109 + try {
72 return backingMap.keySet().stream().toArray(); 110 return backingMap.keySet().stream().toArray();
111 + } finally {
112 + timer.stop();
113 + }
73 } 114 }
74 115
75 @Override 116 @Override
76 public <T> T[] toArray(T[] a) { 117 public <T> T[] toArray(T[] a) {
118 + final MeteringAgent.Context timer = monitor.startTimer(TO_ARRAY);
119 + try {
77 return backingMap.keySet().stream().toArray(size -> a); 120 return backingMap.keySet().stream().toArray(size -> a);
121 + } finally {
122 + timer.stop();
123 + }
78 } 124 }
79 125
80 @Override 126 @Override
81 public boolean add(E e) { 127 public boolean add(E e) {
128 + final MeteringAgent.Context timer = monitor.startTimer(ADD);
129 + try {
82 return backingMap.putIfAbsent(e, true) == null; 130 return backingMap.putIfAbsent(e, true) == null;
131 + } finally {
132 + timer.stop();
133 + }
83 } 134 }
84 135
85 @SuppressWarnings("unchecked") 136 @SuppressWarnings("unchecked")
86 @Override 137 @Override
87 public boolean remove(Object o) { 138 public boolean remove(Object o) {
139 + final MeteringAgent.Context timer = monitor.startTimer(REMOVE);
140 + try {
88 return backingMap.remove((E) o) != null; 141 return backingMap.remove((E) o) != null;
142 + } finally {
143 + timer.stop();
144 + }
89 } 145 }
90 146
91 @Override 147 @Override
92 public boolean containsAll(Collection<?> c) { 148 public boolean containsAll(Collection<?> c) {
149 + final MeteringAgent.Context timer = monitor.startTimer(CONTAINS_ALL);
150 + try {
93 return c.stream() 151 return c.stream()
94 .allMatch(this::contains); 152 .allMatch(this::contains);
153 + } finally {
154 + timer.stop();
155 + }
95 } 156 }
96 157
97 @Override 158 @Override
98 public boolean addAll(Collection<? extends E> c) { 159 public boolean addAll(Collection<? extends E> c) {
160 + final MeteringAgent.Context timer = monitor.startTimer(ADD_ALL);
161 + try {
99 return c.stream() 162 return c.stream()
100 .map(this::add) 163 .map(this::add)
101 .reduce(Boolean::logicalOr) 164 .reduce(Boolean::logicalOr)
102 .orElse(false); 165 .orElse(false);
166 + } finally {
167 + timer.stop();
168 + }
103 } 169 }
104 170
105 @Override 171 @Override
106 public boolean retainAll(Collection<?> c) { 172 public boolean retainAll(Collection<?> c) {
173 + final MeteringAgent.Context timer = monitor.startTimer(RETAIN_ALL);
174 + try {
107 Set<?> retainSet = Sets.newHashSet(c); 175 Set<?> retainSet = Sets.newHashSet(c);
108 return backingMap.keySet() 176 return backingMap.keySet()
109 .stream() 177 .stream()
...@@ -111,10 +179,15 @@ public class DefaultDistributedSet<E> implements DistributedSet<E> { ...@@ -111,10 +179,15 @@ public class DefaultDistributedSet<E> implements DistributedSet<E> {
111 .map(this::remove) 179 .map(this::remove)
112 .reduce(Boolean::logicalOr) 180 .reduce(Boolean::logicalOr)
113 .orElse(false); 181 .orElse(false);
182 + } finally {
183 + timer.stop();
184 + }
114 } 185 }
115 186
116 @Override 187 @Override
117 public boolean removeAll(Collection<?> c) { 188 public boolean removeAll(Collection<?> c) {
189 + final MeteringAgent.Context timer = monitor.startTimer(REMOVE_ALL);
190 + try {
118 Set<?> removeSet = Sets.newHashSet(c); 191 Set<?> removeSet = Sets.newHashSet(c);
119 return backingMap.keySet() 192 return backingMap.keySet()
120 .stream() 193 .stream()
...@@ -122,11 +195,19 @@ public class DefaultDistributedSet<E> implements DistributedSet<E> { ...@@ -122,11 +195,19 @@ public class DefaultDistributedSet<E> implements DistributedSet<E> {
122 .map(this::remove) 195 .map(this::remove)
123 .reduce(Boolean::logicalOr) 196 .reduce(Boolean::logicalOr)
124 .orElse(false); 197 .orElse(false);
198 + } finally {
199 + timer.stop();
200 + }
125 } 201 }
126 202
127 @Override 203 @Override
128 public void clear() { 204 public void clear() {
205 + final MeteringAgent.Context timer = monitor.startTimer(CLEAR);
206 + try {
129 backingMap.clear(); 207 backingMap.clear();
208 + } finally {
209 + timer.stop();
210 + }
130 } 211 }
131 212
132 @Override 213 @Override
......
...@@ -30,9 +30,11 @@ public class DefaultDistributedSetBuilder<E> implements DistributedSetBuilder<E> ...@@ -30,9 +30,11 @@ public class DefaultDistributedSetBuilder<E> implements DistributedSetBuilder<E>
30 30
31 private String name; 31 private String name;
32 private ConsistentMapBuilder<E, Boolean> mapBuilder; 32 private ConsistentMapBuilder<E, Boolean> mapBuilder;
33 + private boolean metering = true;
33 34
34 public DefaultDistributedSetBuilder(DatabaseManager manager) { 35 public DefaultDistributedSetBuilder(DatabaseManager manager) {
35 this.mapBuilder = manager.consistentMapBuilder(); 36 this.mapBuilder = manager.consistentMapBuilder();
37 + mapBuilder.withMeteringDisabled();
36 } 38 }
37 39
38 @Override 40 @Override
...@@ -73,7 +75,13 @@ public class DefaultDistributedSetBuilder<E> implements DistributedSetBuilder<E> ...@@ -73,7 +75,13 @@ public class DefaultDistributedSetBuilder<E> implements DistributedSetBuilder<E>
73 } 75 }
74 76
75 @Override 77 @Override
78 + public DistributedSetBuilder<E> withMeteringDisabled() {
79 + metering = false;
80 + return this;
81 + }
82 +
83 + @Override
76 public DistributedSet<E> build() { 84 public DistributedSet<E> build() {
77 - return new DefaultDistributedSet<E>(name, mapBuilder.build()); 85 + return new DefaultDistributedSet<E>(name, metering, mapBuilder.build());
78 } 86 }
79 } 87 }
......
1 +package org.onosproject.store.consistent.impl;
2 +
3 +/*
4 + * Copyright 2015 Open Networking Laboratory
5 + *
6 + * Licensed under the Apache License, Version 2.0 (the "License");
7 + * you may not use this file except in compliance with the License.
8 + * You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing, software
13 + * distributed under the License is distributed on an "AS IS" BASIS,
14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 + * See the License for the specific language governing permissions and
16 + * limitations under the License.
17 + */
18 +
19 +import com.codahale.metrics.Timer;
20 +import com.google.common.collect.Maps;
21 +import org.onlab.metrics.MetricsComponent;
22 +import org.onlab.metrics.MetricsFeature;
23 +import org.onlab.metrics.MetricsService;
24 +import org.onlab.osgi.DefaultServiceDirectory;
25 +
26 +import java.util.Map;
27 +import java.util.concurrent.TimeUnit;
28 +
29 +import static com.google.common.base.Preconditions.checkNotNull;
30 +
31 +/**
32 + * Agent that implements usage and performance monitoring via the metrics service.
33 + */
34 +public class MeteringAgent {
35 +
36 + private MetricsService metricsService;
37 + private MetricsComponent metricsComponent;
38 + private MetricsFeature metricsFeature;
39 + private final Map<String, Timer> perObjOpTimers = Maps.newConcurrentMap();
40 + private final Map<String, Timer> perOpTimers = Maps.newConcurrentMap();
41 + private Timer perPrimitiveTimer;
42 + private Timer perObjTimer;
43 + private MetricsFeature wildcard;
44 + private final boolean activated;
45 + private Context nullTimer;
46 +
47 + /**
48 + * Constructs a new MeteringAgent for a given distributed primitive.
49 + * Instantiates the metrics service
50 + * Initializes all the general metrics for that object
51 + *
52 + * @param primitiveName Type of primitive to be metered
53 + * @param objName Global name of the primitive
54 + * @param activated
55 + */
56 + public MeteringAgent(String primitiveName, String objName, boolean activated) {
57 + checkNotNull(objName, "Object name cannot be null");
58 + this.activated = activated;
59 + nullTimer = new Context(null, "");
60 + if (this.activated) {
61 + this.metricsService = DefaultServiceDirectory.getService(MetricsService.class);
62 + this.metricsComponent = metricsService.registerComponent(primitiveName);
63 + this.metricsFeature = metricsComponent.registerFeature(objName);
64 + this.wildcard = metricsComponent.registerFeature("*");
65 + this.perObjTimer = metricsService.createTimer(metricsComponent, metricsFeature, "*");
66 + this.perPrimitiveTimer = metricsService.createTimer(metricsComponent, wildcard, "*");
67 + }
68 + }
69 +
70 + /**
71 + * Initializes a specific timer for a given operation.
72 + *
73 + * @param op Specific operation being metered
74 + */
75 + public Context startTimer(String op) {
76 + if (!activated) {
77 + return nullTimer;
78 + }
79 + // Check if timer exists, if it doesn't creates it
80 + final Timer currTimer = perObjOpTimers.computeIfAbsent(op, timer ->
81 + metricsService.createTimer(metricsComponent, metricsFeature, op));
82 + perOpTimers.computeIfAbsent(op, timer -> metricsService.createTimer(metricsComponent, wildcard, op));
83 + // Starts timer
84 + return new Context(currTimer.time(), op);
85 + }
86 +
87 + /**
88 + * Timer.Context with a specific operation.
89 + */
90 + public class Context {
91 + private final Timer.Context context;
92 + private final String operation;
93 +
94 + /**
95 + * Constructs Context.
96 + *
97 + * @param context
98 + * @param operation
99 + */
100 + public Context(Timer.Context context, String operation) {
101 + this.context = context;
102 + this.operation = operation;
103 + }
104 +
105 + /**
106 + * Stops timer given a specific context and updates all related metrics.
107 + */
108 + public void stop() {
109 + if (!activated) {
110 + return;
111 + }
112 + //Stop and updates timer with specific measurements per map, per operation
113 + final long time = context.stop();
114 + //updates timer with aggregated measurements per map
115 + perOpTimers.get(operation).update(time, TimeUnit.NANOSECONDS);
116 + //updates timer with aggregated measurements per map
117 + perObjTimer.update(time, TimeUnit.NANOSECONDS);
118 + //updates timer with aggregated measurements per all Consistent Maps
119 + perPrimitiveTimer.update(time, TimeUnit.NANOSECONDS);
120 + }
121 + }
122 +
123 +}