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

📄 rrddbpool.java

📁 jrobin,使用纯java实现的RRD数据库,使用RRD数据库来统计数据.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* ============================================================
 * JRobin : Pure java implementation of RRDTool's functionality
 * ============================================================
 *
 * Project Info:  http://www.jrobin.org
 * Project Lead:  Sasa Markovic (saxon@jrobin.org);
 *
 * (C) Copyright 2003-2005, by Sasa Markovic.
 *
 * Developers:    Sasa Markovic (saxon@jrobin.org)
 *
 *
 * This library is free software; you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software Foundation;
 * either version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this
 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package org.jrobin.core;

import java.io.IOException;
import java.util.HashMap;

/**
 * This class should be used to synchronize access to RRD files
 * in a multithreaded environment. This class should be also used to prevent openning of
 * too many RRD files at the same time (thus avoiding operating system limits)
 */

public class RrdDbPool {
	/**
	 * Initial capacity of the pool i.e. maximum number of simultaneously open RRD files. The pool will
	 * never open too many RRD files at the same time.
	 */
	public static final int INITIAL_CAPACITY = 200;
	private static RrdDbPool instance;

	private int capacity = INITIAL_CAPACITY;
	private HashMap<String, RrdEntry> rrdMap = new HashMap<String, RrdEntry>(INITIAL_CAPACITY);

	/**
	 * Creates a single instance of the class on the first call, or returns already existing one.
	 *
	 * @return Single instance of this class
	 * @throws RrdException Thrown if the default RRD backend is not derived from the {@link RrdFileBackendFactory}
	 */
	public synchronized static RrdDbPool getInstance() throws RrdException {
		if (instance == null) {
			instance = new RrdDbPool();
		}
		return instance;
	}

	private RrdDbPool() throws RrdException {
		RrdBackendFactory factory = RrdBackendFactory.getDefaultFactory();
		if (!(factory instanceof RrdFileBackendFactory)) {
			throw new RrdException("Cannot create instance of " + getClass().getName() + " with " +
					"a default backend factory not derived from RrdFileBackendFactory");
		}
	}

	/**
	 * Requests a RrdDb reference for the given RRD file path.<p>
	 * <ul>
	 * <li>If the file is already open, previously returned RrdDb reference will be returned. Its usage count
	 * will be incremented by one.
	 * <li>If the file is not already open and the number of already open RRD files is less than
	 * {@link #INITIAL_CAPACITY}, the file will be open and a new RrdDb reference will be returned.
	 * If the file is not already open and the number of already open RRD files is equal to
	 * {@link #INITIAL_CAPACITY}, the method blocks until some RRD file is closed.
	 * </ul>
	 *
	 * @param path Path to existing RRD file
	 * @return reference for the give RRD file
	 * @throws IOException  Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 */
	public synchronized RrdDb requestRrdDb(String path) throws IOException, RrdException {
		String canonicalPath = Util.getCanonicalPath(path);
		while (!rrdMap.containsKey(canonicalPath) && rrdMap.size() >= capacity) {
			try {
				wait();
			}
			catch (InterruptedException e) {
				throw new RrdException(e);
			}
		}
		if (rrdMap.containsKey(canonicalPath)) {
			// already open, just increase usage count
			RrdEntry entry = rrdMap.get(canonicalPath);
			entry.count++;
			return entry.rrdDb;
		}
		else {
			// not open, open it now and add to the map
			RrdDb rrdDb = new RrdDb(canonicalPath);
			rrdMap.put(canonicalPath, new RrdEntry(rrdDb));
			return rrdDb;
		}
	}

	/**
	 * Requests a RrdDb reference for the given RRD file definition object.<p>
	 * <ul>
	 * <li>If the file with the path specified in the RrdDef object is already open,
	 * the method blocks until the file is closed.
	 * <li>If the file is not already open and the number of already open RRD files is less than
	 * {@link #INITIAL_CAPACITY}, a new RRD file will be created and a its RrdDb reference will be returned.
	 * If the file is not already open and the number of already open RRD files is equal to
	 * {@link #INITIAL_CAPACITY}, the method blocks until some RRD file is closed.
	 * </ul>
	 *
	 * @param rrdDef Definition of the RRD file to be created
	 * @return Reference to the newly created RRD file
	 * @throws IOException  Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 */
	public synchronized RrdDb requestRrdDb(RrdDef rrdDef) throws IOException, RrdException {
		String canonicalPath = Util.getCanonicalPath(rrdDef.getPath());
		while (rrdMap.containsKey(canonicalPath) || rrdMap.size() >= capacity) {
			try {
				wait();
			}
			catch (InterruptedException e) {
				throw new RrdException(e);
			}
		}
		RrdDb rrdDb = new RrdDb(rrdDef);
		rrdMap.put(canonicalPath, new RrdEntry(rrdDb));
		return rrdDb;
	}

