Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mindbright/util/Queue.java


1   /******************************************************************************
2    *
3    * Copyright (c) 2000 by Mindbright Technology AB, Stockholm, Sweden.
4    *                 www.mindbright.se, info@mindbright.se
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation; either version 2 of the License, or
9    * (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   *****************************************************************************
17   * $Author: nallen $
18   * $Date: 2001/11/12 16:31:29 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.util;
22  
23  public final class Queue {
24  
25      final static int QUEUE_DEPTH   = 512;
26      final static int QUEUE_HIWATER = 384;
27  
28      Object[]   queue;
29      boolean    isWaitGet;
30      boolean    isWaitPut;
31      boolean    isBlocking;
32      int        rOffset;
33      int        wOffset;
34      int        maxQueueDepth;
35  
36      // Copies used for saving real values when disabling queue
37      //
38      int        rOffsetCP;
39      int        wOffsetCP;
40      int        maxQueueDepthCP;
41  
42      public Queue() {
43    this.queue      = new Object[QUEUE_DEPTH + 1];
44    this.isWaitGet  = false;
45    this.isWaitPut  = false;
46    this.isBlocking = true;
47    this.rOffset    = 0;
48    this.wOffset    = 0;
49    this.maxQueueDepth = QUEUE_DEPTH;
50      }
51  
52      public synchronized void setMaxDepth(int maxDepth) {
53    maxQueueDepth = maxDepth;
54      }
55  
56      public synchronized void putLast(Object obj) {
57    putFlowControl();
58    queue[wOffset++] = obj;
59    if(wOffset == (QUEUE_DEPTH + 1))
60        wOffset = 0;
61    if(isWaitGet)
62        this.notify();
63      }
64  
65      public synchronized void putFirst(Object obj) {
66    putFlowControl();
67    rOffset--;
68    if(rOffset == -1)
69        rOffset = QUEUE_DEPTH;
70    queue[rOffset] = obj;
71    if(isWaitGet)
72        this.notify();
73      }
74  
75      public synchronized void release() {
76    if(isWaitGet)
77        this.notify();
78      }
79  
80      public synchronized void disable() {
81    rOffsetCP       = rOffset;
82    wOffsetCP       = wOffset;
83    maxQueueDepthCP = maxQueueDepth;
84    rOffset         = 0;
85    wOffset         = 0;
86    maxQueueDepth   = 0;
87      }
88  
89      public synchronized void enable() {
90    rOffset       = rOffsetCP;
91    wOffset       = wOffsetCP;
92    maxQueueDepth = maxQueueDepthCP;
93    if(!isEmpty()) {
94        this.release();
95    }
96    if(isWaitPut && (freeSpace() > (QUEUE_DEPTH - QUEUE_HIWATER))) {
97        this.notifyAll();
98        isWaitPut = false;
99    }
100     }
101 
102     public synchronized void setBlocking(boolean block) {
103   isBlocking = block;
104   release();
105     }
106 
107     public synchronized boolean isEmpty() {
108   return (rOffset == wOffset);
109     }
110 
111     private final void putFlowControl() {
112   int fs = freeSpace();
113   if(fs == (QUEUE_DEPTH - maxQueueDepth)) {
114       isWaitPut = true;
115   }
116   if(isWaitPut) {
117       try {
118     this.wait();
119       } catch (InterruptedException e) {
120     // !!!
121       }
122   }
123     }
124 
125     private final int freeSpace() {
126   int fSpc = rOffset - wOffset;
127   if(fSpc <= 0)
128       fSpc += (QUEUE_DEPTH + 1);
129   fSpc--;
130   return fSpc;
131     }
132 
133     public synchronized Object getFirst() {
134   Object obj = null;
135   if(isEmpty()) {
136       if(!isBlocking) {
137     return null;
138       }
139       isWaitGet = true;
140       try {
141     this.wait();
142       } catch (InterruptedException e) {
143     // !!!
144       }
145   }
146   isWaitGet = false;
147   obj = queue[rOffset];
148   queue[rOffset++] = null;
149   if(rOffset == (QUEUE_DEPTH + 1))
150       rOffset = 0;
151   if(isWaitPut && (freeSpace() > (QUEUE_DEPTH - QUEUE_HIWATER))) {
152       this.notifyAll();
153       isWaitPut = false;
154   }
155   return obj;
156     }
157 }