1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest.util;
  28 
  29 
  30 /**
  31  * A simple variable length first-in first-out queue.
  32  */
  33 
  34 public class Fifo<E>
  35 {
  36     /**
  37      * Create a buffer with a default initial size.
  38      */
  39     public Fifo() {
  40         this(defaultInitialSlots);
  41     }
  42 
  43     /**
  44      * Create a buffer with a specified initial size.
  45      *
  46      * @param initialSlots      The number of initial slots in the buffer; the number of
  47      *                          slots required by the buffer will be expanded as required.
  48      */
  49     public Fifo(int initialSlots) {
  50         bufSize = initialSlots;
  51         buf = (E[]) new Object[bufSize];
  52         insertSlot = 0;
  53         removeSlot = 0;
  54         entries = 0;
  55     }
  56 
  57     /**
  58      * Check if the buffer has an entries or not.
  59      *
  60      * @return                  true if the buffer has no entries, and false otherwise.
  61      */
  62     public synchronized boolean isEmpty() {
  63         return (entries == 0);
  64     }
  65 
  66     /**
  67      * Return the number of entries currently in the fifo.
  68      *
  69      * @return                  The number of entries currently in the fifo
  70      */
  71     public synchronized int size() {
  72         return entries;
  73     }
  74 
  75     /**
  76      * Insert an entry into the buffer. The buffer will be increased in size if necessary
  77      * to accommodate the new entry.
  78      *
  79      * @param obj               The object to be inserted.  It must not be null.
  80      */
  81     public synchronized void insert(E obj) {
  82         if (obj == null)
  83             throw new NullPointerException();
  84 
  85         if (entries == bufSize) {
  86             int newBufSize = 2 * bufSize;
  87             E[] newBuf = (E[]) new Object[newBufSize];
  88             int saveEntries = entries;
  89             for (int i = 0; entries > 0; i++) {
  90                 newBuf[i] = remove();
  91             }
  92             entries = saveEntries;
  93             buf = newBuf;
  94             bufSize = newBufSize;
  95             removeSlot = 0;
  96             insertSlot = entries;
  97         }
  98 
  99         buf[insertSlot] = obj;
 100         insertSlot = (insertSlot + 1) % bufSize;
 101         entries++;
 102     }
 103 
 104     /**
 105      * Remove an entry from the buffer if one is available.
 106      *
 107      * @return                  The next object in line to be removed, if one is available,
 108      *                          or null if none are available.
 109      */
 110     public synchronized E remove() {
 111         if (entries == 0)
 112             return null;
 113 
 114         E o = buf[removeSlot];
 115         buf[removeSlot] = null;
 116         removeSlot = (removeSlot + 1) % bufSize;
 117         entries--;
 118 
 119         return o;
 120     }
 121 
 122     /**
 123      * Flush all entries from the buffer.
 124      */
 125     public synchronized void flush() {
 126         insertSlot = 0;
 127         removeSlot = 0;
 128         entries = 0;
 129         for (int i = 0; i < buf.length; i++)
 130             buf[i] = null;
 131     }
 132 
 133 
 134     //----------Data members---------------------------------------------------------
 135 
 136     private final static int defaultInitialSlots = 16;
 137 
 138     private E[] buf;               // The circular array to hold the entries
 139     private int bufSize;                // The size of the array: buf.length
 140     private int insertSlot;             // The next slot to store an entry
 141     private int removeSlot;             // The next slot from which to remove an entry
 142     private int entries;                // The number of entries in the array
 143 
 144 }