	/**
	 * Requests a RrdDb reference for the given path. The file will be created from
	 * external data (from XML dump, RRD file or RRDTool's binary RRD file).<p>
	 * <ul>
	 * <li>If the file with the path specified is already open,
	 * the method blocks until the file is closed.
	 * <li>If the file is not already open and the number of already open RRD files is less than
	 * {@link #INITIAL_CAPACITY}, a new RRD file will be created and a its RrdDb reference will be returned.
	 * If the file is not already open and the number of already open RRD files is equal to
	 * {@link #INITIAL_CAPACITY}, the method blocks until some RRD file is closed.
	 * </ul>
	 *
	 * @param path	   Path to RRD file which should be created
	 * @param sourcePath Path to external data which is to be converted to JRobin's native RRD file format
	 * @return Reference to the newly created RRD file
	 * @throws IOException  Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 */
	public synchronized RrdDb requestRrdDb(String path, String sourcePath)
			throws IOException, RrdException {
		String canonicalPath = Util.getCanonicalPath(path);
		while (rrdMap.containsKey(canonicalPath) || rrdMap.size() >= capacity) {
			try {
				wait();
			}
			catch (InterruptedException e) {
				throw new RrdException(e);
			}
		}
		RrdDb rrdDb = new RrdDb(canonicalPath, sourcePath);
		rrdMap.put(canonicalPath, new RrdEntry(rrdDb));
		return rrdDb;
	}

	/**
	 * Releases RrdDb reference previously obtained from the pool. When a reference is released, its usage
	 * count is decremented by one. If usage count drops to zero, the underlying RRD file will be closed.
	 *
	 * @param rrdDb RrdDb reference to be returned to the pool
	 * @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 {
		// null pointer should not kill the thread, just ignore it
		if (rrdDb == null) {
			return;
		}
		String canonicalPath = Util.getCanonicalPath(rrdDb.getPath());
		if (!rrdMap.containsKey(canonicalPath)) {
			throw new RrdException("Could not release [" + canonicalPath + "], the file was never requested");
		}
		RrdEntry entry = rrdMap.get(canonicalPath);
		if (--entry.count <= 0) {
			// no longer used
			rrdMap.remove(canonicalPath);
			notifyAll();
			entry.rrdDb.close();
		}
	}

	/**
	 * Returns the maximum number of simultaneously open RRD files.
	 *
	 * @return maximum number of simultaneously open RRD files
	 */
	public synchronized int getCapacity() {
		return capacity;
	}

	/**
	 * Sets the maximum number of simultaneously open RRD files.
	 *
	 * @param capacity Maximum number of simultaneously open RRD files.
	 */
	public synchronized void setCapacity(int capacity) {
		this.capacity = capacity;
	}

	/**
	 * Returns an array of open file names.
	 *
	 * @return Array with canonical paths to open RRD files held in the pool.
	 */
	public synchronized String[] getOpenFiles() {
		return rrdMap.keySet().toArray(new String[0]);
	}

	/**
	 * Returns the number of open RRD files.
	 *
	 * @return Number of currently open RRD files held in the pool.
	 */
	public synchronized int getOpenFileCount() {
		return rrdMap.size();
	}

	class RrdEntry {
		RrdDb rrdDb;
		int count;

		RrdEntry(RrdDb rrdDb) {
			this.rrdDb = rrdDb;
			this.count = 1;
		}
	}
}

// OLDER VERSION IS HERE

///* ============================================================
// * JRobin : Pure java implementation of RRDTool's functionality
// * ============================================================
// *
// * Project Info:  http://www.jrobin.org
// * Project Lead:  Sasa Markovic (saxon@jrobin.org);
// *
// * (C) Copyright 2003-2005, by Sasa Markovic.
// *
// * Developers:    Sasa Markovic (saxon@jrobin.org)
// *
// *
// * This library is free software; you can redistribute it and/or modify it under the terms
// * of the GNU Lesser General Public License as published by the Free Software Foundation;
// * either version 2.1 of the License, or (at your option) any later version.
// *
// * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// * See the GNU Lesser General Public License for more details.
// *
// * You should have received a copy of the GNU Lesser General Public License along with this
// * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
// * Boston, MA 02111-1307, USA.
// */
//package org.jrobin.core;
//
//import java.io.IOException;
//import java.util.HashMap;
//import java.util.Iterator;
//import java.util.LinkedHashMap;
//import java.util.Set;
//
///**
// * Class to represent the pool of open RRD files.<p>
// *
// * To open already existing RRD file with JRobin, you have to create a
// * {@link org.jrobin.core.RrdDb RrdDb} object by specifying RRD file path
// * as constructor argument. This operation can be time consuming
// * especially with large RRD files with many datasources and
// * several long archives.<p>
// *
// * In a multithreaded environment you might probably need a reference to the
// * same RRD file from two different threads (RRD file updates are performed in
// * one thread but data fetching and graphing is performed in another one). To make
// * the RrdDb construction process more efficient it might be convenient to open all
// * RRD files in a centralized place. That's the purpose of RrdDbPool class.<p>
// *
// * How does it work? The typical usage scenario goes like this:<p>
// *
// * <pre>
// * // obtain instance to RrdDbPool object
// * RrdDbPool pool = RrdDbPool.getInstance();
// *
// * // request a reference to RrdDb object
// * String path = "some_relative_or_absolute_path_to_any_RRD_file";
// * RrdDb rrdDb = RrdDbPool.requestRrdDb(path);
// *
// * // reference obtained, do whatever you want with it...
// * ...
// * ...
// *
// * // once you don't need the reference, release it.
// * // DO NOT CALL rrdDb.close() - files no longer in use are eventually closed by the pool
// * pool.release(rrdDb);
// * </pre>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -