KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > cluster > util > SmartQueue


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.catalina.cluster.util;
18
19 /**
20  * A smart queue, used for async replication <BR>
21  * the "smart" part of this queue is that if the session is already queued for
22  * replication, and it is updated again, the session will simply be replaced,
23  * hence we don't replicate stuff that is obsolete. Put this into util, since it
24  * is quite generic.
25  *
26  * @author Filip Hanik
27  * @version 1.0
28  */

29
30 import java.util.LinkedList JavaDoc;
31 import java.util.HashMap JavaDoc;
32
33 public class SmartQueue {
34
35     public static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
36             .getLog(SmartQueue.class);
37
38     /**
39      * This is the actual queue
40      */

41     private LinkedList JavaDoc queue = new LinkedList JavaDoc();
42
43     /**
44      * And this is only for performance, fast lookups
45      */

46     private HashMap JavaDoc queueMap = new HashMap JavaDoc();
47
48     private Object JavaDoc mutex = new Object JavaDoc();
49
50     public SmartQueue() {
51     }
52
53     /**
54      * Add an object to the queue
55      *
56      * @param entry -
57      * the smart entry
58      */

59     public void add(SmartEntry entry) {
60         /*
61          * make sure we are within a synchronized block since we are dealing
62          * with two unsync collections
63          */

64         synchronized (mutex) {
65             /* check to see if this object has already been queued */
66             SmartEntry current = (SmartEntry) queueMap.get(entry.getKey());
67             if (current == null) {
68                 /* the object has not been queued, at it to the end of the queue */
69                 if (log.isDebugEnabled())
70                     log.debug("[" + Thread.currentThread().getName()
71                             + "][SmartQueue] Adding new object=" + entry);
72                 queue.addLast(entry);
73                 queueMap.put(entry.getKey(), entry);
74             } else {
75                 /* the object has been queued, replace the value */
76                 if (log.isDebugEnabled())
77                     log.debug("[" + Thread.currentThread().getName()
78                             + "][SmartQueue] Replacing old object=" + current);
79                 current.setValue(entry.getValue());
80                 if (log.isDebugEnabled())
81                     log.debug("with new object=" + current);
82             }
83             /*
84              * wake up all the threads that are waiting for the lock to be
85              * released
86              */

87             mutex.notifyAll();
88         }
89     }
90
91     public int size() {
92         synchronized (mutex) {
93             return queue.size();
94         }
95     }
96
97     /**
98      * Blocks forever until an element has been added to the queue
99      */

100     public SmartEntry remove() {
101         return remove(0);
102     }
103
104     public SmartEntry remove(long timeout) {
105         SmartEntry result = null;
106         long startEntry = System.currentTimeMillis();
107         synchronized (mutex) {
108             while (size() == 0) {
109                 try {
110                     if (log.isDebugEnabled())
111                         log
112                                 .debug("["
113                                         + Thread.currentThread().getName()
114                                         + "][SmartQueue] Queue sleeping until object added size="
115                                         + size() + ".");
116                     if ((timeout != 0)
117                             && ((System.currentTimeMillis() - startEntry) > timeout)) {
118                         return null;
119                     }
120                     mutex.wait(timeout);
121                     if (log.isDebugEnabled())
122                         log
123                                 .debug("["
124                                         + Thread.currentThread().getName()
125                                         + "][SmartQueue] Queue woke up or interrupted size="
126                                         + size() + ".");
127                 } catch (IllegalMonitorStateException JavaDoc ex) {
128                     throw ex;
129                 } catch (InterruptedException JavaDoc ex) {
130                 }//catch
131
}//while
132
/* guaranteed that we are not empty by now */
133             result = (SmartEntry) queue.removeFirst();
134             queueMap.remove(result.getKey());
135             if (log.isDebugEnabled())
136                 log.debug("[" + Thread.currentThread().getName()
137                         + "][SmartQueue] Returning=" + result);
138         }
139         return result;
140     }
141
142     public static class SmartEntry {
143         protected Object JavaDoc key;
144
145         protected Object JavaDoc value;
146
147         public SmartEntry(Object JavaDoc key, Object JavaDoc value) {
148             if (key == null)
149                 throw new IllegalArgumentException JavaDoc(
150                         "SmartEntry key can not be null.");
151             if (value == null)
152                 throw new IllegalArgumentException JavaDoc(
153                         "SmartEntry value can not be null.");
154             this.key = key;
155             this.value = value;
156         }
157
158         public Object JavaDoc getKey() {
159             return key;
160         }
161
162         public Object JavaDoc getValue() {
163             return value;
164         }
165
166         public void setValue(Object JavaDoc value) {
167             if (value == null)
168                 throw new IllegalArgumentException JavaDoc(
169                         "SmartEntry value can not be null.");
170             this.value = value;
171         }
172
173         public int hashCode() {
174             return key.hashCode();
175         }
176
177         public boolean equals(Object JavaDoc o) {
178             if (!(o instanceof SmartEntry))
179                 return false;
180             SmartEntry other = (SmartEntry) o;
181             return other.getKey().equals(getKey());
182         }
183
184         public String JavaDoc toString() {
185             return "[SmartyEntry key=" + key + " value=" + value + "]";
186         }
187     }
188
189 }
Popular Tags