ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/util/uk/org/iscream/cms/util/Queue.java
(Generate patch)

Comparing projects/cms/source/util/uk/org/iscream/cms/util/Queue.java (file contents):
Revision 1.13 by tdb, Sun Feb 25 23:29:06 2001 UTC vs.
Revision 1.19 by tdb, Thu Mar 22 18:23:27 2001 UTC

# Line 1 | Line 1
1   //---PACKAGE DECLARATION---
2 < package uk.ac.ukc.iscream.util;
2 > package uk.org.iscream.util;
3  
4   //---IMPORTS---
5   import java.util.LinkedList;
6   import java.util.NoSuchElementException;
7 < import uk.ac.ukc.iscream.util.*;
7 > import java.util.Random;
8 > import uk.org.iscream.util.*;
9  
10   /**
11   * A Queue class designed to operate in a multi-threaded environment, with
# Line 24 | Line 25 | public class Queue {
25       */
26      public static final String REVISION = "$Revision$";
27      
28 +    /**
29 +     * Pass to constructor to remove a RANDOM item from
30 +     * the Queue upon reaching the maximum limit.
31 +     */
32 +    public static final int RANDOM = 0;
33 +    
34 +    /**
35 +     * Pass to constructor to remove the FIRST item from
36 +     * the Queue upon reaching the maximum limit.
37 +     */
38 +    public static final int FIRST = 1;
39 +    
40 +    /**
41 +     * Pass to constructor to remove the LAST item from
42 +     * the Queue upon reaching the maximum limit.
43 +     */
44 +    public static final int LAST = 2;
45 +    
46 +    /**
47 +     * Pass to constructor to drop the new item upon reaching
48 +     * the maximum Queue limit.
49 +     */
50 +    public static final int DROP = 3;
51 +    
52 +    /**
53 +     * To allow opposite lookups.
54 +     */
55 +    public static final String[] algorithms = {"RANDOM", "FIRST", "LAST", "DROP"};
56 +    
57   //---STATIC METHODS---
58  
59   //---CONSTRUCTORS---  
60 +    
61 +    /**
62 +     * Constructs a new Queue with a maximum size limit on
63 +     * any individual queue. This should be used to stop
64 +     * conditions where the Queue cannot be guaranteed to
65 +     * be emptied as quick as it's filled.
66 +     *
67 +     * An algorithm will be used to remove data when new data
68 +     * arrives. There may be choices of algorithms later on.
69 +     *
70 +     * @param maxSize the upper limit for a queue
71 +     * @param removeAlgorithm the remove algorithm to use upon reaching the maxSize
72 +     */
73 +    public Queue(int maxSize, int removeAlgorithm) {
74 +        _maxSize = maxSize;
75 +        _removeAlgorithm = removeAlgorithm;
76 +    }
77 +    
78 +    /**
79 +     * Constructs a Queue with no maximum size.
80 +     */
81 +    public Queue() {
82 +        _maxSize = -1;
83 +    }
84  
85   //---PUBLIC METHODS---
86      
# Line 40 | Line 94 | public class Queue {
94          for(int i=0; i < _lists.size(); i++) {
95              // skip over any gaps left in the list
96              if(_lists.get(i) != null) {
97 +                // get size before adding to the Queue
98                  int s = ((LinkedList) _lists.get(i)).size();
99 <                synchronized(this) {
100 <                    // add() does the same thing, but this ensures behaviour
101 <                    ((LinkedList) _lists.get(i)).addLast(o);
99 >                // check whether we need to remove an item from the current Queue
100 >                if(_maxSize!=-1 && s==_maxSize && _removeAlgorithm!=DROP) {
101 >                    // we need to remove an item
102 >                    removeQueueItem((LinkedList) _lists.get(i));
103                  }
104 +                // check if we should add (not if Queue full, and using DROP algorithm)
105 +                if(!(s==_maxSize && _removeAlgorithm==DROP)) {
106 +                    // add the next item, ensuring we lock
107 +                    synchronized(this) {
108 +                        // LinkedList.add() does the same thing, but this ensures behaviour
109 +                        ((LinkedList) _lists.get(i)).addLast(o);
110 +                    }
111 +                }
112                  // if the queue was empty before the add it is possible
113                  // that a consumer is waiting... so we notify them
114                  if (s == 0) {
# Line 72 | Line 136 | public class Queue {
136              throw new InvalidQueueException("Requested queue "+queue+" does not exist");
137          }
138          // block if the queue is empty
139 <        if (((LinkedList) _lists.get(queue)).size() == 0) {
140 <            synchronized(((LinkedList) _lists.get(queue))) {
139 >        synchronized(((LinkedList) _lists.get(queue))) {
140 >            if (((LinkedList) _lists.get(queue)).size() == 0) {
141                  try { ((LinkedList) _lists.get(queue)).wait(); } catch(Exception e) {}
142              }
143          }
# Line 138 | Line 202 | public class Queue {
202                  status += "queue"+i+"=\"[deleted]\" ";
203              }
204          }
205 <        status += "total=\""+_count+"\"></queue>";
205 >        status += "total=\""+_count+"\"";
206 >        if(_maxSize != -1) {
207 >            status += " maxSize=\""+_maxSize+"\"";
208 >        }
209 >        status += "></queue>";
210          return status;
211      }
212      
# Line 179 | Line 247 | public class Queue {
247       *
248       * @return An integer to be passed to the get() method.
249       */
250 <    public int getQueue() {
250 >    public synchronized int getQueue() {
251          int pos = -1;
252          for(int i=0; i < _lists.size(); i++) {
253              if(_lists.get(i) == null) {
# Line 203 | Line 271 | public class Queue {
271       *
272       * @param queue The integer identifier for the queue, given by getQueue().
273       */
274 <    public void removeQueue(int queue) {
274 >    public synchronized void removeQueue(int queue) {
275          _lists.set(queue, null);
276      }
277      
# Line 264 | Line 332 | public class Queue {
332       * Overrides the {@link java.lang.Object#toString() Object.toString()}
333       * method to provide clean logging (every class should have this).
334       *
335 <     * This uses the uk.ac.ukc.iscream.util.FormatName class
335 >     * This uses the uk.org.iscream.util.FormatName class
336       * to format the toString()
337       *
338       * @return the name of this class and its CVS revision.
# Line 277 | Line 345 | public class Queue {
345      }
346  
347   //---PRIVATE METHODS---
348 <
348 >    
349 >    /**
350 >     * This method removes an item from a Queue, using a method
351 >     * requested at construction.
352 >     *
353 >     * @param list The LinkedList from which to remove an item.
354 >     */
355 >    private void removeQueueItem(LinkedList list) {
356 >        // look at our algorithm
357 >        // remove a random item from the list
358 >        if(_removeAlgorithm==RANDOM) {
359 >            // new Random, with a good seed
360 >            Random rand = new Random(System.currentTimeMillis());
361 >            int i = rand.nextInt(_maxSize);
362 >            synchronized(this) {
363 >                list.remove(i);
364 >            }
365 >        }
366 >        // remove the first item from the list
367 >        else if(_removeAlgorithm==FIRST) {
368 >            synchronized(this) {
369 >                list.removeFirst();
370 >            }
371 >        }
372 >        // remove the last item from the list
373 >        else if(_removeAlgorithm==LAST) {
374 >            synchronized(this) {
375 >                list.removeLast();
376 >            }
377 >        }
378 >    }
379 >    
380   //---ACCESSOR/MUTATOR METHODS---
381  
382   //---ATTRIBUTES---
# Line 297 | Line 396 | public class Queue {
396       * A reference to our QueueMonitor, if we have one.
397       */
398      private QueueMonitor _queueMon = null;
399 +    
400 +    /**
401 +     * The maximum size of any Queue.
402 +     */
403 +    private int _maxSize = -1;
404 +    
405 +    /**
406 +     * The remove algorithm to use upon a Queue reaching
407 +     * it's maximum size.
408 +     */
409 +    private int _removeAlgorithm = -1;
410      
411      /**
412       * This is the friendly identifier of the

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines