📄 rrddbpool.java
字号:
throw new RrdException("VALIDATOR: Cannot create new RrdDb file. " +
"File " + keypath + " already active in pool");
}
else {
// 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
* is no longer needed (all references to it are released) is marked 'eligible for
* closing'. It will be eventually closed by the pool when the number of open RRD files
* becomes too big. Most recently released files will be closed last.
* @param rrdDb Reference to RRD file that is no longer needed.
* @throws IOException Thrown in case of I/O error.
* @throws RrdException Thrown in case of JRobin specific error.
*/
public synchronized void release(RrdDb rrdDb) throws IOException, RrdException {
if(rrdDb == null) {
// we don't want NullPointerException
return;
}
if(rrdDb.isClosed()) {
throw new RrdException("Cannot release: already closed");
}
String keypath = rrdDb.getCanonicalPath();
if(rrdMap.containsKey(keypath)) {
RrdEntry rrdEntry = (RrdEntry) rrdMap.get(keypath);
reportRelease(rrdEntry);
debug("RELEASED: " + rrdEntry.dump());
}
else {
throw new RrdException("RRD file " + keypath + " not in the pool");
}
// notify garbage collector
notify();
}
/**
* This method runs garbage collector in a separate thread. If the number of
* open RRD files kept in the pool is too big (greater than number
* returned from {@link #getCapacity getCapacity()}), garbage collector will try
* to close and remove RRD files with a reference count equal to zero.
* Never call this method directly.
*/
public void run() {
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: waiting: " +
rrdMap.size() + " open, " +
rrdGcList.size() + " released, " +
"capacity = " + capacity + ", " +
"hits = " + poolHitsCount + ", " +
"requests = " + poolRequestsCount);
wait();
debug("GC: running");
} catch (InterruptedException e) {
}
}
}
}
protected void finalize() throws IOException {
reset();
}
/**
* Clears the internal state of the pool entirely. All open RRD files are closed.
* @throws IOException Thrown in case of I/O related error.
*/
public synchronized void reset() throws IOException {
Iterator it = rrdMap.values().iterator();
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 RrdFileBackend.getCanonicalPath(path);
}
private static void debug(String msg) {
if(DEBUG) {
System.out.println("POOL: " + msg);
}
}
/**
* Returns the internal state of the pool. Useful for debugging purposes.
* @return Internal pool state (list of open RRD files, with the number of usages for
* each one).
* @throws IOException Thrown in case of I/O error.
*/
public synchronized String dump() throws IOException {
StringBuffer buff = new StringBuffer();
Iterator it = rrdMap.values().iterator();
while(it.hasNext()) {
RrdEntry rrdEntry = (RrdEntry) it.next();
buff.append(rrdEntry.dump());
buff.append("\n");
}
return buff.toString();
}
/**
* Returns maximum number of internally open RRD files
* which still does not force garbage collector to run.
*
* @return Desired nuber of open files held in the pool.
*/
public synchronized int getCapacity() {
return capacity;
}
/**
* Sets maximum number of internally open RRD files
* which still does not force garbage collector to run.
*
* @param capacity Desired number of open files to hold in the pool
*/
public synchronized void setCapacity(int capacity) {
this.capacity = capacity;
debug("Capacity set to: " + capacity);
}
private RrdBackendFactory getFactory() throws RrdException {
if(factory == null) {
factory = RrdBackendFactory.getDefaultFactory();
if(!(factory instanceof RrdFileBackendFactory)) {
factory = null;
throw new RrdException(
"RrdDbPool cannot work with factories not derived from RrdFileBackendFactory");
}
}
return factory;
}
private class RrdEntry {
private RrdDb rrdDb;
private int usageCount;
public RrdEntry(RrdDb rrdDb) {
this.rrdDb = rrdDb;
}
RrdDb getRrdDb() {
return rrdDb;
}
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 = rrdDb.getCanonicalPath();
return keypath + " [" + usageCount + "]";
}
}
/**
* Calculates pool's efficency ratio. The ratio is obtained by dividing the number of
* RrdDb requests served from the internal pool of open RRD files
* with the number of total RrdDb requests.
* @return Pool's efficiency ratio as a double between 1 (best) and 0 (worst). If no RrdDb reference
* was ever requested, 1 would be returned.
*/
public synchronized double getPoolEfficency() {
if(poolRequestsCount == 0) {
return 1.0;
}
double ratio = (double) poolHitsCount / (double) poolRequestsCount;
// round to 3 decimal digits
return Math.round(ratio * 1000.0) / 1000.0;
}
/**
* Returns the number of RRD requests served from the internal pool of open RRD files
* @return The number of pool "hits".
*/
public synchronized int getPoolHitsCount() {
return poolHitsCount;
}
/**
* Returns the total number of RRD requests successfully served by this pool.
* @return Total number of RRD requests
*/
public synchronized int getPoolRequestsCount() {
return poolRequestsCount;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -