/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.util; /** * <p>Title: CircularCounter</p> * <p>Description: Atomic circular counter</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.util.CircularCounter</code></p> */ public class CircularCounter { /** The value returned after which the counter is reset */ protected final long resetAt; /** The value that the counter is reset to */ protected final long resetTo; /** The internal counter */ private long counter; /** * Creates a new CircularCounter * @param startAt The first value returned by the counter * @param resetAt The value returned after which the counter is reset * @param resetTo The value that the counter is reset to * @return The created counter */ public static CircularCounter newCounter(long startAt, long resetAt, long resetTo) { return new CircularCounter(startAt, resetAt, resetTo); } /** * Creates a new CircularCounter starting at zero and resetting to zero * @param startAt The first value returned by the counter * @return The created counter */ public static CircularCounter newCounter(long startAt) { return new CircularCounter(startAt, 0L, 0L); } /** * Resets the counter to the reset value */ public synchronized void reset() { counter = resetTo; } /** * Returns the current value of the counter * @return the current value of the counter */ public synchronized long get() { return counter; } /** * Creates a new CircularCounter * @param startAt The first value returned by the counter * @param resetAt The value returned after which the counter is reset * @param resetTo The value that the counter is reset to */ protected CircularCounter(long startAt, long resetAt, long resetTo) { if(startAt>resetAt) throw new IllegalArgumentException("StartAt value [" + startAt + "] is greater than ResetAt value [" + resetAt + "]", new Throwable()); if(resetTo>resetAt) throw new IllegalArgumentException("ResetTo value [" + resetTo + "] is greater than ResetAt value [" + resetAt + "]", new Throwable()); counter = startAt; this.resetAt = resetAt; this.resetTo = resetTo; } /** * Returns the next counter value, resetting the counter after increment if it has reached the <b><code>resetAt</code></b> value. * @return The next counter value */ public synchronized long next() { long next = counter++; if(next==resetAt) { counter = resetTo; } return next; } }