001: /*
002: * $Id: RatePerUnit.java 8077 2007-08-27 20:15:25Z aperepel $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.util.counters.impl;
012:
013: import org.mule.util.counters.CounterFactory.Type;
014:
015: import java.security.InvalidParameterException;
016: import java.util.Iterator;
017: import java.util.LinkedList;
018:
019: public class RatePerUnit extends AggregateCounter {
020:
021: private static class Sample {
022: private double value;
023: private long time;
024:
025: public Sample(double value, long time) {
026: this .value = value;
027: this .time = time;
028: }
029:
030: /**
031: * @return the time of the sample
032: */
033: public long getTime() {
034: return time;
035: }
036:
037: /**
038: * @return the value of the sample
039: */
040: public double getValue() {
041: return value;
042: }
043: }
044:
045: private final LinkedList samples;
046: private final long unit;
047: private final long length;
048: private final long baseTime;
049:
050: public RatePerUnit(String name, String p, Type type,
051: AbstractCounter base) {
052: super (name, type, base);
053:
054: if (type == Type.RATE_PER_SECOND) {
055: unit = 1000;
056: } else if (type == Type.RATE_PER_MINUTE) {
057: unit = 60 * 1000;
058: } else if (type == Type.RATE_PER_HOUR) {
059: unit = 60 * 60 * 1000;
060: } else {
061: throw new InvalidParameterException();
062: }
063:
064: long newLength = 0;
065:
066: try {
067: newLength = Long.parseLong(p);
068: } catch (Exception e) {
069: newLength = 0;
070: } finally {
071: if (newLength <= 0) {
072: newLength = 128;
073: }
074:
075: length = newLength;
076: }
077:
078: samples = new LinkedList();
079: baseTime = System.currentTimeMillis();
080: }
081:
082: public double nextValue() {
083: if (samples.isEmpty()) {
084: return 0.0;
085: } else {
086: double total = 0.0;
087: long current = getTime();
088: Iterator it = samples.iterator();
089: Sample sample = null;
090: while (it.hasNext()) {
091: sample = (Sample) it.next();
092: if (current - sample.time > length) {
093: break;
094: }
095: total += sample.value;
096: }
097: return total
098: / (1 + current - (sample != null ? sample.time : 0));
099: }
100: }
101:
102: public void doCompute() {
103: Sample l = samples.isEmpty() ? null : (Sample) samples
104: .getFirst();
105: long t = getTime();
106: if (l == null || t > l.time) {
107: Sample s = new Sample(this .getBase().nextValue(), t);
108: samples.addFirst(s);
109: } else {
110: l.value += getBase().nextValue();
111: }
112: while (samples.size() > length) {
113: samples.removeLast();
114: }
115: }
116:
117: protected long getTime() {
118: return (System.currentTimeMillis() - baseTime) / unit;
119: }
120:
121: }
|