1 package org.apache.jcs.auxiliary.disk.jdbc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.util.Hashtable;
25 import java.util.Map;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.ThreadFactory;
29 import java.util.concurrent.TimeUnit;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.jcs.auxiliary.AuxiliaryCache;
34 import org.apache.jcs.auxiliary.disk.AbstractDiskCacheManager;
35
36
37
38
39
40
41
42 public abstract class JDBCDiskCacheManagerAbstractTemplate
43 extends AbstractDiskCacheManager
44 {
45
46 private static final long serialVersionUID = 218557927622128905L;
47
48
49 private static final Log log = LogFactory.getLog( JDBCDiskCacheManagerAbstractTemplate.class );
50
51
52 protected static int clients;
53
54
55 protected static Hashtable<String, JDBCDiskCache<? extends Serializable, ? extends Serializable>> caches =
56 new Hashtable<String, JDBCDiskCache<? extends Serializable, ? extends Serializable>>();
57
58
59
60
61
62 protected static Hashtable<String, TableState> tableStates = new Hashtable<String, TableState>();
63
64
65 private ScheduledExecutorService shrinkerDaemon;
66
67
68
69
70
71 private final Map<String, ShrinkerThread> shrinkerThreadMap = new Hashtable<String, ShrinkerThread>();
72
73
74
75
76
77
78
79
80 protected abstract <K extends Serializable, V extends Serializable> JDBCDiskCache<K, V> createJDBCDiskCache( JDBCDiskCacheAttributes cattr, TableState tableState );
81
82
83
84
85
86
87
88
89 public <K extends Serializable, V extends Serializable> JDBCDiskCache<K, V> getCache( JDBCDiskCacheAttributes cattr )
90 {
91 JDBCDiskCache<K, V> diskCache = null;
92
93 log.debug( "cacheName = " + cattr.getCacheName() );
94
95 synchronized ( caches )
96 {
97 @SuppressWarnings("unchecked")
98 JDBCDiskCache<K, V> jdbcDiskCache = (JDBCDiskCache<K, V>) caches.get( cattr.getCacheName() );
99 diskCache = jdbcDiskCache;
100
101 if ( diskCache == null )
102 {
103 TableState tableState = tableStates.get( cattr.getTableName() );
104
105 if ( tableState == null )
106 {
107 tableState = new TableState( cattr.getTableName() );
108 }
109
110 diskCache = createJDBCDiskCache( cattr, tableState );
111 diskCache.setCacheEventLogger( getCacheEventLogger() );
112 diskCache.setElementSerializer( getElementSerializer() );
113 caches.put( cattr.getCacheName(), diskCache );
114 }
115 }
116
117 if ( log.isDebugEnabled() )
118 {
119 log.debug( "JDBC cache = " + diskCache );
120 }
121
122
123 createShrinkerWhenNeeded( cattr, diskCache );
124
125 return diskCache;
126 }
127
128
129
130
131
132
133
134 protected void createShrinkerWhenNeeded( JDBCDiskCacheAttributes cattr, AuxiliaryCache<?, ?> raf )
135 {
136
137 if ( cattr.isUseDiskShrinker() )
138 {
139 if ( shrinkerDaemon == null )
140 {
141 shrinkerDaemon = Executors.newScheduledThreadPool(2, new MyThreadFactory());
142 }
143
144 ShrinkerThread shrinkerThread = shrinkerThreadMap.get( cattr.getTableName() );
145 if ( shrinkerThread == null )
146 {
147 shrinkerThread = new ShrinkerThread();
148 shrinkerThreadMap.put( cattr.getTableName(), shrinkerThread );
149
150 long intervalMillis = Math.max( 999, cattr.getShrinkerIntervalSeconds() * 1000 );
151 if ( log.isInfoEnabled() )
152 {
153 log.info( "Setting the shrinker to run every [" + intervalMillis + "] ms. for table ["
154 + cattr.getTableName() + "]" );
155 }
156 shrinkerDaemon.scheduleAtFixedRate(shrinkerThread, 0, intervalMillis, TimeUnit.MILLISECONDS);
157 }
158 shrinkerThread.addDiskCacheToShrinkList( (JDBCDiskCache<?, ?>) raf );
159 }
160 }
161
162
163
164
165 public void freeCache( String name )
166 {
167 JDBCDiskCache<?, ?> raf = caches.get( name );
168 if ( raf != null )
169 {
170 try
171 {
172 raf.dispose();
173 }
174 catch ( IOException e )
175 {
176 log.error( "Problem disposing of disk.", e );
177 }
178 }
179 }
180
181
182 public void release()
183 {
184
185 if ( --clients != 0 )
186 {
187 return;
188 }
189 synchronized ( caches )
190 {
191 for (JDBCDiskCache<?, ?> raf : caches.values())
192 {
193 if ( raf != null )
194 {
195 try
196 {
197 raf.dispose();
198 }
199 catch ( IOException e )
200 {
201 log.error( "Problem disposing of disk.", e );
202 }
203 }
204 }
205 }
206 }
207
208
209
210
211 protected static class MyThreadFactory
212 implements ThreadFactory
213 {
214
215
216
217
218
219
220 public Thread newThread( Runnable runner )
221 {
222 Thread t = new Thread( runner );
223 String oldName = t.getName();
224 t.setName( "JCS-JDBCDiskCacheManager-" + oldName );
225 t.setDaemon( true );
226 t.setPriority( Thread.MIN_PRIORITY );
227 return t;
228 }
229 }
230 }