1 22 23 package org.cofax; 24 25 import java.util.*; 26 27 import org.cofax.CofaxUtil; 28 29 38 39 public final class CofaxCache { 40 41 42 private String lastError; 43 44 45 private HashMap cacheHash = new HashMap(); 46 47 48 private HashMap dirtyHash = new HashMap(); 49 50 51 private int maxURLsToCount = 0; 52 53 54 private int maxURLsToStore = 0; 55 56 57 private int curLowTrack = 0; 58 59 60 private int curLowCache = 0; 61 62 63 private int dirtyReadTime = 0; 64 65 66 private String curLowTrackURL; 67 68 69 private String curLowCacheURL; 70 71 72 private String curOldCacheURL; 73 74 75 private long timeToRefresh = 0; 76 77 78 private long cacheRequests = 0; 79 80 81 private long cacheHits = 0; 82 83 84 private long dirtyHits = 0; 85 86 87 private long curCacheCount = 0; 88 89 90 private long curTrackCount = 0; 91 92 93 private long cacheTimeToDie = 0; 94 95 96 private long curOldCache = 0; 97 98 private Date clearedTimeTotal; 99 100 private Date maxTrackReached; 101 102 private Date maxStoreReached; 103 104 private boolean isMaxTrackReached; 105 106 private boolean isMaxStoreReached; 107 108 private boolean isCleaning = false; 110 112 127 public CofaxCache(int maxUrlsToCount, int maxUrlsToCache, int refreshCacheInterval, int dirtyReadInterval) { 128 129 this.maxURLsToCount = maxUrlsToCount; 130 this.maxURLsToStore = maxUrlsToCache; 131 this.timeToRefresh = refreshCacheInterval * CofaxUtil.MILLISECONDS_PER_MINUTE; 132 this.cacheTimeToDie = (refreshCacheInterval * CofaxUtil.MILLISECONDS_PER_MINUTE * 2); 134 this.dirtyReadTime = dirtyReadInterval * CofaxUtil.MILLISECONDS_PER_SECOND; 136 this.clearedTimeTotal = new Date(); 137 this.isMaxTrackReached = false; 138 this.isMaxStoreReached = false; 139 this.isCleaning = false; } 141 142 147 public long getTrackedCount() { 148 150 return curTrackCount; 151 } 152 153 158 public long getCachedCount() { 159 161 return curCacheCount; 162 } 163 164 169 public int getMaxTrack() { 170 172 return maxURLsToCount; 173 } 174 175 181 public void setMaxTrack(int inMaxURLsToCount) { 182 183 maxURLsToCount = inMaxURLsToCount; 184 185 } 186 187 192 public int getMaxStore() { 193 195 return maxURLsToStore; 196 } 197 198 204 public void setMaxStore(int inMaxURLsToStore) { 205 206 maxURLsToStore = inMaxURLsToStore; 207 208 } 209 210 215 public long getRefreshInterval() { 216 219 return timeToRefresh; 220 } 221 222 228 public void setRefreshInterval(int inTimeToRefresh) { 229 230 timeToRefresh = inTimeToRefresh; 231 232 } 233 234 239 public int getDirtyRead() { 240 241 return dirtyReadTime; 242 } 243 244 250 public void setDirtyRead(int inDirtyRead) { 251 252 dirtyReadTime = inDirtyRead; 253 254 } 255 256 261 public HashMap getCacheHash() { 262 265 return cacheHash; 266 } 267 268 273 public Date getClearedTimeTotal() { 274 275 return clearedTimeTotal; 276 } 277 278 283 public long getCacheRequests() { 284 285 return cacheRequests; 286 } 287 288 293 public long getCacheHits() { 294 295 return cacheHits; 296 } 297 298 303 public long getDirtyCacheHits() { 304 305 return dirtyHits; 306 } 307 308 313 public Date getMaxTrackReached() { 314 315 return maxTrackReached; 316 } 317 318 323 public Date getMaxStoreReached() { 324 325 return maxStoreReached; 326 } 327 328 333 public boolean getIsMaxTrackReached() { 334 335 return isMaxTrackReached; 336 } 337 338 343 public boolean getIsMaxStoreReached() { 344 345 return isMaxStoreReached; 346 } 347 348 353 public int getMaxTrackTurnOver() { 354 355 return 0; 356 358 } 359 360 363 public synchronized void clear() { 364 366 this.cacheHash.clear(); 367 this.curCacheCount = 0; 368 this.curTrackCount = 0; 369 clearedTimeTotal = new Date(); 370 isMaxStoreReached = false; 371 isMaxTrackReached = false; 372 373 } 374 375 391 public synchronized boolean isPageCached(String id) { 392 393 CofaxPage page = new CofaxPage(); 394 long curTime = new Date().getTime(); 395 cacheRequests++; 397 399 if (cacheHash.containsKey(id)) { 400 if (cacheHash.get(id) instanceof CofaxPage) { 402 page = (CofaxPage) cacheHash.get(id); 403 if (page.isPageCached()) { 405 if ((curTime - page.getLastModified()) < timeToRefresh) { 407 return true; 409 } else { 410 Integer x = new Integer (page.getHitCount()); 413 this.removeFromCache(id); 414 if (curTrackCount >= maxURLsToCount) { 415 this.dumpLowestTrackedHitCount(); 417 } 418 this.addPageToCache(id, x); 419 page.setStartBuildTime(); 420 this.dirtyHash.put(id, page); 423 } 424 } 425 } else if (isPageDirtyCached(id)) { 426 return true; 427 } 428 } else if (isPageDirtyCached(id)) { 429 return true; 430 } 431 return false; 432 434 } 435 436 449 public synchronized boolean isPageDirtyCached(String id) { 450 451 if (dirtyHash.containsKey(id)) { 452 CofaxPage page = new CofaxPage(); 453 page = (CofaxPage) dirtyHash.get(id); 454 long curTime = new Date().getTime(); 456 if ((curTime - page.getStartBuildTime()) < dirtyReadTime) { 458 return true; 460 } 461 } 462 return false; 463 } 464 465 473 public synchronized boolean removeFromCache(String id) { 474 475 if (cacheHash.containsKey(id)) { 476 if (cacheHash.get(id) instanceof CofaxPage) { 478 this.curCacheCount--; 479 } else if (cacheHash.get(id) instanceof Integer ) { 480 this.curTrackCount--; 481 } 482 cacheHash.remove(id); 483 this.generateLowTrackCount(); 484 this.generateLowCacheCount(); 485 this.generateOldCache(); 486 return (true); 487 } 488 return false; 489 } 490 491 503 public synchronized boolean expireInCache(String id) { 504 505 if (cacheHash.containsKey(id)) { 506 if (cacheHash.get(id) instanceof CofaxPage) { 508 CofaxPage page = (CofaxPage) cacheHash.get(id); 509 Date curDate = new Date(); 510 long expInOneMinute = curDate.getTime() - timeToRefresh + CofaxUtil.MILLISECONDS_PER_MINUTE; 511 page.setLastModified(expInOneMinute); 512 page.setPageCached(true); 513 page.setCachedTime(expInOneMinute); 514 return (true); 515 } 516 } 517 return (false); 518 } 519 520 523 private void printStats() { 524 525 long fOldCAge = curOldCache / CofaxUtil.MILLISECONDS_PER_MINUTE; 526 System.out.println("Cache Stats:"); 527 System.out.println(" Current Cached Pages: " + curCacheCount + " Max to cache: " + maxURLsToStore); 528 System.out.println(" Current Tracked Pages: " + curTrackCount + " Max to track: " + maxURLsToCount); 529 System.out.println(" Current Low Cache hits: " + curLowCache + " page: " + curLowCacheURL); 530 System.out.println(" Current Low Tracked hits: " + curLowTrack + " page: " + curLowTrackURL); 531 System.out.println(" Current Oldest Cache Age: " + fOldCAge + " page: " + curOldCacheURL); 532 533 } 534 535 544 public synchronized boolean incrementHitCount(String id) { 545 546 boolean toReturn = false; 547 CofaxPage curPage = new CofaxPage(); 548 549 if (cacheHash.containsKey(id)) { 550 if (cacheHash.get(id) instanceof CofaxPage) { 551 curPage = (CofaxPage) cacheHash.get(id); 552 curPage.incrementHitCount(); 553 toReturn = true; 554 } else if (cacheHash.get(id) instanceof Integer ) { 555 Integer x = new Integer (0); 556 x = (Integer ) cacheHash.get(id); 557 int y = x.intValue(); 558 y++; 559 x = new Integer (y); 560 cacheHash.put(id, x); 561 toReturn = true; 562 } 563 if (id.equals(curLowTrackURL)) { 566 this.generateLowTrackCount(); 567 } 568 569 if (id.equals(curLowCacheURL)) { 570 this.generateLowCacheCount(); 571 } 572 } 573 return toReturn; 574 } 575 576 582 private boolean dumpLowestTrackedHitCount() { 583 584 if (curTrackCount == 0) { 585 return false; 586 } 587 588 this.removeFromCache(curLowTrackURL); 589 return true; 590 } 591 592 600 public int getHitCount(String id) { 601 602 if (cacheHash.containsKey(id)) { 603 if (cacheHash.get(id) instanceof CofaxPage) { 604 CofaxPage testPage = new CofaxPage(); 605 testPage = (CofaxPage) cacheHash.get(id); 606 return testPage.getHitCount(); 607 } else if (cacheHash.get(id) instanceof Integer ) { 608 Integer x = new Integer (0); 609 x = (Integer ) cacheHash.get(id); 610 return x.intValue(); 611 } 612 } 613 return -1; 614 } 615 616 628 private synchronized boolean placePageInCache(String id, Object item, int hitCount) { 629 630 try { 631 Date curDate = new Date(); 632 CofaxPage page = new CofaxPage(); 633 page = (CofaxPage) item; 634 page.setLastModified(curDate.getTime()); 635 page.setPageCached(true); 636 page.setCachedTime(curDate.getTime()); 637 page.setHitCount(hitCount); 638 this.cacheHash.put(id, page); 639 this.curCacheCount++; 640 this.generateLowTrackCount(); 641 this.generateLowCacheCount(); 642 return true; 643 } catch (Exception e) { 644 lastError = e.toString(); 645 return false; 646 } 647 648 } 649 650 662 private synchronized boolean placeTrackInCache(String id, Object item) { 663 664 try { 665 this.cacheHash.put(id, item); 666 this.curTrackCount++; 667 this.generateLowTrackCount(); 668 return true; 669 } catch (Exception e) { 670 lastError = e.toString(); 671 return false; 672 } 673 674 } 675 676 691 public synchronized boolean addPageToCache(String id, Object item) { 692 693 try { 694 if (cacheHash.containsKey(id)) { 695 if (cacheHash.get(id) instanceof Integer ) { 697 Integer x = new Integer (0); 699 x = (Integer ) cacheHash.get(id); 700 this.removeFromCache(id); 701 if (item instanceof CofaxPage) { 703 this.placePageInCache(id, item, x.intValue()); 704 } else if (item instanceof Integer ) { 705 this.placeTrackInCache(id, item); 706 } 707 } else if (cacheHash.get(id) instanceof CofaxPage) { 708 this.removeFromCache(id); 710 if (item instanceof CofaxPage) { 712 this.placePageInCache(id, item, 1); 713 } else if (item instanceof Integer ) { 714 this.placeTrackInCache(id, item); 715 } 716 } 717 } else { 718 if (item instanceof CofaxPage) { 720 this.placePageInCache(id, item, 1); 721 } else if (item instanceof Integer ) { 722 this.placeTrackInCache(id, item); 723 } 724 } 725 } catch (Exception e) { 726 lastError = e.toString(); 727 return false; 728 } 729 this.dirtyHash.remove(id); 730 this.generateOldCache(); 731 return true; 732 } 733 734 742 public synchronized ArrayList removeByPartialUrl(String partialUrl) { 743 744 ArrayList list = new ArrayList(); 745 746 for (Iterator i = cacheHash.keySet().iterator(); i.hasNext();) { 747 String url = (String ) i.next(); 748 if (url.indexOf(partialUrl) > -1) { 749 this.removeFromCache(url); 750 list.add(url); 751 } 752 } 753 return list; 754 } 755 756 764 public synchronized ArrayList expireByPartialUrl(String partialUrl) { 765 766 ArrayList list = new ArrayList(); 767 768 for (Iterator i = cacheHash.keySet().iterator(); i.hasNext();) { 769 String url = (String ) i.next(); 770 if (url.indexOf(partialUrl) > -1) { 771 this.expireInCache(url); 772 list.add(url); 773 } 774 } 775 return list; 776 } 777 778 787 public synchronized CofaxPage getPage(String id) { 788 Object _o = cacheHash.get(id); 790 CofaxPage _p = null; 791 792 if (_o instanceof CofaxPage) 793 _p = (CofaxPage) _o; 794 795 if (_p != null) { 796 cacheHits++; 797 return _p; 798 } else { 799 _o = dirtyHash.get(id); 800 if (_o instanceof CofaxPage) 801 _p = (CofaxPage) _o; 802 if (_p != null) { 803 dirtyHits++; 804 return _p; 805 } else { 806 return null; } 809 } 810 811 } 812 813 820 private synchronized boolean dumpLowestCachedURL() { 821 822 String uHold = curLowCacheURL; 823 Integer cHold = new Integer (curLowCache); 824 this.removeFromCache(curLowCacheURL); 825 if (curTrackCount < maxURLsToCount) { 826 this.addPageToCache(uHold, cHold); 828 } 829 this.generateOldCache(); 830 return true; 831 } 832 833 840 private synchronized boolean dumpOldestCachedURL() { 841 842 CofaxPage lPage = new CofaxPage(); 843 String uHold = curOldCacheURL; 844 Integer cHold; 845 846 if (this.cacheHash.containsKey(uHold)) { 847 lPage = (CofaxPage) this.cacheHash.get(uHold); 848 cHold = new Integer (lPage.getHitCount()); 849 } else { 850 cHold = new Integer (1); 851 } 852 this.removeFromCache(curOldCacheURL); 853 if (curTrackCount < maxURLsToCount) { 854 this.addPageToCache(uHold, cHold); 856 } 857 return true; 858 } 859 860 869 public synchronized boolean shouldPageBeCached(String id) { 870 871 try { 872 CofaxPage testPage = new CofaxPage(); 873 if (cacheHash.containsKey(id)) { 874 if (cacheHash.get(id) instanceof CofaxPage) { 876 testPage = (CofaxPage) cacheHash.get(id); 878 if (testPage.isPageCached()) { 879 return false; 880 } 881 } else if (cacheHash.get(id) instanceof Integer ) { 882 Integer x = new Integer (0); 884 x = (Integer ) cacheHash.get(id); 885 if (curCacheCount < maxURLsToStore) { 886 return true; 888 } else if (x.intValue() > curLowCache) { 889 this.dumpLowestCachedURL(); 891 return true; 892 } else if (this.curOldCache > this.cacheTimeToDie) { 893 this.dumpOldestCachedURL(); 895 return true; 896 } 897 } 898 } else { 899 if (curCacheCount < maxURLsToStore) { 901 return true; 903 } else if (this.curOldCache > this.cacheTimeToDie) { 904 this.dumpOldestCachedURL(); 906 return true; 907 } else { 908 if (curTrackCount < maxURLsToCount) { 910 this.addPageToCache(id, new Integer (1)); 912 } else { 913 this.dumpLowestTrackedHitCount(); 915 this.addPageToCache(id, new Integer (1)); 916 } 917 return false; 918 } 919 } 920 } catch (Exception e) { 921 lastError = e.toString(); 922 return false; 923 } 924 return false; 925 } 926 927 933 public int getTrackedTotal() { 934 935 Iterator URLs = cacheHash.keySet().iterator(); 936 String url; 937 Integer x; 938 Integer y; 939 int totalCount = 0; 940 CofaxPage loopPage = new CofaxPage(); 941 942 while (URLs.hasNext()) { 943 url = (String ) URLs.next(); 944 if (cacheHash.get(url) instanceof Integer ) { 945 x = (Integer ) cacheHash.get(url); 946 } else { 947 loopPage = (CofaxPage) cacheHash.get(url); 948 y = new Integer (loopPage.getHitCount()); 949 x = y; 950 } 951 totalCount += x.intValue(); 952 } 953 return totalCount; 954 } 955 956 962 private synchronized boolean generateLowTrackCount() { 963 964 Iterator URLs = cacheHash.keySet().iterator(); 965 String url; 966 String lUrl = ""; 967 Integer x; 968 int lCount = -1; 969 boolean gotLow = false; 970 971 if (curTrackCount == 0) { 972 return false; 973 } 974 975 while (URLs.hasNext()) { 976 url = (String ) URLs.next(); 977 if (cacheHash.get(url) instanceof Integer ) { 978 x = (Integer ) cacheHash.get(url); 979 if (x.intValue() < lCount || lCount == -1) { 980 lCount = x.intValue(); 981 lUrl = url; 982 gotLow = true; 983 } 984 } 985 } 986 if (gotLow) { 987 curLowTrack = lCount; 988 curLowTrackURL = lUrl; 989 return true; 990 } else { 991 return false; 992 } 993 994 } 995 996 1002 private synchronized boolean generateLowCacheCount() { 1003 1004 Iterator URLs = cacheHash.keySet().iterator(); 1005 String url; 1006 String lUrl = ""; 1007 Integer x; 1008 int lCount = -1; 1009 boolean gotLow = false; 1010 CofaxPage lPage = new CofaxPage(); 1011 1012 if (curCacheCount == 0) { 1013 return false; 1014 } 1015 1016 while (URLs.hasNext()) { 1017 url = (String ) URLs.next(); 1018 if (cacheHash.get(url) instanceof CofaxPage) { 1019 lPage = (CofaxPage) cacheHash.get(url); 1020 if (lPage.getHitCount() < lCount || lCount == -1) { 1021 lCount = lPage.getHitCount(); 1022 lUrl = url; 1023 gotLow = true; 1024 } 1025 } 1026 } 1027 if (gotLow) { 1028 this.curLowCache = lCount; 1029 this.curLowCacheURL = lUrl; 1030 return true; 1031 } else { 1032 return false; 1033 } 1034 1035 } 1036 1037 1043 private synchronized boolean generateOldCache() { 1044 1045 Iterator URLs = cacheHash.keySet().iterator(); 1046 String url = ""; 1047 String lUrl = ""; 1048 long lCount = -1; 1049 boolean gotOld = false; 1050 CofaxPage lPage = new CofaxPage(); 1051 1052 if (curCacheCount == 0) { 1053 return false; 1054 } 1055 1056 Date currDate = new Date(); 1057 long currSecs = currDate.getTime(); 1058 long cacheAge = 0; 1059 long cachedTime = 0; 1060 1061 while (URLs.hasNext()) { 1062 url = (String ) URLs.next(); 1063 if (cacheHash.get(url) instanceof CofaxPage) { 1064 lPage = (CofaxPage) cacheHash.get(url); 1065 cachedTime = lPage.getLastModified(); 1066 cacheAge = currSecs - cachedTime; 1067 if (cacheAge > lCount || lCount == -1) { 1068 lCount = cacheAge; 1069 lUrl = url; 1070 gotOld = true; 1071 } 1072 } 1073 } 1074 if (gotOld) { 1075 this.curOldCache = lCount; 1076 this.curOldCacheURL = lUrl; 1077 return true; 1078 } else { 1079 return false; 1080 } 1081 1082 } 1083 1084 1087 public String toString() { 1088 return "Instance Of: " + getClass().getName() + "\n" + "maxURLsToCount: " + maxURLsToCount + "\n" + "maxUrlsToStore: " + maxURLsToStore + "\n" 1089 + "timeToRefresh: " + timeToRefresh + "\n" + "cacheTimeToDie: " + cacheTimeToDie + "\n" + "dirtyReadTime: " + dirtyReadTime; 1090 } 1091 1092 public synchronized boolean CleanIfPossible() { 1097 if (isCleaning) { 1099 return false; } 1102 1103 isCleaning = true; 1104 1106 try { 1107 HashMap _pages = getCacheHash(); 1108 Iterator objects = _pages.keySet().iterator(); 1109 1110 long curTime = System.currentTimeMillis(); 1111 1114 1116 while (objects.hasNext()) { 1117 String id = (String ) objects.next(); 1118 if (_pages.get(id) instanceof CofaxPage) { 1119 CofaxPage _p = (CofaxPage) _pages.get(id); 1121 if (_p != null && _p.getContentsLength() > 0 && (curTime - _p.getLastModified()) > timeToRefresh) { 1122 _p.reset(); 1124 org.cofax.cds.CDSServlet.cofaxLog("Cleaning this page : " + _p.getPageId()); 1125 } 1126 } 1127 } 1128 } catch (Exception ex) { 1129 org.cofax.cds.CDSServlet.cofaxLog("Error while cleaning : " + ex); 1130 } 1131 1132 isCleaning = false; return true; 1135 } 1136 1137} 1138 | Popular Tags |