1 57 58 package com.Yasna.util; 59 60 import java.util.*; 61 import com.Yasna.util.LinkedList; 62 63 110 public class Cache implements Cacheable { 111 112 118 protected static long currentTime = System.currentTimeMillis(); 119 120 124 protected static CacheTimer timer = new CacheTimer(1000L); 125 126 130 protected HashMap cachedObjectsHash; 131 132 136 protected LinkedList lastAccessedList; 137 138 142 protected LinkedList ageList; 143 144 148 protected int maxSize = 128 * 1024; 149 150 153 protected int size = 0; 154 155 159 protected long maxLifetime = -1; 160 161 169 protected long cacheHits, cacheMisses = 0L; 170 171 175 public Cache() { 176 cachedObjectsHash = new HashMap(103); 179 180 lastAccessedList = new LinkedList(); 181 ageList = new LinkedList(); 182 } 183 184 190 public Cache(int maxSize) { 191 this(); 192 this.maxSize = maxSize; 193 } 194 195 206 public Cache(long maxLifetime) { 207 this(); 208 this.maxLifetime = maxLifetime; 209 } 210 211 219 public Cache(int maxSize, long maxLifetime) { 220 this(); 221 this.maxSize = maxSize; 222 this.maxLifetime = maxLifetime; 223 } 224 225 230 public int getSize() { 231 return size; 232 } 233 234 241 public int getMaxSize() { 242 return maxSize; 243 } 244 245 252 public void setMaxSize(int maxSize) { 253 this.maxSize = maxSize; 254 cullCache(); 257 } 258 259 264 public synchronized int getNumElements() { 265 return cachedObjectsHash.size(); 266 } 267 268 274 public synchronized void add(Object key, Cacheable object) { 275 278 if (cachedObjectsHash.containsKey(key)) { 280 return; 281 } 282 int objectSize = object.getSize(); 283 if (objectSize > maxSize * .90) { 285 return; 286 } 287 size += objectSize; 288 CacheObject cacheObject = new CacheObject(object, objectSize); 289 cachedObjectsHash.put(key, cacheObject); 290 LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key); 292 cacheObject.lastAccessedListNode = lastAccessedNode; 295 LinkedListNode ageNode = ageList.addFirst(key); 297 ageNode.timestamp = System.currentTimeMillis(); 300 cacheObject.ageListNode = ageNode; 301 302 cullCache(); 305 } 306 307 316 public synchronized Cacheable get(Object key) { 317 deleteExpiredEntries(); 320 321 CacheObject cacheObject = (CacheObject)cachedObjectsHash.get(key); 322 if (cacheObject == null) { 323 cacheMisses++; 325 return null; 326 } 327 328 cacheHits++; 330 331 cacheObject.lastAccessedListNode.remove(); 334 lastAccessedList.addFirst(cacheObject.lastAccessedListNode); 335 336 return cacheObject.object; 337 } 338 339 344 public synchronized void remove(Object key) { 345 348 CacheObject cacheObject = (CacheObject)cachedObjectsHash.get(key); 349 if (cacheObject == null) { 351 return; 352 } 353 cachedObjectsHash.remove(key); 355 cacheObject.lastAccessedListNode.remove(); 357 cacheObject.ageListNode.remove(); 358 cacheObject.ageListNode = null; 360 cacheObject.lastAccessedListNode = null; 361 size -= cacheObject.size; 363 } 364 365 368 public synchronized void clear() { 369 372 Object [] keys = cachedObjectsHash.keySet().toArray(); 373 for (int i=0; i<keys.length; i++) { 374 remove(keys[i]); 375 } 376 377 cachedObjectsHash.clear(); 379 cachedObjectsHash = new HashMap(103); 380 lastAccessedList.clear(); 381 lastAccessedList = new LinkedList(); 382 ageList.clear(); 383 ageList = new LinkedList(); 384 385 size = 0; 386 cacheHits = 0; 387 cacheMisses = 0; 388 } 389 390 396 public Collection values() { 397 return Collections.unmodifiableCollection(cachedObjectsHash.values()); 398 } 399 400 410 public long getCacheHits() { 411 return cacheHits; 412 } 413 414 424 public long getCacheMisses() { 425 return cacheMisses; 426 } 427 428 432 private final void deleteExpiredEntries() { 433 if (maxLifetime <= 0) { 435 return; 436 } 437 438 LinkedListNode node = ageList.getLast(); 443 if (node == null) { 445 return; 446 } 447 448 long expireTime = currentTime - maxLifetime; 452 453 while(expireTime > node.timestamp) { 454 457 remove(node.object); 459 460 node = ageList.getLast(); 462 if (node == null) { 464 return; 465 } 466 } 467 } 468 469 475 private final void cullCache() { 476 if (size >= maxSize * .97) { 479 deleteExpiredEntries(); 481 int desiredSize = (int)(maxSize * .90); 482 while (size > desiredSize) { 483 remove(lastAccessedList.getLast().object); 485 } 486 } 487 } 488 } 489 490 | Popular Tags |