|
From: <sa...@us...> - 2004-03-11 14:21:08
|
Update of /cvsroot/jrobin/src/org/jrobin/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27547/org/jrobin/core Modified Files: RrdDb.java RrdDbPool.java Log Message: RrdDbPool final tweaks Index: RrdDb.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdDb.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** RrdDb.java 2 Mar 2004 09:47:49 -0000 1.12 --- RrdDb.java 11 Mar 2004 13:54:25 -0000 1.13 *************** *** 69,72 **** --- 69,73 ---- static final int XML_INITIAL_BUFFER_CAPACITY = 100000; // bytes + private String canonicalPath; private RrdFile file; private Header header; *************** *** 224,227 **** --- 225,229 ---- } file.setMode(RrdFile.MODE_NORMAL); + canonicalPath = file.getCanonicalFilePath(); } *************** *** 762,764 **** } } ! } --- 764,774 ---- } } ! ! /** ! * Returns canonical path to the underlying RRD file. ! * @return Canonical path to RRD file; ! */ ! public String getCanonicalPath() { ! return canonicalPath; ! } ! } Index: RrdDbPool.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/RrdDbPool.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RrdDbPool.java 2 Mar 2004 09:47:49 -0000 1.5 --- RrdDbPool.java 11 Mar 2004 13:54:25 -0000 1.6 *************** *** 101,121 **** private static final boolean DEBUG = false; - private static final Comparator ENTRY_COMPARATOR = new Comparator() { - public int compare(Object o1, Object o2) { - RrdEntry r1 = (RrdEntry) o1, r2 = (RrdEntry) o2; - if (!r1.isReleased() && !r2.isReleased()) { - return 0; - } else if (r1.isReleased() && !r2.isReleased()) { - return -1; - } else if (!r1.isReleased() && r2.isReleased()) { - return +1; - } else { - // both released - long diff = r1.getReleaseDate().getTime() - - r2.getReleaseDate().getTime(); - return diff < 0L ? -1 : (diff == 0L ? 0 : +1); - } - } - }; /** * Constant to represent the maximum number of internally open RRD files --- 101,104 ---- *************** *** 123,129 **** */ public static final int INITIAL_CAPACITY = 50; ! private volatile int capacity = INITIAL_CAPACITY; ! private HashMap rrdMap = new HashMap(); /** --- 106,113 ---- */ public static final int INITIAL_CAPACITY = 50; ! private int capacity = INITIAL_CAPACITY; ! private Map rrdMap = new HashMap(); ! private List rrdGcList = new LinkedList(); /** *************** *** 163,167 **** // already open RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! rrdEntry.reportUsage(); debug("EXISTING: " + rrdEntry.dump()); return rrdEntry.getRrdDb(); --- 147,151 ---- // already open RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! reportUsage(rrdEntry); debug("EXISTING: " + rrdEntry.dump()); return rrdEntry.getRrdDb(); *************** *** 169,173 **** // not found, open it RrdDb rrdDb = new RrdDb(path); ! put(keypath, rrdDb); return rrdDb; } --- 153,157 ---- // not found, open it RrdDb rrdDb = new RrdDb(path); ! addRrdEntry(keypath, rrdDb); return rrdDb; } *************** *** 187,193 **** throws IOException, RrdException { String keypath = getCanonicalPath(path); ! validateInactive(keypath); RrdDb rrdDb = new RrdDb(path, xmlPath); ! put(keypath, rrdDb); return rrdDb; } --- 171,177 ---- throws IOException, RrdException { String keypath = getCanonicalPath(path); ! prooveInactive(keypath); RrdDb rrdDb = new RrdDb(path, xmlPath); ! addRrdEntry(keypath, rrdDb); return rrdDb; } *************** *** 204,215 **** String path = rrdDef.getPath(); String keypath = getCanonicalPath(path); ! validateInactive(keypath); RrdDb rrdDb = new RrdDb(rrdDef); ! put(keypath, rrdDb); return rrdDb; } ! private synchronized void put(String keypath, RrdDb rrdDb) throws IOException { RrdEntry newEntry = new RrdEntry(rrdDb); debug("NEW: " + newEntry.dump()); rrdMap.put(keypath, newEntry); --- 188,214 ---- String path = rrdDef.getPath(); String keypath = getCanonicalPath(path); ! prooveInactive(keypath); RrdDb rrdDb = new RrdDb(rrdDef); ! addRrdEntry(keypath, rrdDb); return rrdDb; } ! private void reportUsage(RrdEntry rrdEntry) { ! if(rrdEntry.reportUsage() == 1) { ! // must not be garbage collected ! rrdGcList.remove(rrdEntry); ! } ! } ! ! private void reportRelease(RrdEntry rrdEntry) { ! if(rrdEntry.reportRelease() == 0) { ! // ready to be garbage collected ! rrdGcList.add(rrdEntry); ! } ! } ! ! private void addRrdEntry(String keypath, RrdDb rrdDb) throws IOException { RrdEntry newEntry = new RrdEntry(rrdDb); + reportUsage(newEntry); debug("NEW: " + newEntry.dump()); rrdMap.put(keypath, newEntry); *************** *** 218,226 **** } ! private void validateInactive(String keypath) throws RrdException, IOException { if(rrdMap.containsKey(keypath)) { // already open, check if active (not released) RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! if(!rrdEntry.isReleased()) { // not released, not allowed here throw new RrdException("VALIDATOR: Cannot create new RrdDb file. " + --- 217,225 ---- } ! private void prooveInactive(String keypath) throws RrdException, IOException { if(rrdMap.containsKey(keypath)) { // already open, check if active (not released) RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! if(rrdEntry.isInUse()) { // not released, not allowed here throw new RrdException("VALIDATOR: Cannot create new RrdDb file. " + *************** *** 230,239 **** // open but released... safe to close it debug("WILL BE RECREATED: " + rrdEntry.dump()); ! rrdEntry.close(); ! rrdMap.values().remove(rrdEntry); } } } /** * Method used to report that the reference to a RRD file is no longer needed. File that --- 229,244 ---- // open but released... safe to close it debug("WILL BE RECREATED: " + rrdEntry.dump()); ! removeRrdEntry(rrdEntry); } } } + private void removeRrdEntry(RrdEntry rrdEntry) throws IOException { + rrdEntry.closeRrdDb(); + rrdMap.values().remove(rrdEntry); + rrdGcList.remove(rrdEntry); + debug("REMOVED: " + rrdEntry.dump()); + } + /** * Method used to report that the reference to a RRD file is no longer needed. File that *************** *** 258,262 **** if(rrdMap.containsKey(keypath)) { RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! rrdEntry.release(); debug("RELEASED: " + rrdEntry.dump()); } --- 263,267 ---- if(rrdMap.containsKey(keypath)) { RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath); ! reportRelease(rrdEntry); debug("RELEASED: " + rrdEntry.dump()); } *************** *** 278,307 **** debug("GC: started"); synchronized (this) { ! for (;;) { ! while (rrdMap.size() > capacity) { ! debug("GC: should run: (" + rrdMap.size() + " > " + capacity + ")"); ! RrdEntry oldestEntry = (RrdEntry) ! Collections.min(rrdMap.values(), ENTRY_COMPARATOR); ! if (oldestEntry.isReleased()) { ! try { ! debug("GC: closing " + oldestEntry.dump()); ! oldestEntry.close(); ! } catch (IOException e) { ! debug("GC error: " + e); ! e.printStackTrace(); ! } ! rrdMap.values().remove(oldestEntry); ! } else { ! // all references are used ! debug("GC: NOP: all references are active (" + rrdMap.size() + ")"); ! break; } } try { ! // nothing to do ! debug("GC: sleeping (" + rrdMap.size() + ")"); wait(); debug("GC: running"); ! } catch (InterruptedException e) { } } } --- 283,303 ---- debug("GC: started"); synchronized (this) { ! for (; ;) { ! while (rrdMap.size() > capacity && rrdGcList.size() > 0) { ! try { ! RrdEntry oldestRrdEntry = (RrdEntry) rrdGcList.get(0); ! debug("GC: closing " + oldestRrdEntry.dump()); ! removeRrdEntry(oldestRrdEntry); ! } catch (IOException e) { ! e.printStackTrace(); } } + try { ! debug("GC: sleeping (" + rrdMap.size() + "/" + rrdGcList.size() + ")"); wait(); debug("GC: running"); ! } catch (InterruptedException e) { ! } } } *************** *** 314,318 **** /** * Clears the internal state of the pool entirely. All open RRD files are closed. - * Use with extreme caution. * @throws IOException Thrown in case of I/O related error. */ --- 310,313 ---- *************** *** 321,335 **** while(it.hasNext()) { RrdEntry rrdEntry = (RrdEntry) it.next(); ! rrdEntry.close(); } rrdMap.clear(); debug("Nothing left in the pool"); } ! static String getCanonicalPath(String path) throws IOException { return new File(path).getCanonicalPath(); } ! static void debug(String msg) { if(DEBUG) { System.out.println("POOL: " + msg); --- 316,331 ---- while(it.hasNext()) { RrdEntry rrdEntry = (RrdEntry) it.next(); ! rrdEntry.closeRrdDb(); } rrdMap.clear(); + rrdGcList.clear(); debug("Nothing left in the pool"); } ! private static String getCanonicalPath(String path) throws IOException { return new File(path).getCanonicalPath(); } ! private static void debug(String msg) { if(DEBUG) { System.out.println("POOL: " + msg); *************** *** 360,364 **** * @return Desired nuber of open files held in the pool. */ ! public int getCapacity() { return capacity; } --- 356,360 ---- * @return Desired nuber of open files held in the pool. */ ! public synchronized int getCapacity() { return capacity; } *************** *** 370,374 **** * @param capacity Desired number of open files to hold in the pool */ ! public void setCapacity(int capacity) { this.capacity = capacity; } --- 366,370 ---- * @param capacity Desired number of open files to hold in the pool */ ! public synchronized void setCapacity(int capacity) { this.capacity = capacity; } *************** *** 376,385 **** private class RrdEntry { private RrdDb rrdDb; - private Date releaseDate; private int usageCount; public RrdEntry(RrdDb rrdDb) { this.rrdDb = rrdDb; - reportUsage(); } --- 372,379 ---- *************** *** 388,423 **** } ! void reportUsage() { ! releaseDate = null; ! usageCount++; ! } ! ! void release() { ! if(usageCount > 0) { ! usageCount--; ! if(usageCount == 0) { ! releaseDate = new Date(); ! } ! } ! } ! ! boolean isReleased() { ! return usageCount == 0; } ! int getUsageCount() { ! return usageCount; } ! Date getReleaseDate() { ! return releaseDate; } ! void close() throws IOException { rrdDb.close(); } String dump() throws IOException { ! String keypath = getCanonicalPath(rrdDb.getRrdFile().getFilePath()); return keypath + " [" + usageCount + "]"; } --- 382,405 ---- } ! int reportUsage() { ! assert usageCount >= 0: "Unexpected reportUsage count: " + usageCount; ! return ++usageCount; } ! int reportRelease() { ! assert usageCount > 0: "Unexpected reportRelease count: " + usageCount; ! return --usageCount; } ! boolean isInUse() { ! return usageCount > 0; } ! void closeRrdDb() throws IOException { rrdDb.close(); } String dump() throws IOException { ! String keypath = getCanonicalPath(rrdDb.getCanonicalPath()); return keypath + " [" + usageCount + "]"; } |