001: /*
002: @COPYRIGHT@
003: */
004: package demo.jmx;
005:
006: import java.util.LinkedList;
007: import java.util.List;
008:
009: /**
010: * Bounded queue collection
011: */
012: public class HistoryQueue implements IHistory {
013: private static final int DEFAULT_INTERVAL = 30;
014:
015: private final long granularity;
016: private final int capacity;
017: private final List buffer = new LinkedList();
018:
019: private boolean enabled = true;
020:
021: public HistoryQueue() {
022: this (DEFAULT_INTERVAL, 24 * 60 * 60 / DEFAULT_INTERVAL); // default 24h
023: }
024:
025: public HistoryQueue(int granularity, int capacity) {
026: this .granularity = granularity * 1000;
027: this .capacity = capacity;
028: }
029:
030: // JMX access
031:
032: public String[] getHistory() {
033: synchronized (this .buffer) {
034: String[] history = new String[this .buffer.size()];
035: for (int i = 0; i < history.length; i++) {
036: HistoryData data = (HistoryData) this .buffer.get(i);
037: history[i] = data.toString();
038: }
039: return history;
040: }
041: }
042:
043: public boolean getEnabled() {
044: return this .enabled;
045: }
046:
047: public void setEnabled(boolean enabled) {
048: synchronized (this ) {
049: this .enabled = enabled;
050: }
051: }
052:
053: public void reset() {
054: synchronized (this .buffer) {
055: this .buffer.clear();
056: }
057: }
058:
059: public void updateHistory(int duration, String error) {
060: if (this .enabled) {
061: synchronized (this ) {
062: HistoryData historyData = getHistoryData(System
063: .currentTimeMillis());
064: historyData.update(duration, error);
065: }
066: }
067: }
068:
069: private HistoryData getHistoryData(long time) {
070: HistoryData data = (HistoryData) peek();
071:
072: long intervalStart = time - (time % granularity);
073:
074: if (data == null) {
075: data = new HistoryData(intervalStart, 0);
076: add(data);
077: } else {
078: if (time - data.getIntervalStart() > granularity) {
079: data = new HistoryData(intervalStart, 0);
080: add(data);
081: }
082: }
083: return data;
084: }
085:
086: /**
087: * Adds new object to the queue and returns object pushed out
088: * of the queue as a result of add or null if nothing was
089: * pushed out (max capacity not reached yet).
090: */
091: private Object add(Object o) {
092: Object removed = null;
093: if (this .buffer.size() >= this .capacity)
094: removed = this .buffer.remove(0);
095: this .buffer.add(o);
096: return removed;
097: }
098:
099: private Object peek() {
100: final int size = this .buffer.size();
101: return size == 0 ? null : this .buffer.get(size - 1);
102: }
103: }
|