1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.monitoring.store;
18
19 import org.apache.commons.monitoring.Role;
20 import org.apache.commons.monitoring.configuration.Configuration;
21 import org.apache.commons.monitoring.counters.Counter;
22 import org.apache.commons.monitoring.counters.DefaultCounter;
23 import org.apache.commons.monitoring.gauges.Gauge;
24
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Map;
28 import java.util.TreeMap;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentMap;
31 import java.util.concurrent.ConcurrentSkipListMap;
32 import java.util.concurrent.locks.Lock;
33
34 public class DefaultDataStore implements DataStore {
35 private final ConcurrentMap<Counter.Key, Counter> counters = new ConcurrentHashMap<Counter.Key, Counter>(50);
36 private final Map<Role, Map<Long, Double>> gauges = new ConcurrentHashMap<Role, Map<Long, Double>>();
37
38 @Override
39 public Counter getOrCreateCounter(final Counter.Key key) {
40 Counter counter = counters.get(key);
41 if (counter == null) {
42 counter = new DefaultCounter(key, this);
43 final Counter previous = counters.putIfAbsent(key, counter);
44 if (previous != null) {
45 counter = previous;
46 }
47 }
48 return counter;
49 }
50
51 @Override
52 public void clearCounters() {
53 counters.clear();
54 }
55
56 @Override
57 public Collection<Counter> getCounters() {
58 return counters.values();
59 }
60
61 @Override
62 public void addToCounter(final Counter counter, final double delta) {
63 if (!DefaultCounter.class.isInstance(counter)) {
64 throw new IllegalArgumentException(DefaultDataStore.class.getName() + " only supports " + DefaultCounter.class.getName());
65 }
66
67 final DefaultCounter defaultCounter = DefaultCounter.class.cast(counter);
68 final Lock lock = defaultCounter.getLock();
69 lock.lock();
70 try {
71 defaultCounter.addInternal(delta);
72 } finally {
73 lock.unlock();
74 }
75 }
76
77 @Override
78 public Map<Long, Double> getGaugeValues(GaugeValuesRequest gaugeValuesRequest) {
79 final Map<Long, Double> map = gauges.get(gaugeValuesRequest.getRole());
80 if (map == null) {
81 return Collections.emptyMap();
82 }
83
84 final Map<Long, Double> copy = new TreeMap<Long, Double>( map );
85
86 final Map<Long, Double> out = new TreeMap<Long, Double>();
87 for (final Map.Entry<Long, Double> entry : copy.entrySet()) {
88 final long time = entry.getKey();
89 if (time >= gaugeValuesRequest.getStart() && time <= gaugeValuesRequest.getEnd()) {
90 out.put(time, entry.getValue());
91 }
92 }
93 return out;
94 }
95
96 @Override
97 public void createOrNoopGauge(final Role role) {
98 gauges.put(role, new FixedSizedMap());
99 }
100
101 @Override
102 public void addToGauge(final Gauge gauge, final long time, final double value) {
103 gauges.get(gauge.role()).put(time, value);
104 }
105
106
107 protected static class FixedSizedMap extends ConcurrentSkipListMap<Long, Double> {
108 private static final int MAX_SIZE = Configuration.getInteger(Configuration.COMMONS_MONITORING_PREFIX + "gauge.max-size", 100);
109
110 protected FixedSizedMap() {
111
112 }
113
114 protected FixedSizedMap(final Map<Long, Double> value) {
115 super(value);
116 }
117
118 @Override
119 public Double put(final Long key, final Double value) {
120 if (size() >= MAX_SIZE) {
121 remove(keySet().iterator().next());
122 }
123 return super.put(key, value);
124 }
125 }
126 }