1 22 package org.jboss.util; 23 24 import java.util.ArrayList ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Timer ; 31 import java.util.TimerTask ; 32 33 46 public class TimedCachePolicy 47 extends TimerTask 48 implements CachePolicy 49 { 50 52 public static interface TimedEntry 53 { 54 58 public void init(long now); 59 60 63 public boolean isCurrent(long now); 64 65 68 public boolean refresh(); 69 70 72 public void destroy(); 73 74 77 public Object getValue(); 78 } 79 80 protected static Timer resolutionTimer = new Timer (true); 81 82 83 protected Map entryMap; 84 86 protected int defaultLifetime; 87 88 protected boolean threadSafe; 89 90 protected long now; 91 92 protected int resolution; 93 94 protected ResolutionTimer theTimer; 95 96 100 public TimedCachePolicy() 101 { 102 this(30*60, false, 0); 103 } 104 108 public TimedCachePolicy(int defaultLifetime) 109 { 110 this(defaultLifetime, false, 0); 111 } 112 125 public TimedCachePolicy(int defaultLifetime, boolean threadSafe, int resolution) 126 { 127 this.defaultLifetime = defaultLifetime; 128 this.threadSafe = threadSafe; 129 if( resolution <= 0 ) 130 resolution = 60; 131 this.resolution = resolution; 132 } 133 134 137 public void create() 138 { 139 if( threadSafe ) 140 entryMap = Collections.synchronizedMap(new HashMap ()); 141 else 142 entryMap = new HashMap (); 143 now = System.currentTimeMillis(); 144 } 145 148 public void start() 149 { 150 theTimer = new ResolutionTimer(); 151 resolutionTimer.scheduleAtFixedRate(theTimer, 0, 1000*resolution); 152 } 153 155 public void stop() 156 { 157 theTimer.cancel(); 158 flush(); 159 } 160 162 public void destroy() 163 { 164 entryMap.clear(); 165 } 166 167 173 public Object get(Object key) 174 { 175 TimedEntry entry = (TimedEntry) entryMap.get(key); 176 if( entry == null ) 177 return null; 178 179 if( entry.isCurrent(now) == false ) 180 { if( entry.refresh() == false ) 182 { entry.destroy(); 184 entryMap.remove(key); 185 return null; 186 } 187 } 188 Object value = entry.getValue(); 189 return value; 190 } 191 196 public Object peek(Object key) 197 { 198 TimedEntry entry = (TimedEntry) entryMap.get(key); 199 Object value = null; 200 if( entry != null ) 201 value = entry.getValue(); 202 return value; 203 } 204 212 public void insert(Object key, Object value) 213 { 214 if( entryMap.containsKey(key) ) 215 throw new IllegalStateException ("Attempt to insert duplicate entry"); 216 TimedEntry entry = null; 217 if( (value instanceof TimedEntry) == false ) 218 { entry = new DefaultTimedEntry(defaultLifetime, value); 220 } 221 else 222 { 223 entry = (TimedEntry) value; 224 } 225 entry.init(now); 226 entryMap.put(key, entry); 227 } 228 231 public void remove(Object key) 232 { 233 TimedEntry entry = (TimedEntry) entryMap.remove(key); 234 if( entry != null ) 235 entry.destroy(); 236 } 237 239 public void flush() 240 { 241 Map tmpMap = null; 242 synchronized( this ) 243 { 244 tmpMap = entryMap; 245 if( threadSafe ) 246 entryMap = Collections.synchronizedMap(new HashMap ()); 247 else 248 entryMap = new HashMap (); 249 } 250 251 Iterator iter = tmpMap.values().iterator(); 253 while( iter.hasNext() ) 254 { 255 TimedEntry entry = (TimedEntry) iter.next(); 256 entry.destroy(); 257 } 258 tmpMap.clear(); 259 } 260 261 public int size() 262 { 263 return entryMap.size(); 264 } 265 267 271 public List getValidKeys() 272 { 273 ArrayList validKeys = new ArrayList (); 274 synchronized( entryMap ) 275 { 276 Iterator iter = entryMap.entrySet().iterator(); 277 while( iter.hasNext() ) 278 { 279 Map.Entry entry = (Map.Entry ) iter.next(); 280 TimedEntry value = (TimedEntry) entry.getValue(); 281 if( value.isCurrent(now) == true ) 282 validKeys.add(entry.getKey()); 283 } 284 } 285 return validKeys; 286 } 287 288 291 public int getDefaultLifetime() 292 { 293 return defaultLifetime; 294 } 295 299 public synchronized void setDefaultLifetime(int defaultLifetime) 300 { 301 this.defaultLifetime = defaultLifetime; 302 } 303 304 308 public int getResolution() 309 { 310 return resolution; 311 } 312 318 public synchronized void setResolution(int resolution) 319 { 320 if( resolution <= 0 ) 321 resolution = 60; 322 if( resolution != this.resolution ) 323 { 324 this.resolution = resolution; 325 theTimer.cancel(); 326 theTimer = new ResolutionTimer(); 327 resolutionTimer.scheduleAtFixedRate(theTimer, 0, 1000*resolution); 328 } 329 } 330 331 334 public void run() 335 { 336 now = System.currentTimeMillis(); 337 } 338 339 342 public long currentTimeMillis() 343 { 344 return now; 345 } 346 347 350 public TimedEntry peekEntry(Object key) 351 { 352 TimedEntry entry = (TimedEntry) entryMap.get(key); 353 return entry; 354 } 355 356 359 static class DefaultTimedEntry implements TimedEntry 360 { 361 long expirationTime; 362 Object value; 363 364 DefaultTimedEntry(long lifetime, Object value) 365 { 366 this.expirationTime = 1000 * lifetime; 367 this.value = value; 368 } 369 public void init(long now) 370 { 371 expirationTime += now; 372 } 373 public boolean isCurrent(long now) 374 { 375 return expirationTime > now; 376 } 377 public boolean refresh() 378 { 379 return false; 380 } 381 public void destroy() 382 { 383 } 384 public Object getValue() 385 { 386 return value; 387 } 388 } 389 390 393 private class ResolutionTimer extends TimerTask 394 { 395 public void run() 396 { 397 TimedCachePolicy.this.run(); 398 } 399 } 400 } 401 402 | Popular Tags |