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