1 64 65 package com.jcorporate.expresso.core.cache; 66 67 import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock; 68 import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock; 69 import org.apache.commons.collections.LRUMap; 70 import org.apache.log4j.Logger; 71 72 import java.util.HashMap ; 73 import java.util.Iterator ; 74 import java.util.Map ; 75 import java.util.Vector ; 76 77 78 91 public class UnOrderedCache 92 implements Cache { 93 94 98 private final ReadWriteLock cacheLock = new WriterPreferenceReadWriteLock(); 99 100 103 private long accessCount = 0; 104 105 private Map cacheContents = java.util.Collections.synchronizedMap(new HashMap ()); 109 110 private String cacheName = null; 112 113 private static final String thisClass = UnOrderedCache.class.getName() + "."; 115 116 private int maxSize = 0; 118 119 private static final transient Logger log = Logger.getLogger(UnOrderedCache.class); 121 122 125 public UnOrderedCache() { 126 super(); 127 } 128 129 private final synchronized void incrementAccessCount() { 130 accessCount++; 131 } 132 133 138 public void addItem(CacheEntry newItem) { 139 incrementAccessCount(); 140 141 if (log.isDebugEnabled()) { 142 log.debug("Cache " + getName() + " Added item " + 143 newItem.getKey()); 144 } 145 146 try { 147 cacheLock.writeLock().acquire(); 148 } catch (InterruptedException ex) { 149 log.error("Interrupted waiting for write lock. Aborting method", ex); 150 return; 151 } 152 153 try { 154 cacheContents.put(newItem.getKey(), newItem); 157 158 newItem.clearUsedCount(); 159 } finally { 160 cacheLock.writeLock().release(); 161 } 162 } 163 164 167 public void clear() { 168 try { 169 cacheLock.writeLock().acquire(); 170 } catch (InterruptedException ex) { 171 log.error("Interrupted waiting for write lock. Aborting method", ex); 172 return; 173 } 174 try { 175 if (maxSize > 0) { 176 cacheContents = java.util.Collections.synchronizedMap(new LRUMap(maxSize)); 177 } else { 178 cacheContents = java.util.Collections.synchronizedMap(new HashMap ()); 179 } 180 } finally { 181 cacheLock.writeLock().release(); 182 } 183 } 184 185 191 public CacheEntry getCacheEntry(String itemKey) { 192 incrementAccessCount(); 193 CacheEntry returnValue = null; 194 boolean removeCacheItem = false; 195 CacheEntry oneItem = null; 196 try { 197 cacheLock.readLock().acquire(); 198 } catch (InterruptedException ex) { 199 log.error("Interrupted waiting for write lock. Aborting method", ex); 200 return null; 201 } 202 203 try { 204 oneItem = (CacheEntry) cacheContents.get(itemKey); 205 206 if (oneItem != null) { 207 if (oneItem.isExpired()) { 208 if (log.isDebugEnabled()) { 209 log.debug("Item '" + itemKey + 210 "' expired & was removed. Expiry was " + 211 oneItem.getExpires()); 212 } 213 removeCacheItem = true; 214 215 } else { 217 oneItem.incrementUsedCount(); 219 returnValue = oneItem; 220 } 221 } 222 223 } finally { 224 cacheLock.readLock().release(); 225 } 226 227 if (removeCacheItem) { 230 removeItem(oneItem.getContents()); 231 return null; 232 } 233 234 return returnValue; 235 } 236 237 244 public Cacheable getItem(String itemKey) { 245 CacheEntry oneItem = this.getCacheEntry(itemKey); 248 if (oneItem == null) { 249 return null; 250 } 251 252 if (oneItem.getContents() == null) { 253 if (log.isDebugEnabled()) { 254 log.debug("Item '" + itemKey + "' had null contents"); 255 } 256 } 257 258 return oneItem.getContents(); 259 } 260 261 266 public int getItemCount() { 267 int returnvalue = 0; 268 try { 269 cacheLock.readLock().acquire(); 270 } catch (InterruptedException ex) { 271 log.error("Interrupted waiting for write lock. Aborting method", ex); 272 return 0; 273 } 274 try { 275 returnvalue = cacheContents.size(); 276 } finally { 277 cacheLock.readLock().release(); 278 } 279 return returnvalue; 280 } 281 282 288 public Vector getItems() { 289 incrementAccessCount(); 290 Vector v = null; 291 try { 292 cacheLock.writeLock().acquire(); 293 } catch (InterruptedException ex) { 294 log.error("Interrupted waiting for write lock. Aborting method", ex); 295 return null; 296 } 297 298 try { 299 if (cacheContents.size() <= 0) { 300 return null; 301 } 302 303 int length = cacheContents.size(); 307 v = new Vector (length); 308 309 for (Iterator i = cacheContents.values().iterator(); i.hasNext();) { 310 CacheEntry oneItem = (CacheEntry) i.next(); 311 if (oneItem.isExpired()) { 312 i.remove(); 313 } else { 314 oneItem.incrementUsedCount(); 315 v.addElement(oneItem.getContents()); 316 } 317 } 318 } finally { 319 cacheLock.writeLock().release(); 320 } 321 322 return v; 323 } 324 325 330 public synchronized String getName() { 331 return cacheName; 332 } 333 334 339 public synchronized long getUsedCount() { 340 return accessCount; 341 } 342 343 349 public boolean isOrdered() { 350 return false; 351 } 352 353 354 359 public synchronized void removeItem(Cacheable oldItem) { 360 try { 361 cacheLock.writeLock().acquire(); 362 } catch (InterruptedException ex) { 363 log.error("Interrupted waiting for write lock. Aborting method", ex); 364 return; 365 } 366 try { 367 cacheContents.remove(oldItem.getKey()); 368 } finally { 369 cacheLock.writeLock().release(); 370 } 371 } 372 373 374 380 public void setItems(java.util.List newItems) throws CacheException { 381 if (newItems instanceof java.util.Vector ) { 382 setItems(newItems); 383 } else { 384 setItems(new Vector (newItems)); 385 } 386 } 387 388 395 public void setItems(Vector newItems) 396 throws CacheException { 397 incrementAccessCount(); 398 clear(); 399 try { 400 cacheLock.writeLock().acquire(); 401 } catch (InterruptedException ex) { 402 log.error("Interrupted waiting for write lock. Aborting method", ex); 403 return; 404 } 405 406 try { 407 Object oneObject = null; 408 int size = newItems.size(); 409 for (int i = 0; i < size; i++) { 410 oneObject = newItems.elementAt(i); 411 412 if (oneObject instanceof Cacheable) { 413 CacheEntry ce = new CacheEntry((Cacheable) oneObject, -1); 414 addItem(ce); 415 } else { 416 String myName = thisClass + ":setItems()"; 417 throw new CacheException(myName + 418 ":Item in vector is of class " + 419 oneObject.getClass().getName() + 420 ", which is not Cacheable - cannot set items"); 421 } 422 } 423 } finally { 424 cacheLock.writeLock().release(); 425 } 426 } 427 428 429 436 public synchronized void setMaxSize(int newMaxSize) { 437 try { 438 cacheLock.writeLock().acquire(); 439 } catch (InterruptedException ex) { 440 log.error("Interrupted waiting for write lock. Aborting method", ex); 441 return; 442 } 443 444 try { 445 if (newMaxSize > 0) { 446 LRUMap newMap = new LRUMap(newMaxSize); 447 if (cacheContents.size() > 0) { 448 newMap.putAll(cacheContents); 449 } 450 cacheContents = java.util.Collections.synchronizedMap(newMap); 451 } else { 452 cacheContents = java.util.Collections.synchronizedMap(new HashMap (cacheContents)); 453 } 454 455 maxSize = newMaxSize; 456 } finally { 457 cacheLock.writeLock().release(); 458 } 459 } 460 461 466 public synchronized void setName(String newName) { 467 cacheName = newName; 468 } 469 470 } 471 | Popular Tags |