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.util.Collections;
23 import java.util.HashSet;
24 import java.util.Set;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /***
30 * Calls delete expired on the disk caches. The shrinker is run by a clock daemon. The shrinker
31 * calls delete on each region. It pauses between calls.
32 * <p>
33 * @author Aaron Smuts
34 */
35 public class ShrinkerThread
36 implements Runnable
37 {
38 /*** The logger. */
39 private final static Log log = LogFactory.getLog( ShrinkerThread.class );
40
41 /*** A set of JDBCDiskCache objects to call deleteExpired on. */
42 private Set shrinkSet = Collections.synchronizedSet( new HashSet() );
43
44 /***
45 * Default time period to use.
46 */
47 private static final long DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS = 5000;
48
49 /***
50 * How long should we wait between calls to deleteExpired when we are iterating through the list
51 * of regions. Delete can lock the table. We want to give clients a chance to get some work
52 * done.
53 */
54 private long pauseBetweenRegionCallsMillis = DEFAULT_PAUSE_BETWEEN_REGION_CALLS_MILLIS;
55
56 /***
57 * Does nothing special.
58 * <p>
59 * @param diskCache
60 */
61 protected ShrinkerThread()
62 {
63 super();
64 }
65
66 /***
67 * Adds a JDBC disk cache to the set of disk cache to shrink.
68 * <p>
69 * @param diskCache
70 */
71 public void addDiskCacheToShrinkList( JDBCDiskCache diskCache )
72 {
73
74
75
76
77 shrinkSet.add( diskCache );
78 }
79
80 /***
81 * Calls deleteExpired on each item in the set. It pauses between each call.
82 */
83 public void run()
84 {
85 if ( log.isInfoEnabled() )
86 {
87 log.info( "Running JDBC disk cache shrinker. Number of regions [" + shrinkSet.size() + "]" );
88 }
89
90 Object[] caches = null;
91
92 synchronized ( shrinkSet )
93 {
94 caches = this.shrinkSet.toArray();
95 }
96
97 if ( caches != null )
98 {
99 for ( int i = 0; i < caches.length; i++ )
100 {
101 JDBCDiskCache cache = (JDBCDiskCache) caches[i];
102
103 long start = System.currentTimeMillis();
104 int deleted = cache.deleteExpired();
105 long end = System.currentTimeMillis();
106
107 if ( log.isInfoEnabled() )
108 {
109 log.info( "Deleted [" + deleted + "] expired for region [" + cache.getCacheName() + "] for table ["
110 + cache.getTableName() + "] in " + ( end - start ) + " ms." );
111 }
112
113
114 if ( i < caches.length - 1 )
115 {
116 if ( log.isInfoEnabled() )
117 {
118 log.info( "Pausing for [" + this.getPauseBetweenRegionCallsMillis()
119 + "] ms. before shinker the next region." );
120 }
121
122 try
123 {
124 Thread.sleep( this.getPauseBetweenRegionCallsMillis() );
125 }
126 catch ( InterruptedException e )
127 {
128 log.warn( "Interrupted while waiting to delete expired for the enxt region." );
129 }
130 }
131 }
132 }
133 }
134
135 /***
136 * How long should we wait between calls to deleteExpired when we are iterating through the list
137 * of regions.
138 * <p>
139 * @param pauseBetweenRegionCallsMillis The pauseBetweenRegionCallsMillis to set.
140 */
141 public void setPauseBetweenRegionCallsMillis( long pauseBetweenRegionCallsMillis )
142 {
143 this.pauseBetweenRegionCallsMillis = pauseBetweenRegionCallsMillis;
144 }
145
146 /***
147 * How long should we wait between calls to deleteExpired when we are iterating through the list
148 * of regions.
149 * <p>
150 * @return Returns the pauseBetweenRegionCallsMillis.
151 */
152 public long getPauseBetweenRegionCallsMillis()
153 {
154 return pauseBetweenRegionCallsMillis;
155 }
156 }