1 24 25 package com.jdon.util; 26 27 import java.text.DecimalFormat ; 28 import java.util.Iterator ; 29 import java.util.LinkedList ; 30 import java.util.Map ; 31 import java.util.concurrent.ConcurrentHashMap ; 32 33 49 public class UtilCache { 50 public static String module = UtilCache.class.getName(); 51 52 static final DecimalFormat percentFormat = new DecimalFormat ("#0.0"); 54 55 private PropsUtil propsUtil; 56 57 58 public static Map utilCacheTable = new ConcurrentHashMap (); 59 60 64 protected static Map defaultIndices = new ConcurrentHashMap (); 65 66 70 protected String name; 71 72 73 public LinkedList keyLRUList = new LinkedList (); 74 75 80 public Map cacheLineTable = new ConcurrentHashMap (); 81 82 83 84 protected long hitCount = 0; 85 86 87 88 protected long missCount = 0; 89 90 94 protected long maxSize = 0; 95 96 100 protected long expireTime = 0; 101 102 106 protected boolean useSoftReference = false; 107 108 124 public UtilCache(PropsUtil propsUtil, String cacheName, long maxSize, long expireTime, boolean useSoftReference) { 125 this.propsUtil = propsUtil; 126 this.useSoftReference = useSoftReference; 127 this.maxSize = maxSize; 128 this.expireTime = expireTime; 129 setPropertiesParams(cacheName); 130 131 name = cacheName + this.getNextDefaultIndex(cacheName); 132 utilCacheTable.put(name, this); 133 } 134 135 147 public UtilCache(PropsUtil propsUtil, String cacheName, long maxSize, long expireTime) { 148 this(propsUtil, cacheName, maxSize, expireTime, false); 149 } 150 151 159 public UtilCache(PropsUtil propsUtil, long maxSize, long expireTime) { 160 this.propsUtil = propsUtil; 161 this.useSoftReference = false; 162 this.maxSize = maxSize; 163 this.expireTime = expireTime; 164 String name = "specified" + this.getNextDefaultIndex("specified"); 165 166 setPropertiesParams(name); 167 utilCacheTable.put(name, this); 168 } 169 170 178 public UtilCache(PropsUtil propsUtil, String cacheName) { 179 this.propsUtil = propsUtil; 180 setPropertiesParams("default"); 181 setPropertiesParams(cacheName); 182 183 name = cacheName + this.getNextDefaultIndex(cacheName); 184 utilCacheTable.put(name, this); 185 } 186 187 192 public UtilCache(PropsUtil propsUtil) { 193 this.propsUtil = propsUtil; 194 setPropertiesParams("default"); 195 196 name = "default" + this.getNextDefaultIndex("default"); 197 utilCacheTable.put(name, this); 198 } 199 200 protected String getNextDefaultIndex(String cacheName) { 201 Integer curInd = (Integer ) UtilCache.defaultIndices.get(cacheName); 202 203 if (curInd == null) { 204 UtilCache.defaultIndices.put(cacheName, new Integer (1)); 205 return ""; 206 } else { 207 UtilCache.defaultIndices.put(cacheName, new Integer (curInd.intValue() + 1)); 208 return Integer.toString(curInd.intValue() + 1); 209 } 210 } 211 212 protected void setPropertiesParams(String cacheName) { 213 if (propsUtil == null) { 214 System.err.println(" UtilCache propsUtil not yet set!! "); 215 return; 216 } 217 218 try { 219 String value = propsUtil.getProperty("cache." + cacheName + ".maxSize"); 220 if (UtilValidate.isNotEmpty(value)) { 221 Debug.logVerbose("[JdonFramework]found cache configure: cache." + cacheName + ".maxSize = " + value, module); 222 Long longValue = new Long (value); 223 if (longValue != null) { 224 maxSize = longValue.longValue(); 225 } 226 } 227 } catch (Exception e) { 228 } 229 230 try { 231 String value = propsUtil.getProperty("cache." + cacheName + ".expireTime"); 232 if (UtilValidate.isNotEmpty(value)) { 233 234 Long longValue = new Long (value); 235 236 if (longValue != null) { 237 expireTime = longValue.longValue(); 238 } 239 } 240 } catch (Exception e) { 241 } 242 243 try { 244 String value = propsUtil.getProperty("cache." + cacheName + ".useSoftReference"); 245 if (UtilValidate.isNotEmpty(value)) { 246 useSoftReference = "true".equals(value); 247 } 248 } catch (Exception e) { 249 } 250 } 251 252 261 public synchronized void put(Object key, Object value) { 262 if (key == null) 263 return; 264 265 if (maxSize > 0) { 266 if (cacheLineTable.containsKey(key)) { 269 keyLRUList.remove(key); 270 keyLRUList.addFirst(key); 271 } else { 272 keyLRUList.addFirst(key); 273 } 274 } 275 276 if (expireTime > 0) { 277 cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference, System.currentTimeMillis())); 278 } else { 279 cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference)); 280 } 281 if (maxSize > 0 && cacheLineTable.size() > maxSize) { 282 Object lastKey = keyLRUList.getLast(); 283 remove(lastKey); 284 } 285 Debug.logVerbose("[JdonFramework]cache now size = " + keyLRUList.size() + " maxSize =" + maxSize + 286 " this Cache id:" + this.hashCode(), module); 287 288 } 289 290 300 public Object get(Object key) { 301 302 if (key == null) { 303 missCount++; 304 return null; 305 } 306 UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.get(key); 307 308 if (hasExpired(line)) { 309 remove(key); 314 line = null; 315 } 316 317 if (line == null) { 318 missCount++; 321 return null; 322 } 323 hitCount++; 325 328 if (maxSize > 0) { 329 keyLRUList.remove(key); 330 keyLRUList.addFirst(key); 331 } 332 return line.getValue(); 333 } 334 335 343 public synchronized Object remove(Object key) { 344 if (key == null) { 345 missCount++; 346 return null; 347 } 348 349 UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.remove(key); 350 if (line != null) { 351 if (maxSize > 0) 352 keyLRUList.remove(key); 353 return line.getValue(); 354 } else { 355 missCount++; 356 return null; 357 } 358 } 359 360 361 public synchronized void clear() { 362 cacheLineTable.clear(); 363 keyLRUList.clear(); 364 clearCounters(); 365 } 366 367 368 public static void clearAllCaches() { 369 Iterator entries = utilCacheTable.entrySet().iterator(); 370 while (entries.hasNext()) { 371 Map.Entry entry = (Map.Entry ) entries.next(); 372 UtilCache utilCache = (UtilCache) entry.getValue(); 373 utilCache.clear(); 374 } 375 } 376 377 382 public String getName() { 383 return name; 384 } 385 386 391 public long getHitCount() { 392 return hitCount; 393 } 394 395 400 public long getMissCount() { 401 return missCount; 402 } 403 404 407 public void clearCounters() { 408 hitCount = 0; 409 missCount = 0; 410 } 411 412 419 public void setMaxSize(long maxSize) { 420 if (maxSize <= 0) { 422 keyLRUList.clear(); 423 } else if (maxSize > 0 && this.maxSize <= 0) { 424 Iterator keys = cacheLineTable.keySet().iterator(); 427 428 while (keys.hasNext()) { 429 keyLRUList.add(keys.next()); 430 } 431 } 432 433 if (maxSize > 0 && cacheLineTable.size() > maxSize) { 436 while (cacheLineTable.size() > maxSize) { 437 Object lastKey = keyLRUList.getLast(); 438 439 remove(lastKey); 440 } 441 } 442 443 this.maxSize = maxSize; 444 } 445 446 451 public long getMaxSize() { 452 return maxSize; 453 } 454 455 461 public void setExpireTime(long expireTime) { 462 if (this.expireTime <= 0 && expireTime > 0) { 464 long currentTime = System.currentTimeMillis(); 465 Iterator values = cacheLineTable.values().iterator(); 466 467 while (values.hasNext()) { 468 UtilCache.CacheLine line = (UtilCache.CacheLine) values.next(); 469 470 line.loadTime = currentTime; 471 } 472 } else if (this.expireTime <= 0 && expireTime > 0) { } 481 482 this.expireTime = expireTime; 483 } 484 485 490 public long getExpireTime() { 491 return expireTime; 492 } 493 494 498 public void setUseSoftReference(boolean useSoftReference) { 499 if (this.useSoftReference != useSoftReference) { 500 this.useSoftReference = useSoftReference; 501 Iterator values = cacheLineTable.values().iterator(); 502 503 while (values.hasNext()) { 504 UtilCache.CacheLine line = (UtilCache.CacheLine) values.next(); 505 506 line.setUseSoftReference(useSoftReference); 507 } 508 } 509 } 510 511 515 public boolean getUseSoftReference() { 516 return this.useSoftReference; 517 } 518 519 524 public long size() { 525 return cacheLineTable.size(); 526 } 527 528 539 public boolean containsKey(Object key) { 540 UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.get(key); 541 542 if (hasExpired(line)) { 543 remove(key); 544 line = null; 545 } 546 if (line != null) { 547 return true; 548 } else { 549 return false; 550 } 551 } 552 553 566 public boolean hasExpired(Object key) { 567 if (key == null) 568 return false; 569 570 UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.get(key); 571 572 return hasExpired(line); 573 } 574 575 protected boolean hasExpired(UtilCache.CacheLine line) { 576 if (line == null) 577 return false; 578 if (this.useSoftReference && line.getValue() == null) 583 return true; 584 if (expireTime <= 0) 585 return false; 586 587 if (line.loadTime <= 0) 588 return true; 589 if ((line.loadTime + expireTime) < System.currentTimeMillis()) { 590 return true; 591 } else { 592 return false; 593 } 594 } 595 596 600 public void clearExpired() { 601 Iterator keys = cacheLineTable.keySet().iterator(); 602 603 while (keys.hasNext()) { 604 Object key = keys.next(); 605 606 if (hasExpired(key)) { 607 remove(key); 608 } 609 } 610 } 611 612 613 public static void clearExpiredFromAllCaches() { 614 Iterator entries = utilCacheTable.entrySet().iterator(); 615 616 while (entries.hasNext()) { 617 Map.Entry entry = (Map.Entry ) entries.next(); 618 UtilCache utilCache = (UtilCache) entry.getValue(); 619 620 utilCache.clearExpired(); 621 } 622 } 623 624 625 public static boolean validKey(String cacheName, Object key) { 626 UtilCache cache = (UtilCache) utilCacheTable.get(cacheName); 627 if (cache != null) { 628 if (cache.containsKey(key)) 629 return true; 630 } 631 return false; 632 } 633 634 public static class CacheLine { 635 public Object valueRef = null; 636 637 public long loadTime = 0; 638 639 public boolean useSoftReference = false; 640 641 public CacheLine(Object value, boolean useSoftReference) { 642 if (useSoftReference) { 643 this.valueRef = new java.lang.ref.SoftReference (value); 644 } else { 645 this.valueRef = value; 646 } 647 this.useSoftReference = useSoftReference; 648 } 649 650 public CacheLine(Object value, boolean useSoftReference, long loadTime) { 651 this(value, useSoftReference); 652 this.loadTime = loadTime; 653 } 654 655 public Object getValue() { 656 if (valueRef == null) 657 return null; 658 if (useSoftReference) { 659 return ((java.lang.ref.SoftReference ) valueRef).get(); 660 } else { 661 return valueRef; 662 } 663 } 664 665 public void setUseSoftReference(boolean useSoftReference) { 666 if (this.useSoftReference != useSoftReference) { 667 synchronized (this) { 668 this.useSoftReference = useSoftReference; 669 if (useSoftReference) { 670 this.valueRef = new java.lang.ref.SoftReference (this.valueRef); 671 } else { 672 this.valueRef = ((java.lang.ref.SoftReference ) this.valueRef).get(); 673 } 674 } 675 } 676 } 677 } 678 679 682 public PropsUtil getPropsUtil() { 683 return propsUtil; 684 } 685 686 690 public void setPropsUtil(PropsUtil propsUtil) { 691 this.propsUtil = propsUtil; 692 } 693 } 694 | Popular Tags |