Skip to content

Commit a66f26a

Browse files
author
Ravindra Dingankar
committed
Address review comments
1 parent 056a473 commit a66f26a

File tree

6 files changed

+69
-36
lines changed

6 files changed

+69
-36
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsRegistry.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,7 @@ public synchronized MutableGaugeFloat newGauge(MetricsInfo info, float iVal) {
216216
*/
217217
public synchronized MutableQuantiles newQuantiles(String name, String desc,
218218
String sampleName, String valueName, int interval) {
219-
checkMetricName(name);
220-
if (interval <= 0) {
221-
throw new MetricsException("Interval should be positive. Value passed" +
222-
" is: " + interval);
223-
}
224-
MutableQuantiles ret =
225-
new MutableQuantiles(name, desc, sampleName, valueName, interval);
226-
metricsMap.put(name, ret);
227-
return ret;
219+
return newQuantiles(name, desc, sampleName, valueName, interval, false);
228220
}
229221

230222
/**
@@ -238,11 +230,16 @@ public synchronized MutableQuantiles newQuantiles(String name, String desc,
238230
* @return a new quantile estimator object
239231
* @throws MetricsException if interval is not a positive integer
240232
*/
241-
public synchronized MutableQuantiles newQuantiles(String name, String desc, String sampleName,
242-
String valueName, int interval, boolean inverseQuantiles) {
243-
MutableQuantiles ret = newQuantiles(name, desc, sampleName, valueName, interval);
244-
ret.inverseQuantiles = inverseQuantiles;
245-
return ret;
233+
public synchronized MutableQuantiles newQuantiles(String name, String desc, String sampleName, String valueName,
234+
int interval, boolean inverseQuantiles) {
235+
checkMetricName(name);
236+
if (interval <= 0) {
237+
throw new MetricsException("Interval should be positive. Value passed is: " + interval);
238+
}
239+
MutableQuantiles ret =
240+
new MutableQuantiles(name, desc, sampleName, valueName, interval, inverseQuantiles);
241+
metricsMap.put(name, ret);
242+
return ret;
246243
}
247244

248245
/**

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MutableQuantiles.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.hadoop.classification.InterfaceStability;
3232
import org.apache.hadoop.metrics2.MetricsInfo;
3333
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
34+
import org.apache.hadoop.metrics2.util.InverseQuantiles;
3435
import org.apache.hadoop.metrics2.util.Quantile;
3536
import org.apache.hadoop.metrics2.util.QuantileEstimator;
3637
import org.apache.hadoop.metrics2.util.SampleQuantiles;
@@ -52,7 +53,6 @@ public class MutableQuantiles extends MutableMetric {
5253
new Quantile(0.75, 0.025), new Quantile(0.90, 0.010),
5354
new Quantile(0.95, 0.005), new Quantile(0.99, 0.001) };
5455

55-
protected boolean inverseQuantiles = false;
5656
private final MetricsInfo numInfo;
5757
private final MetricsInfo[] quantileInfos;
5858
private final int interval;
@@ -84,7 +84,7 @@ public class MutableQuantiles extends MutableMetric {
8484
* rollover interval (in seconds) of the estimator
8585
*/
8686
public MutableQuantiles(String name, String description, String sampleName,
87-
String valueName, int interval) {
87+
String valueName, int interval, boolean inverseQuantiles) {
8888
String ucName = StringUtils.capitalize(name);
8989
String usName = StringUtils.capitalize(sampleName);
9090
String uvName = StringUtils.capitalize(valueName);
@@ -105,8 +105,7 @@ public MutableQuantiles(String name, String description, String sampleName,
105105
String.format(descTemplate, percentile));
106106
}
107107

108-
estimator = new SampleQuantiles(quantiles, inverseQuantiles);
109-
108+
estimator = inverseQuantiles ? new InverseQuantiles(quantiles) : new SampleQuantiles(quantiles);
110109
this.interval = interval;
111110
scheduledTask = scheduler.scheduleWithFixedDelay(new RolloverSample(this),
112111
interval, interval, TimeUnit.SECONDS);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.apache.hadoop.metrics2.util;
2+
3+
import org.apache.hadoop.util.Preconditions;
4+
import java.util.ListIterator;
5+
6+
public class InverseQuantiles extends SampleQuantiles{
7+
8+
public InverseQuantiles(Quantile[] quantiles) {
9+
super(quantiles);
10+
}
11+
12+
13+
/**
14+
* Get the estimated value at the inverse of the specified quantile.
15+
* Eg: return the value at (1 - 0.99)*count position for quantile 0.99.
16+
* When count is 100, quantile 0.99 is desired to return the value at the 1st position
17+
*
18+
* @param quantile Queried quantile, e.g. 0.50 or 0.99.
19+
* @return Estimated value at the inverse position of that quantile.
20+
*/
21+
long query(double quantile) {
22+
Preconditions.checkState(!samples.isEmpty(), "no data in estimator");
23+
24+
int rankMin = 0;
25+
int desired = (int) ((1 - quantile) * count);
26+
27+
ListIterator<SampleItem> it = samples.listIterator();
28+
SampleItem prev;
29+
SampleItem cur = it.next();
30+
for (int i = 1; i < samples.size(); i++) {
31+
prev = cur;
32+
cur = it.next();
33+
34+
rankMin += prev.g;
35+
36+
if (rankMin + cur.g + cur.delta > desired + (allowableError(i) / 2)) {
37+
return prev.value;
38+
}
39+
}
40+
41+
// edge case of wanting max value
42+
return samples.get(0).value;
43+
}
44+
}

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/util/SampleQuantiles.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ public class SampleQuantiles implements QuantileEstimator {
5252
/**
5353
* Total number of items in stream
5454
*/
55-
private long count = 0;
55+
long count = 0;
5656

5757
/**
5858
* Current list of sampled items, maintained in sorted order with error bounds
5959
*/
60-
private LinkedList<SampleItem> samples;
60+
LinkedList<SampleItem> samples;
6161

6262
/**
6363
* Buffers incoming items to be inserted in batch. Items are inserted into
@@ -71,11 +71,9 @@ public class SampleQuantiles implements QuantileEstimator {
7171
* Array of Quantiles that we care about, along with desired error.
7272
*/
7373
private final Quantile quantiles[];
74-
private boolean inverseQuantiles;
7574

76-
public SampleQuantiles(Quantile[] quantiles, boolean inverseQuantiles) {
75+
public SampleQuantiles(Quantile[] quantiles) {
7776
this.quantiles = quantiles;
78-
this. inverseQuantiles = inverseQuantiles;
7977
this.samples = new LinkedList<SampleItem>();
8078
}
8179

@@ -89,7 +87,7 @@ public SampleQuantiles(Quantile[] quantiles, boolean inverseQuantiles) {
8987
* @param rank
9088
* the index in the list of samples
9189
*/
92-
private double allowableError(int rank) {
90+
double allowableError(int rank) {
9391
int size = samples.size();
9492
double minError = size + 1;
9593
for (Quantile q : quantiles) {
@@ -202,10 +200,10 @@ private void compress() {
202200
/**
203201
* Get the estimated value at the specified quantile.
204202
*
205-
* @param quantile Queried quantile, e.g. 0.01, 0.50 or 0.99.
203+
* @param quantile Queried quantile, e.g. 0.50 or 0.99.
206204
* @return Estimated value at that quantile.
207205
*/
208-
private long query(double quantile) {
206+
long query(double quantile) {
209207
Preconditions.checkState(!samples.isEmpty(), "no data in estimator");
210208

211209
int rankMin = 0;
@@ -245,12 +243,7 @@ synchronized public Map<Quantile, Long> snapshot() {
245243

246244
Map<Quantile, Long> values = new TreeMap<Quantile, Long>();
247245
for (int i = 0; i < quantiles.length; i++) {
248-
/* eg : effectiveQuantile for 0.99 with inverseQuantiles will be 0.01.
249-
For inverse quantiles higher numeric value is better and hence we want
250-
to query from the opposite end of the sorted sample
251-
*/
252-
double effectiveQuantile = inverseQuantiles ? 1 - quantiles[i].quantile : quantiles[i].quantile;
253-
values.put(quantiles[i], query(effectiveQuantile));
246+
values.put(quantiles[i], query(quantiles[i].quantile));
254247
}
255248

256249
return values;
@@ -298,7 +291,7 @@ synchronized public String toString() {
298291
* Describes a measured value passed to the estimator, tracking additional
299292
* metadata required by the CKMS algorithm.
300293
*/
301-
private static class SampleItem {
294+
static class SampleItem {
302295

303296
/**
304297
* Value of the sampled item (e.g. a measured latency value)

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/metrics2/util/TestSampleQuantiles.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class TestSampleQuantiles {
3939

4040
@Before
4141
public void init() {
42-
estimator = new SampleQuantiles(quantiles, false);
42+
estimator = new SampleQuantiles(quantiles);
4343
}
4444

4545
/**
@@ -121,7 +121,7 @@ public void testQuantileError() throws IOException {
121121

122122
@Test
123123
public void testInverseQuantiles() {
124-
SampleQuantiles estimatorWithInverseQuantiles = new SampleQuantiles(quantiles, true);
124+
SampleQuantiles estimatorWithInverseQuantiles = new InverseQuantiles(quantiles);
125125
final int count = 100000;
126126
Random r = new Random(0xDEADDEAD);
127127
Long[] values = new Long[count];

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestMultiThreadedHflush.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class TestMultiThreadedHflush {
5353
new Quantile[] {
5454
new Quantile(0.50, 0.050),
5555
new Quantile(0.75, 0.025), new Quantile(0.90, 0.010),
56-
new Quantile(0.95, 0.005), new Quantile(0.99, 0.001) }, false);
56+
new Quantile(0.95, 0.005), new Quantile(0.99, 0.001) });
5757

5858
/*
5959
* creates a file but does not close it

0 commit comments

Comments
 (0)