/** * Copyright (c) 2009 - 2010 AppWork UG(haftungsbeschränkt) <e-mail@appwork.org> * * This file is part of org.appwork.utils.speedmeter * * This software is licensed under the Artistic License 2.0, * see the LICENSE file or http://www.opensource.org/licenses/artistic-license-2.0.php * for details */ package org.appwork.utils.speedmeter; /** * @author daniel * */ public class AverageSpeedMeter implements SpeedMeterInterface { private final long[] bytes; private final long[] times; private final int size; private int index; private boolean changed = false; private long speed = 0; private final Object LOCK = new Object(); private long stalled = 0; private long timeout = -1; /* * no timeout for stalled * connections */ /** * constructor for AverageSpeedMeter with default size 5 */ public AverageSpeedMeter() { this(5); } /** * constructor for AverageSpeedMeter with custom size * * @param size */ public AverageSpeedMeter(final int size) { this.size = size; this.bytes = new long[this.size]; this.times = new long[this.size]; this.index = 0; this.resetSpeedMeter(); } public long getSpeedMeter() { synchronized (this.LOCK) { if (!this.changed) { return this.speed; } long totalValue = 0; long totalTime = this.stalled; for (int i = 0; i < this.size; i++) { if (this.bytes[i] < 0) { continue; } totalValue += this.bytes[i]; totalTime += this.times[i]; } if (totalTime >= 1000) { this.speed = totalValue * 1000 / totalTime; } this.changed = false; return this.speed; } } /* * (non-Javadoc) * * @see org.appwork.utils.speedmeter.SpeedMeterInterface#getSpeedMeter() */ public void putSpeedMeter(final long x, final long time) { synchronized (this.LOCK) { final long put = Math.max(0, x); if (put == 0) { this.stalled += Math.max(0, time); if (this.timeout > 0 && this.stalled > this.timeout) { this.resetSpeedMeter(); } } else { this.bytes[this.index] = put; this.times[this.index] = Math.max(0, time) + this.stalled; this.stalled = 0; this.index++; if (this.index == this.size) { this.index = 0; } } this.changed = true; } } /* * (non-Javadoc) * * @see org.appwork.utils.speedmeter.SpeedMeterInterface#putSpeedMeter(long, * long) */ public void resetSpeedMeter() { synchronized (this.LOCK) { for (this.index = 0; this.index < this.size; this.index++) { this.bytes[this.index] = -1; this.times[this.index] = 0; } this.index = 0; this.speed = 0; this.changed = true; } } /* * (non-Javadoc) * * @see org.appwork.utils.speedmeter.SpeedMeterInterface#resetSpeedMeter() */ public void setStallTimeout(final long timeout) { if (timeout <= 0) { this.timeout = -1; } else { this.timeout = timeout; } } }