/** * 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.collections; import java.nio.LongBuffer; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; /** * <p>Title: ConcurrentLongSlidingWindow</p> * <p>Description: </p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.collections.ConcurrentLongSlidingWindow</code></p> */ public class ConcurrentLongSlidingWindow extends LongSlidingWindow implements ILongSlidingWindow { /** The reentrant read/write lock */ private final ReentrantReadWriteLock readWriteLock; /** The concurrent read lock */ private final ReadLock readLock; /** The exclusive write lock */ private final WriteLock writeLock; /** * Creates a new ConcurrentLongSlidingWindow * @param size the fixed size of the sliding window */ public ConcurrentLongSlidingWindow(int size) { super(size); readWriteLock = new ReentrantReadWriteLock(false); readLock = readWriteLock.readLock(); writeLock = readWriteLock.writeLock(); } /** * Creates a new ConcurrentLongSlidingWindow * @param size the fixed size of the sliding window * @param values the initial values of the sliding window */ public ConcurrentLongSlidingWindow(int size, long[] values) { super(size, values); readWriteLock = new ReentrantReadWriteLock(false); readLock = readWriteLock.readLock(); writeLock = readWriteLock.writeLock(); } private ConcurrentLongSlidingWindow(UnsafeLongArray array) { super(array); readWriteLock = new ReentrantReadWriteLock(false); readLock = readWriteLock.readLock(); writeLock = readWriteLock.writeLock(); } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#insert(long) */ @Override public void insert(long...values) { writeLock.lock(); try { super.insert(values); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#insert(java.nio.LongBuffer) */ @Override public void insert(LongBuffer longBuff) { writeLock.lock(); try { long[] larr = new long[longBuff.limit()]; longBuff.get(larr); super.insert(larr); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#insert(long) */ @Override public Long insert(long value) { writeLock.lock(); try { return super.insert(value); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#inc(int, long) */ @Override public long inc(int index, long value) { writeLock.lock(); try { if(size()<index+1) throw new ArrayOverflowException("Attempted to increment at index [" + index + "] but size is [" + size() + "]", new Throwable()); return array.set(index, array.get(index)+value).get(index); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#inc(int) */ @Override public long inc(int index) { return inc(index, 1L); } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#inc(long) */ @Override public long inc(long value) { return inc(0, value); } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#inc() */ @Override public long inc() { return inc(0, 1L); } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#find(long) */ @Override public int find(long value) { readLock.lock(); try { return array.binarySearch(value); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#set(long) */ @Override public void set(long value) { writeLock.lock(); try { array.set(0, value); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#asDoubleArray() */ @Override public double[] asDoubleArray() { readLock.lock(); try { return array.asDoubleArray(); } finally { readLock.unlock(); } } /** * Returns this sliding window as a long array * @return a long array */ public long[] asLongArray() { readLock.lock(); try { return array.getArray(); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#load(byte[]) */ @Override public void load(byte[] arr) { writeLock.lock(); try { array.load(arr); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#reinitAndLoad(byte[]) */ @Override public void reinitAndLoad(byte[] arr) { writeLock.lock(); try { array.initAndLoad(arr); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#clear() */ @Override public void clear() { writeLock.lock(); try { super.clear(); } finally { writeLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#isEmpty() */ @Override public boolean isEmpty() { readLock.lock(); try { return super.isEmpty(); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#toString() */ @Override public String toString() { readLock.lock(); try { return super.toString(); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#clone() */ @Override public LongSlidingWindow clone() { readLock.lock(); try { return new LongSlidingWindow(array.clone()); } finally { readLock.unlock(); } } /** * Returns the most recent value in the array or -1L if the size is 0. * @return the most recent in the array or -1L if the size is 0. */ public long getNewest() { return getFirst(); } /** * Returns the oldest value in the array or -1L if the size is 0. * @return the oldest in the array or -1L if the size is 0. */ public long getOldest() { return getLast(); } /** * Returns the first (chronologically the most recent) value in the array or -1L if the size is 0. * @return the first value in the array or -1L if the size is 0. */ public long getFirst() { readLock.lock(); try { if(size()<1) return -1L; return array.get(0); } finally { readLock.unlock(); } } /** * Returns the last value (chronologically the oldest) in the array or -1L if the size is 0. * @return the last value in the array or -1L if the size is 0. */ public long getLast() { readLock.lock(); try { if(size()<1) return -1L; return array.get(size()-1); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#get(int) */ @Override public long get(int index) { readLock.lock(); try { return array.get(index); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#size() */ @Override public int size() { readLock.lock(); try { return array.size(); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#sum(int) */ @Override public long sum(int within) { readLock.lock(); try { return super.sum(within); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#sum() */ @Override public long sum() { readLock.lock(); try { return super.sum(); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#avg(int) */ @Override public long avg(int within) { readLock.lock(); try { return super.avg(within); } finally { readLock.unlock(); } } /** * {@inheritDoc} * @see org.helios.apmrouter.collections.ILongSlidingWindow#avg() */ @Override public long avg() { readLock.lock(); try { return super.avg(); } finally { readLock.unlock(); } } }