⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rrddbpool.java

📁 httptunnel.jar httptunnel java 源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				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 + -