KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > DatabaseDispatcher


1 /**
2  * com.mckoi.database.DatabaseDispatcher 19 Aug 2000
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
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 Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database;
26
27 import java.util.*;
28 import com.mckoi.debug.*;
29
30 /**
31  * This is the database system dispatcher thread. This is a thread that
32  * runs in the background servicing delayed events. This thread serves a
33  * number of purposes. It can be used to perform optimizations/clean ups in
34  * the background (similar to hotspot). It could be used to pause until
35  * sufficient information has been collected or there is a lull in
36  * work before it does a query in the background. For example, if a VIEW
37  * is invalidated because the underlying data changes, then we can wait
38  * until the data has finished updating, then perform the view query to
39  * update it correctly.
40  *
41  * @author Tobias Downer
42  */

43
44 class DatabaseDispatcher extends Thread JavaDoc {
45
46   private ArrayList event_queue = new ArrayList();
47
48   private TransactionSystem system;
49
50   private boolean finished;
51   
52   /**
53    * NOTE: Constructing this object will start the thread.
54    */

55   DatabaseDispatcher(TransactionSystem system) {
56     this.system = system;
57     setDaemon(true);
58     setName("Mckoi - Database Dispatcher");
59     finished = false;
60     start();
61   }
62
63   /**
64    * Creates an event object that is passed into 'addEventToDispatch' method
65    * to run the given Runnable method after the time has passed.
66    * <p>
67    * The event created here can be safely posted on the event queue as many
68    * times as you like. It's useful to create an event as a persistant object
69    * to service some event. Just post it on the dispatcher when you want
70    * it run!
71    */

72   Object JavaDoc createEvent(Runnable JavaDoc runnable) {
73     return new DatabaseEvent(runnable);
74   }
75
76   /**
77    * Adds a new event to be dispatched on the queue after 'time_to_wait'
78    * milliseconds has passed.
79    */

80   synchronized void postEvent(int time_to_wait, Object JavaDoc event) {
81     DatabaseEvent evt = (DatabaseEvent) event;
82     // Remove this event from the queue,
83
event_queue.remove(event);
84     // Set the correct time for the event.
85
evt.time_to_run_event = System.currentTimeMillis() + time_to_wait;
86     // Add to the queue in correct order
87
int index = Collections.binarySearch(event_queue, event);
88     if (index < 0) {
89       index = -(index + 1);
90     }
91     event_queue.add(index, event);
92
93     notifyAll();
94   }
95
96   /**
97    * Ends this dispatcher thread.
98    */

99   synchronized void finish() {
100     finished = true;
101     notifyAll();
102   }
103   
104
105   public void run() {
106     while (true) {
107       try {
108
109         DatabaseEvent evt = null;
110         synchronized (this) {
111           while (evt == null) {
112             // Return if finished
113
if (finished) {
114               return;
115             }
116
117             if (event_queue.size() > 0) {
118               // Get the top entry, do we execute it yet?
119
evt = (DatabaseEvent) event_queue.get(0);
120               long diff = evt.time_to_run_event - System.currentTimeMillis();
121               // If we got to wait for the event then do so now...
122
if (diff >= 0) {
123                 evt = null;
124                 wait((int) diff);
125               }
126             }
127             else {
128               // Event queue empty so wait for someone to put an event on it.
129
wait();
130             }
131           }
132           // Remove the top event from the list,
133
event_queue.remove(0);
134         }
135
136         // 'evt' is our event to run,
137
evt.runnable.run();
138
139       }
140       catch (Throwable JavaDoc e) {
141         system.Debug().write(Lvl.ERROR, this, "SystemDispatchThread error");
142         system.Debug().writeException(e);
143       }
144     }
145   }
146
147   // ---------- Inner classes ----------
148

149   class DatabaseEvent implements Comparable JavaDoc {
150     private long time_to_run_event;
151     private Runnable JavaDoc runnable;
152
153     DatabaseEvent(Runnable JavaDoc runnable) {
154       this.runnable = runnable;
155     }
156
157     public int compareTo(Object JavaDoc ob) {
158       DatabaseEvent evt2 = (DatabaseEvent) ob;
159       long dif = time_to_run_event - evt2.time_to_run_event;
160       if (dif > 0) {
161         return 1;
162       }
163       else if (dif < 0) {
164         return -1;
165       }
166       return 0;
167     }
168   }
169
170
171 }
172
Popular Tags