Extract common metric Buffer code
Extract common features from CounterBuffers and GuageBuffers into a shared superclass. The new extracted types allows the service implementations to be simplified. Fixes gh-3257
This commit is contained in:
parent
291388affe
commit
134bc02404
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or 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 org.springframework.boot.actuate.metrics.buffer;
|
||||
|
||||
/**
|
||||
* Base class for a mutable buffer containing a timestamp and a value.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @param <T> The value type
|
||||
*/
|
||||
abstract class Buffer<T extends Number> {
|
||||
|
||||
private volatile long timestamp;
|
||||
|
||||
public Buffer(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer value.
|
||||
* @return the value of the buffer
|
||||
*/
|
||||
public abstract T getValue();
|
||||
|
||||
}
|
||||
|
|
@ -32,29 +32,29 @@ public class BufferCounterService implements CounterService {
|
|||
|
||||
private final ConcurrentHashMap<String, String> names = new ConcurrentHashMap<String, String>();
|
||||
|
||||
private final CounterBuffers writer;
|
||||
private final CounterBuffers buffers;
|
||||
|
||||
/**
|
||||
* Create a {@link BufferCounterService} instance.
|
||||
* @param writer the underlying writer used to manage metrics
|
||||
* @param buffers the underlying buffers used to store metrics
|
||||
*/
|
||||
public BufferCounterService(CounterBuffers writer) {
|
||||
this.writer = writer;
|
||||
public BufferCounterService(CounterBuffers buffers) {
|
||||
this.buffers = buffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(String metricName) {
|
||||
this.writer.increment(wrap(metricName), 1L);
|
||||
this.buffers.increment(wrap(metricName), 1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrement(String metricName) {
|
||||
this.writer.increment(wrap(metricName), -1L);
|
||||
this.buffers.increment(wrap(metricName), -1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(String metricName) {
|
||||
this.writer.reset(wrap(metricName));
|
||||
this.buffers.reset(wrap(metricName));
|
||||
}
|
||||
|
||||
private String wrap(String metricName) {
|
||||
|
|
|
|||
|
|
@ -32,19 +32,19 @@ public class BufferGaugeService implements GaugeService {
|
|||
|
||||
private final ConcurrentHashMap<String, String> names = new ConcurrentHashMap<String, String>();
|
||||
|
||||
private final GaugeBuffers writer;
|
||||
private final GaugeBuffers buffers;
|
||||
|
||||
/**
|
||||
* Create a {@link BufferGaugeService} instance.
|
||||
* @param writer the underlying writer used to manage metrics
|
||||
* @param buffers the underlying buffers used to store metrics
|
||||
*/
|
||||
public BufferGaugeService(GaugeBuffers writer) {
|
||||
this.writer = writer;
|
||||
public BufferGaugeService(GaugeBuffers buffers) {
|
||||
this.buffers = buffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(String metricName, double value) {
|
||||
this.writer.set(wrap(metricName), value);
|
||||
this.buffers.set(wrap(metricName), value);
|
||||
}
|
||||
|
||||
private String wrap(String metricName) {
|
||||
|
|
|
|||
|
|
@ -38,35 +38,29 @@ import org.springframework.lang.UsesJava8;
|
|||
@UsesJava8
|
||||
public class BufferMetricReader implements MetricReader, PrefixMetricReader {
|
||||
|
||||
private final CounterBuffers counters;
|
||||
private static final Predicate<String> ALL = Pattern.compile(".*").asPredicate();
|
||||
|
||||
private final GaugeBuffers gauges;
|
||||
private final CounterBuffers counterBuffers;
|
||||
|
||||
private final Predicate<String> all = Pattern.compile(".*").asPredicate();
|
||||
private final GaugeBuffers gaugeBuffers;
|
||||
|
||||
public BufferMetricReader(CounterBuffers counters, GaugeBuffers gauges) {
|
||||
this.counters = counters;
|
||||
this.gauges = gauges;
|
||||
public BufferMetricReader(CounterBuffers counterBuffers, GaugeBuffers gaugeBuffers) {
|
||||
this.counterBuffers = counterBuffers;
|
||||
this.gaugeBuffers = gaugeBuffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric<?> findOne(final String name) {
|
||||
LongBuffer buffer = this.counters.find(name);
|
||||
if (buffer != null) {
|
||||
return new Metric<Long>(name, buffer.getValue(), new Date(
|
||||
buffer.getTimestamp()));
|
||||
Buffer<?> buffer = this.counterBuffers.find(name);
|
||||
if (buffer == null) {
|
||||
buffer = this.gaugeBuffers.find(name);
|
||||
}
|
||||
DoubleBuffer doubleValue = this.gauges.find(name);
|
||||
if (doubleValue != null) {
|
||||
return new Metric<Double>(name, doubleValue.getValue(), new Date(
|
||||
doubleValue.getTimestamp()));
|
||||
}
|
||||
return null;
|
||||
return (buffer == null ? null : asMetric(name, buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Metric<?>> findAll() {
|
||||
return findAll(this.all);
|
||||
return findAll(BufferMetricReader.ALL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -76,30 +70,30 @@ public class BufferMetricReader implements MetricReader, PrefixMetricReader {
|
|||
|
||||
@Override
|
||||
public long count() {
|
||||
return this.counters.count() + this.gauges.count();
|
||||
return this.counterBuffers.count() + this.gaugeBuffers.count();
|
||||
}
|
||||
|
||||
private Iterable<Metric<?>> findAll(Predicate<String> predicate) {
|
||||
final List<Metric<?>> metrics = new ArrayList<Metric<?>>();
|
||||
this.counters.forEach(predicate, new BiConsumer<String, LongBuffer>() {
|
||||
|
||||
@Override
|
||||
public void accept(String name, LongBuffer value) {
|
||||
metrics.add(new Metric<Long>(name, value.getValue(), new Date(value
|
||||
.getTimestamp())));
|
||||
}
|
||||
|
||||
});
|
||||
this.gauges.forEach(predicate, new BiConsumer<String, DoubleBuffer>() {
|
||||
|
||||
@Override
|
||||
public void accept(String name, DoubleBuffer value) {
|
||||
metrics.add(new Metric<Double>(name, value.getValue(), new Date(value
|
||||
.getTimestamp())));
|
||||
}
|
||||
|
||||
});
|
||||
collectMetrics(this.gaugeBuffers, predicate, metrics);
|
||||
collectMetrics(this.counterBuffers, predicate, metrics);
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private <T extends Number, B extends Buffer<T>> void collectMetrics(
|
||||
Buffers<B> buffers, Predicate<String> predicate, final List<Metric<?>> metrics) {
|
||||
buffers.forEach(predicate, new BiConsumer<String, B>() {
|
||||
|
||||
@Override
|
||||
public void accept(String name, B value) {
|
||||
metrics.add(asMetric(name, value));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private <T extends Number> Metric<T> asMetric(final String name, Buffer<T> buffer) {
|
||||
return new Metric<T>(name, buffer.getValue(), new Date(buffer.getTimestamp()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or 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 org.springframework.boot.actuate.metrics.buffer;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Base class used to manage a map of {@link Buffer} objects.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @param <B> The buffer type
|
||||
*/
|
||||
@UsesJava8
|
||||
abstract class Buffers<B extends Buffer<?>> {
|
||||
|
||||
private final ConcurrentHashMap<String, B> buffers = new ConcurrentHashMap<String, B>();
|
||||
|
||||
public void forEach(final Predicate<String> predicate,
|
||||
final BiConsumer<String, B> consumer) {
|
||||
this.buffers.forEach(new BiConsumer<String, B>() {
|
||||
|
||||
@Override
|
||||
public void accept(String name, B value) {
|
||||
if (predicate.test(name)) {
|
||||
consumer.accept(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public B find(final String name) {
|
||||
return this.buffers.get(name);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return this.buffers.size();
|
||||
}
|
||||
|
||||
protected final void doWith(final String name, final Consumer<B> consumer) {
|
||||
B buffer = this.buffers.get(name);
|
||||
if (buffer == null) {
|
||||
buffer = this.buffers.computeIfAbsent(name, new Function<String, B>() {
|
||||
@Override
|
||||
public B apply(String name) {
|
||||
return createBuffer();
|
||||
}
|
||||
});
|
||||
}
|
||||
consumer.accept(buffer);
|
||||
}
|
||||
|
||||
protected abstract B createBuffer();
|
||||
|
||||
}
|
||||
|
|
@ -27,35 +27,26 @@ import org.springframework.lang.UsesJava8;
|
|||
* @since 1.3.0
|
||||
*/
|
||||
@UsesJava8
|
||||
public class LongBuffer {
|
||||
public class CounterBuffer extends Buffer<Long> {
|
||||
|
||||
private final LongAdder adder;
|
||||
|
||||
private volatile long timestamp;
|
||||
|
||||
public LongBuffer(long timestamp) {
|
||||
public CounterBuffer(long timestamp) {
|
||||
super(timestamp);
|
||||
this.adder = new LongAdder();
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return this.adder.sum();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.adder.reset();
|
||||
}
|
||||
|
||||
public void add(long delta) {
|
||||
this.adder.add(delta);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.adder.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue() {
|
||||
return this.adder.sum();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,93 +16,46 @@
|
|||
|
||||
package org.springframework.boot.actuate.metrics.buffer;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Fast writes to in-memory metrics store using {@link LongBuffer}.
|
||||
* Fast writes to in-memory metrics store using {@link CounterBuffer}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@UsesJava8
|
||||
public class CounterBuffers {
|
||||
|
||||
private final ConcurrentHashMap<String, LongBuffer> metrics = new ConcurrentHashMap<String, LongBuffer>();
|
||||
|
||||
public void forEach(final Predicate<String> predicate,
|
||||
final BiConsumer<String, LongBuffer> consumer) {
|
||||
this.metrics.forEach(new BiConsumer<String, LongBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, LongBuffer value) {
|
||||
if (predicate.test(name)) {
|
||||
consumer.accept(name, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public LongBuffer find(final String name) {
|
||||
return this.metrics.get(name);
|
||||
}
|
||||
|
||||
public void get(final String name, final Consumer<LongBuffer> consumer) {
|
||||
read(name, consumer);
|
||||
}
|
||||
public class CounterBuffers extends Buffers<CounterBuffer> {
|
||||
|
||||
public void increment(final String name, final long delta) {
|
||||
write(name, new Consumer<LongBuffer>() {
|
||||
doWith(name, new Consumer<CounterBuffer>() {
|
||||
|
||||
@Override
|
||||
public void accept(LongBuffer adder) {
|
||||
adder.add(delta);
|
||||
public void accept(CounterBuffer buffer) {
|
||||
buffer.setTimestamp(System.currentTimeMillis());
|
||||
buffer.add(delta);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void reset(final String name) {
|
||||
write(name, new Consumer<LongBuffer>() {
|
||||
doWith(name, new Consumer<CounterBuffer>() {
|
||||
|
||||
@Override
|
||||
public void accept(LongBuffer adder) {
|
||||
adder.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return this.metrics.size();
|
||||
}
|
||||
|
||||
private void read(final String name, final Consumer<LongBuffer> consumer) {
|
||||
acceptInternal(name, consumer);
|
||||
}
|
||||
|
||||
private void write(final String name, final Consumer<LongBuffer> consumer) {
|
||||
acceptInternal(name, new Consumer<LongBuffer>() {
|
||||
@Override
|
||||
public void accept(LongBuffer buffer) {
|
||||
public void accept(CounterBuffer buffer) {
|
||||
buffer.setTimestamp(System.currentTimeMillis());
|
||||
consumer.accept(buffer);
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void acceptInternal(final String name, final Consumer<LongBuffer> consumer) {
|
||||
LongBuffer adder;
|
||||
if (null == (adder = this.metrics.get(name))) {
|
||||
adder = this.metrics.computeIfAbsent(name,
|
||||
new Function<String, LongBuffer>() {
|
||||
@Override
|
||||
public LongBuffer apply(String name) {
|
||||
return new LongBuffer(0L);
|
||||
}
|
||||
});
|
||||
}
|
||||
consumer.accept(adder);
|
||||
@Override
|
||||
protected CounterBuffer createBuffer() {
|
||||
return new CounterBuffer(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,22 +22,17 @@ package org.springframework.boot.actuate.metrics.buffer;
|
|||
* @author Dave Syer
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public class DoubleBuffer {
|
||||
public class GaugeBuffer extends Buffer<Double> {
|
||||
|
||||
private volatile double value;
|
||||
|
||||
private volatile long timestamp;
|
||||
|
||||
public DoubleBuffer(long timestamp) {
|
||||
public GaugeBuffer(long timestamp) {
|
||||
super(timestamp);
|
||||
this.value = 0;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
@Override
|
||||
public Double getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
|
|
@ -45,8 +40,4 @@ public class DoubleBuffer {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,79 +16,32 @@
|
|||
|
||||
package org.springframework.boot.actuate.metrics.buffer;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.lang.UsesJava8;
|
||||
|
||||
/**
|
||||
* Fast writes to in-memory metrics store using {@link DoubleBuffer}.
|
||||
* Fast writes to in-memory metrics store using {@link GaugeBuffer}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@UsesJava8
|
||||
public class GaugeBuffers {
|
||||
|
||||
private final ConcurrentHashMap<String, DoubleBuffer> metrics = new ConcurrentHashMap<String, DoubleBuffer>();
|
||||
|
||||
public void forEach(final Predicate<String> predicate,
|
||||
final BiConsumer<String, DoubleBuffer> consumer) {
|
||||
this.metrics.forEach(new BiConsumer<String, DoubleBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, DoubleBuffer value) {
|
||||
if (predicate.test(name)) {
|
||||
consumer.accept(name, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DoubleBuffer find(final String name) {
|
||||
return this.metrics.get(name);
|
||||
}
|
||||
|
||||
public void get(final String name, final Consumer<DoubleBuffer> consumer) {
|
||||
acceptInternal(name, consumer);
|
||||
}
|
||||
public class GaugeBuffers extends Buffers<GaugeBuffer> {
|
||||
|
||||
public void set(final String name, final double value) {
|
||||
write(name, value);
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return this.metrics.size();
|
||||
}
|
||||
|
||||
private void write(final String name, final double value) {
|
||||
acceptInternal(name, new Consumer<DoubleBuffer>() {
|
||||
doWith(name, new Consumer<GaugeBuffer>() {
|
||||
@Override
|
||||
public void accept(DoubleBuffer buffer) {
|
||||
public void accept(GaugeBuffer buffer) {
|
||||
buffer.setTimestamp(System.currentTimeMillis());
|
||||
buffer.setValue(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void reset(String name) {
|
||||
this.metrics.remove(name, this.metrics.get(name));
|
||||
}
|
||||
|
||||
private void acceptInternal(final String name, final Consumer<DoubleBuffer> consumer) {
|
||||
DoubleBuffer value;
|
||||
if (null == (value = this.metrics.get(name))) {
|
||||
value = this.metrics.computeIfAbsent(name,
|
||||
new Function<String, DoubleBuffer>() {
|
||||
@Override
|
||||
public DoubleBuffer apply(String tag) {
|
||||
return new DoubleBuffer(0L);
|
||||
}
|
||||
});
|
||||
}
|
||||
consumer.accept(value);
|
||||
@Override
|
||||
protected GaugeBuffer createBuffer() {
|
||||
return new GaugeBuffer(0L);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,18 +99,18 @@ public class BufferGaugeServiceSpeedTests {
|
|||
watch.start("readRaw" + count);
|
||||
for (String name : names) {
|
||||
this.gauges.forEach(Pattern.compile(name).asPredicate(),
|
||||
new BiConsumer<String, DoubleBuffer>() {
|
||||
new BiConsumer<String, GaugeBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, DoubleBuffer value) {
|
||||
public void accept(String name, GaugeBuffer value) {
|
||||
err.println(name + "=" + value);
|
||||
}
|
||||
});
|
||||
}
|
||||
final DoubleAdder total = new DoubleAdder();
|
||||
this.gauges.forEach(Pattern.compile(".*").asPredicate(),
|
||||
new BiConsumer<String, DoubleBuffer>() {
|
||||
new BiConsumer<String, GaugeBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, DoubleBuffer value) {
|
||||
public void accept(String name, GaugeBuffer value) {
|
||||
total.add(value.getValue());
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ public class CounterBuffersTests {
|
|||
@Test
|
||||
public void inAndOut() {
|
||||
this.buffers.increment("foo", 2);
|
||||
this.buffers.get("foo", new Consumer<LongBuffer>() {
|
||||
this.buffers.doWith("foo", new Consumer<CounterBuffer>() {
|
||||
@Override
|
||||
public void accept(LongBuffer buffer) {
|
||||
public void accept(CounterBuffer buffer) {
|
||||
CounterBuffersTests.this.value = buffer.getValue();
|
||||
}
|
||||
});
|
||||
|
|
@ -48,9 +48,9 @@ public class CounterBuffersTests {
|
|||
|
||||
@Test
|
||||
public void getNonExistent() {
|
||||
this.buffers.get("foo", new Consumer<LongBuffer>() {
|
||||
this.buffers.doWith("foo", new Consumer<CounterBuffer>() {
|
||||
@Override
|
||||
public void accept(LongBuffer buffer) {
|
||||
public void accept(CounterBuffer buffer) {
|
||||
CounterBuffersTests.this.value = buffer.getValue();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -98,18 +98,18 @@ public class CounterServiceSpeedTests {
|
|||
watch.start("readRaw" + count);
|
||||
for (String name : names) {
|
||||
this.counters.forEach(Pattern.compile(name).asPredicate(),
|
||||
new BiConsumer<String, LongBuffer>() {
|
||||
new BiConsumer<String, CounterBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, LongBuffer value) {
|
||||
public void accept(String name, CounterBuffer value) {
|
||||
err.println(name + "=" + value);
|
||||
}
|
||||
});
|
||||
}
|
||||
final LongAdder total = new LongAdder();
|
||||
this.counters.forEach(Pattern.compile(".*").asPredicate(),
|
||||
new BiConsumer<String, LongBuffer>() {
|
||||
new BiConsumer<String, CounterBuffer>() {
|
||||
@Override
|
||||
public void accept(String name, LongBuffer value) {
|
||||
public void accept(String name, CounterBuffer value) {
|
||||
total.add(value.getValue());
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue