Clover coverage report - gsbase - 2.0.1
Coverage timestamp: Sat Jan 1 2005 12:30:02 EST
file stats: LOC: 258   Methods: 10
NCLOC: 123   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BlockingCircularQueue.java 0% 0% 0% 0%
coverage
 1    /*
 2    * Copyright (c) 1998, 2005 Gargoyle Software Inc. All rights reserved.
 3    *
 4    * Redistribution and use in source and binary forms, with or without
 5    * modification, are permitted provided that the following conditions are met:
 6    *
 7    * 1. Redistributions of source code must retain the above copyright notice,
 8    * this list of conditions and the following disclaimer.
 9    * 2. Redistributions in binary form must reproduce the above copyright notice,
 10    * this list of conditions and the following disclaimer in the documentation
 11    * and/or other materials provided with the distribution.
 12    * 3. The end-user documentation included with the redistribution, if any, must
 13    * include the following acknowledgment:
 14    *
 15    * "This product includes software developed by Gargoyle Software Inc.
 16    * (http://www.GargoyleSoftware.com/)."
 17    *
 18    * Alternately, this acknowledgment may appear in the software itself, if
 19    * and wherever such third-party acknowledgments normally appear.
 20    * 4. The name "Gargoyle Software" must not be used to endorse or promote
 21    * products derived from this software without prior written permission.
 22    * For written permission, please contact info@GargoyleSoftware.com.
 23    * 5. Products derived from this software may not be called "GSBase", nor may
 24    * "GSBase" appear in their name, without prior written permission of
 25    * Gargoyle Software Inc.
 26    *
 27    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 28    * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 29    * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
 30    * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 31    * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 32    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 33    * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 34    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 35    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 36    * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 37    */
 38    package com.gargoylesoftware.base.trace;
 39   
 40    import com.gargoylesoftware.base.util.DetailedIllegalArgumentException;
 41    import com.gargoylesoftware.base.util.DetailedNullPointerException;
 42    import java.io.Serializable;
 43   
 44    /**
 45    * <p style="color: orange">Internal use only.</p>.
 46    * <p>A circular queue with blocking semantics.</p>
 47    *
 48    * @version $Revision: 1.8 $
 49    * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
 50    */
 51    public class BlockingCircularQueue
 52    implements
 53    Serializable {
 54   
 55    // Required for serialization - do not remove or modify
 56    private static final long serialVersionUID = 2206052328240171051L;
 57   
 58    // Locks for blocking on add/next
 59    private final Object getLock_ = new Object();
 60    private final Object addLock_ = new Object();
 61   
 62    // The actual storage
 63    private final Object queue_[];
 64   
 65    private final int capacity_;
 66    private int size_;
 67   
 68    // Objects get added to the front and removed from the back
 69    private int front_;
 70    private int back_;
 71   
 72   
 73    /**
 74    * Create the queue with a capacity of 20
 75    */
 76  0 public BlockingCircularQueue() {
 77  0 this( 20 );
 78    }
 79   
 80   
 81   
 82    /**
 83    * Create the queue with the specified capacity
 84    *
 85    *@param capacity The size of the queue
 86    */
 87  0 public BlockingCircularQueue( final int capacity ) {
 88  0 queue_ = new Object[capacity];
 89  0 capacity_ = capacity;
 90  0 if( capacity < 2 ) {
 91  0 throw new DetailedIllegalArgumentException( "capacity", capacity, "Must be larger than two" );
 92    }
 93    }
 94   
 95   
 96    /**
 97    * Remove all items from the queue
 98    */
 99  0 public synchronized void clear() {
 100  0 front_ = 0;
 101  0 back_ = 0;
 102  0 size_ = 0;
 103   
 104    // Remove any current object references so that they can be
 105    // garbage collected.
 106  0 int i;
 107  0 for( i = 0; i < capacity_; i++ ) {
 108  0 queue_[i] = null;
 109    }
 110    }
 111   
 112   
 113    /**
 114    * Add an object to the queue. If the collection is currently full then
 115    * block until an object is removed.
 116    *
 117    * @param object The object to add.
 118    * @return true if the object was successfully added.
 119    */
 120  0 public boolean add( final Object object ) {
 121  0 assertNotNull( "object", object );
 122  0 while( true ) {
 123  0 synchronized( this ) {
 124  0 if( size_ != capacity_ ) {
 125  0 if( size_ == 0 ) {
 126  0 front_ = 0;
 127  0 back_ = 0;
 128    }
 129    else {
 130  0 front_ = incrementPosition( front_ );
 131    }
 132  0 queue_[front_] = object;
 133  0 synchronized( getLock_ ) {
 134  0 getLock_.notify();
 135    }
 136  0 size_++;
 137  0 return true;
 138    }
 139    }
 140  0 synchronized( addLock_ ) {
 141  0 try {
 142  0 addLock_.wait();
 143    }
 144    catch( final InterruptedException e ) {
 145    //TODO: We should be doing something here
 146    }
 147    }
 148    }
 149    }
 150   
 151   
 152    /**
 153    * Return the next item in the queue. The returned item is removed from the
 154    * collection. If no objects are present then block until an object has
 155    * been added.
 156    *
 157    * @return The next item.
 158    */
 159  0 public Object next() {
 160  0 while( true ) {
 161    // If there's something in the queue then return it now.
 162  0 synchronized( this ) {
 163  0 if( isEmpty() == false ) {
 164  0 final Object object = queue_[back_];
 165  0 queue_[back_] = null;// help the garbage collector
 166  0 back_ = incrementPosition( back_ );
 167  0 synchronized( addLock_ ) {
 168  0 addLock_.notify();
 169    }
 170  0 size_--;
 171  0 return object;
 172    }
 173    }
 174    // There wasn't anything in the queue. Block until something gets added.
 175  0 synchronized( getLock_ ) {
 176  0 try {
 177  0 getLock_.wait();
 178    }
 179    catch( InterruptedException e ) {
 180    //TODO: Do something here
 181    }
 182    }
 183    }
 184    }
 185   
 186   
 187    /**
 188    * Utility method to increment the position and roll back to zero once we
 189    * hit the end. Return the new position after the adjustment.
 190    * @param position The position to increment
 191    * @return the new position
 192    */
 193  0 private int incrementPosition( final int position ) {
 194  0 if( ( position < 0 ) || ( position >= capacity_ ) ) {
 195  0 throw new DetailedIllegalArgumentException(
 196    "position", new Integer( position ), "Must be within 1 and " + capacity_ );
 197    }
 198  0 int newPosition = position + 1;
 199  0 if( newPosition == capacity_ ) {
 200  0 newPosition = 0;
 201    }
 202  0 return newPosition;
 203    }
 204   
 205   
 206    /**
 207    * Return the number of objects currently in the collection.
 208    * @return The object count.
 209    */
 210  0 public int size() {
 211  0 return size_;
 212    }
 213   
 214   
 215    /**
 216    * Return true if the collection is empty.
 217    * @return true if the collection is empty.
 218    */
 219  0 public boolean isEmpty() {
 220  0 return size_ == 0;
 221    }
 222   
 223   
 224    /**
 225    * Return a string representation of this object.
 226    * @return a string representation of this object.
 227    */
 228  0 public String toString() {
 229  0 final StringBuffer buffer = new StringBuffer();
 230  0 buffer.append( getClass().getName() );
 231  0 buffer.append( ": capacity_=" );
 232  0 buffer.append( capacity_ );
 233  0 buffer.append( " size_=" );
 234  0 buffer.append( size_ );
 235  0 buffer.append( " front_=" );
 236  0 buffer.append( front_ );
 237  0 buffer.append( " back_=" );
 238  0 buffer.append( back_ );
 239  0 return buffer.toString();
 240    }
 241   
 242   
 243    /**
 244    * Verify that the specified value is not null. If it is then throw an
 245    * exception
 246    *
 247    *@param fieldName The name of the field to check
 248    *@param fieldValue The value of the field to check
 249    *@exception DetailedNullPointerException If fieldValue is null
 250    */
 251  0 protected final void assertNotNull( final String fieldName, final Object fieldValue )
 252    throws DetailedNullPointerException {
 253  0 if( fieldValue == null ) {
 254  0 throw new DetailedNullPointerException( fieldName );
 255    }
 256    }
 257    }
 258