KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc2 > schema > PartitionedTableCache


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc2.schema;
23
24 import org.jboss.system.ServiceMBeanSupport;
25
26 import javax.transaction.Transaction JavaDoc;
27
28 /**
29  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
30  * @version <tt>$Revision: 37459 $</tt>
31  * @jmx:mbean extends="org.jboss.system.ServiceMBean"
32  */

33 public class PartitionedTableCache
34    extends ServiceMBeanSupport
35    implements Cache, PartitionedTableCacheMBean
36 {
37    private Cache.Listener listener = Cache.Listener.NOOP;
38
39    private final int minCapacity;
40    private final int minPartitionCapacity;
41    private int maxCapacity;
42    private int maxPartitionCapacity;
43
44    private final TableCache[] partitions;
45
46    private Overager overager;
47
48    public PartitionedTableCache(int minCapacity, int maxCapacity, int partitionsTotal)
49    {
50       this.minCapacity = minCapacity;
51       this.maxCapacity = maxCapacity;
52
53       minPartitionCapacity = minCapacity / partitionsTotal + 1;
54       maxPartitionCapacity = maxCapacity / partitionsTotal + 1;
55       partitions = new TableCache[partitionsTotal];
56       for(int i = 0; i < partitions.length; ++i)
57       {
58          partitions[i] = new TableCache(i, minPartitionCapacity, maxPartitionCapacity);
59       }
60
61       if(log.isTraceEnabled())
62       {
63          log.trace("min-capacity=" + minCapacity + ", max-capacity=" + maxCapacity + ", partitions=" + partitionsTotal);
64       }
65    }
66
67    public void stopService()
68    {
69       if(overager != null)
70       {
71          overager.stop();
72       }
73    }
74
75    public void initOverager(long period, long maxAge, String JavaDoc threadName)
76    {
77       final long periodMs = period * 1000;
78       final long maxAgeMs = maxAge * 1000;
79       overager = new Overager(maxAgeMs, periodMs);
80       new Thread JavaDoc(overager, threadName).start();
81    }
82
83    /**
84     * @jmx.managed-operation
85     */

86    public void registerListener(Cache.Listener listener)
87    {
88       if(log.isTraceEnabled())
89       {
90          log.trace("registered listener for " + getServiceName());
91       }
92
93       this.listener = listener;
94       for(int i = 0; i < partitions.length; ++i)
95       {
96          partitions[i].registerListener(listener);
97       }
98    }
99
100    /**
101     * @jmx.managed-operation
102     */

103    public int size()
104    {
105       int size = 0;
106       for(int i = 0; i < partitions.length; ++i)
107       {
108          size += partitions[i].size();
109       }
110       return size;
111    }
112
113    /**
114     * @jmx.managed-attribute
115     */

116    public int getMaxCapacity()
117    {
118       return maxCapacity;
119    }
120
121    /**
122     * @jmx.managed-attribute
123     */

124    public void setMaxCapacity(int maxCapacity)
125    {
126       this.maxCapacity = maxCapacity;
127       this.maxPartitionCapacity = maxCapacity / partitions.length + 1;
128       for(int i = 0; i < partitions.length; ++i)
129       {
130          partitions[i].setMaxCapacity(maxPartitionCapacity);
131       }
132    }
133
134    /**
135     * @jmx.managed-attribute
136     */

137    public int getMinCapacity()
138    {
139       return minCapacity;
140    }
141
142    /**
143     * @jmx.managed-attribute
144     */

145    public int getPartitionsTotal()
146    {
147       return partitions.length;
148    }
149
150    /**
151     * @jmx.managed-attribute
152     */

153    public int getMinPartitionCapacity()
154    {
155       return minPartitionCapacity;
156    }
157
158    /**
159     * @jmx.managed-attribute
160     */

161    public int getMaxPartitionCapacity()
162    {
163       return maxPartitionCapacity;
164    }
165
166    public void lock()
167    {
168    }
169
170    public void lock(Object JavaDoc key)
171    {
172       int partitionIndex = getPartitionIndex(key);
173       partitions[partitionIndex].lock(key);
174    }
175
176    public void unlock()
177    {
178    }
179
180    public void unlock(Object JavaDoc key)
181    {
182       int partitionIndex = getPartitionIndex(key);
183       partitions[partitionIndex].unlock(key);
184    }
185
186    public Object JavaDoc[] getFields(Object JavaDoc pk)
187    {
188       final int i = getPartitionIndex(pk);
189       return partitions[i].getFields(pk);
190    }
191
192    public Object JavaDoc[] getRelations(Object JavaDoc pk)
193    {
194       final int i = getPartitionIndex(pk);
195       return partitions[i].getRelations(pk);
196    }
197
198    public void put(Transaction JavaDoc tx, Object JavaDoc pk, Object JavaDoc[] fields, Object JavaDoc[] relations)
199    {
200       final int i = getPartitionIndex(pk);
201       partitions[i].put(tx, pk, fields, relations);
202    }
203
204    public void remove(Transaction JavaDoc tx, Object JavaDoc pk)
205    {
206       final int i = getPartitionIndex(pk);
207       partitions[i].remove(tx, pk);
208    }
209
210    public boolean contains(Transaction JavaDoc tx, Object JavaDoc pk)
211    {
212       final int i = getPartitionIndex(pk);
213       return partitions[i].contains(tx, pk);
214    }
215
216    public void lockForUpdate(Transaction JavaDoc tx, Object JavaDoc pk) throws Exception JavaDoc
217    {
218       final int i = getPartitionIndex(pk);
219       partitions[i].lockForUpdate(tx, pk);
220    }
221
222    public void releaseLock(Transaction JavaDoc tx, Object JavaDoc pk) throws Exception JavaDoc
223    {
224       final int i = getPartitionIndex(pk);
225       partitions[i].releaseLock(tx, pk);
226    }
227
228    public void flush()
229    {
230       for(int i = 0; i < partitions.length; ++i)
231       {
232          final TableCache partition = partitions[i];
233          partition.lock();
234          try
235          {
236             partition.flush();
237          }
238          finally
239          {
240             partition.unlock();
241          }
242       }
243    }
244    
245    // Private
246

247    private int getPartitionIndex(Object JavaDoc key)
248    {
249       return Math.abs(key.hashCode()) % partitions.length;
250    }
251
252    // Inner
253

254    private class Overager implements Runnable JavaDoc
255    {
256       private final long maxAgeMs;
257       private final long periodMs;
258       private boolean run = true;
259
260       public Overager(long maxAgeMs, long periodMs)
261       {
262          this.maxAgeMs = maxAgeMs;
263          this.periodMs = periodMs;
264       }
265
266       public void stop()
267       {
268          run = false;
269       }
270
271       public void run()
272       {
273          while(run)
274          {
275             long lastUpdated = System.currentTimeMillis() - maxAgeMs;
276             for(int i = 0; i < partitions.length; ++i)
277             {
278                partitions[i].ageOut(lastUpdated);
279             }
280
281             try
282             {
283                Thread.sleep(periodMs);
284             }
285             catch(InterruptedException JavaDoc e)
286             {
287             }
288          }
289       }
290    }
291 }
292
Popular Tags