1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.metrics;
20
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.List;
24 import java.util.Map.Entry;
25 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.ConcurrentMap;
27 import java.util.concurrent.locks.ReadWriteLock;
28 import java.util.concurrent.locks.ReentrantReadWriteLock;
29
30 import org.apache.hadoop.hbase.util.Pair;
31 import org.apache.hadoop.metrics.MetricsRecord;
32 import org.apache.hadoop.metrics.util.MetricsBase;
33 import org.apache.hadoop.metrics.util.MetricsRegistry;
34 import org.cliffc.high_scale_lib.Counter;
35
36 import com.google.common.collect.Lists;
37
38 @Deprecated
39 public class ExactCounterMetric extends MetricsBase {
40
41 private static final int DEFAULT_TOP_N = 5;
42
43
44 private final int topN;
45 private final ConcurrentMap<String, Counter> counts = new ConcurrentHashMap<String, Counter>();
46
47
48
49
50
51 private final ReadWriteLock lock;
52
53
54
55
56
57
58
59
60 public ExactCounterMetric(final String nam, final MetricsRegistry registry,
61 final String description, int topN) {
62 super(nam, description);
63
64 this.lock = new ReentrantReadWriteLock();
65 this.topN = topN;
66
67 if (registry != null) {
68 registry.add(nam, this);
69 }
70 }
71
72
73
74
75
76
77 public ExactCounterMetric(final String nam, MetricsRegistry registry) {
78 this(nam, registry, NO_DESCRIPTION, DEFAULT_TOP_N);
79 }
80
81
82
83
84 private Counter getOrCreateCounter(String type){
85 Counter cnt = counts.get(type);
86 if (cnt == null){
87 cnt = new Counter();
88 counts.put(type, cnt);
89 }
90 return cnt;
91 }
92
93 public void update(String type) {
94 this.lock.readLock().lock();
95 try {
96 getOrCreateCounter(type).increment();
97 } finally {
98 this.lock.readLock().unlock();
99 }
100 }
101
102 public void update(String type, long count) {
103 this.lock.readLock().lock();
104 try {
105 getOrCreateCounter(type).add(count);
106 } finally {
107 this.lock.readLock().unlock();
108 }
109 }
110
111 public List<Pair<String, Long>> getTop(int n) {
112 final List<Pair<String, Long>> countsSnapshot =
113 Lists.newArrayListWithCapacity(this.counts.size());
114
115
116 this.lock.writeLock().lock();
117 try {
118 for(Entry<String, Counter> entry : this.counts.entrySet()) {
119 countsSnapshot.add(Pair.newPair(entry.getKey(),
120 entry.getValue().get()));
121 }
122 } finally {
123 this.lock.writeLock().unlock();
124 }
125
126 Collections.sort(countsSnapshot, new Comparator<Pair<String, Long>>() {
127 @Override
128 public int compare(Pair<String, Long> a, Pair<String, Long> b) {
129 return b.getSecond().compareTo(a.getSecond());
130 }
131 });
132
133 return countsSnapshot.subList(0, Math.min(n, countsSnapshot.size()));
134 }
135
136 @Override
137 public void pushMetric(MetricsRecord mr) {
138 final List<Pair<String, Long>> topKeys = getTop(Integer.MAX_VALUE);
139 int sum = 0;
140
141 int counter = 0;
142 for (Pair<String, Long> keyCount : topKeys) {
143 counter++;
144
145 if (counter <= this.topN) {
146 mr.setMetric(getName() + "_" + keyCount.getFirst(),
147 keyCount.getSecond());
148 }
149 sum += keyCount.getSecond();
150 }
151 mr.setMetric(getName() + "_map_size", this.counts.size());
152 mr.setMetric(getName() + "_total_count", sum);
153 }
154
155 }