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

📄 rrddb.java

📁 httptunnel.jar httptunnel java 源码
💻 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, by Sasa Markovic.
 *
 * Developers:    Sasa Markovic (saxon@jrobin.org)
 *                Arne Vandamme (cobralord@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 net.jumperz.ext.org.jrobin.core;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * <p>Main class used to create and manipulate round robin databases (RRDs). Use this class to perform
 * update and fetch operations on exisiting RRDs, to create new RRD from
 * the definition (object of class {@link net.jumperz.ext.org.jrobin.core.RrdDef RrdDef}) or
 * from XML file (dumped content of RRDTool's or JRobin's RRD file).</p>
 *
 * <p>Each RRD is backed with some kind of storage. For example, RRDTool supports only one kind of
 * storage (disk file). On the contrary, JRobin gives you freedom to use other storage (backend) types
 * even to create your own backend types for some special purposes. JRobin by default stores
 * RRD data in files (as RRDTool), but you might choose to store RRD data in memory (this is
 * supported in JRobin), to use java.nio.* instead of java.io.* package for file manipulation
 * (also supported) or to store whole RRDs in the SQL database
 * (you'll have to extend some classes to do this).</p>
 *
 * <p>Note that JRobin uses binary format different from RRDTool's format. You cannot
 * use this class to manipulate RRD files created with RRDTool. <b>However, if you perform
 * the same sequence of create, update and fetch operations, you will get exactly the same
 * results from JRobin and RRDTool.</b><p>
 *
 * <p>
 * You will not be able to use JRobin API if you are not familiar with
 * basic RRDTool concepts. Good place to start is the
 * <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/tutorial/rrdtutorial.html">official RRD tutorial</a>
 * and relevant RRDTool man pages: <a href="../../../../man/rrdcreate.html" target="man">rrdcreate</a>,
 * <a href="../../../../man/rrdupdate.html" target="man">rrdupdate</a>,
 * <a href="../../../../man/rrdfetch.html" target="man">rrdfetch</a> and
 * <a href="../../../../man/rrdgraph.html" target="man">rrdgraph</a>.
 * For RRDTool's advanced graphing capabilities (RPN extensions), also supported in JRobin,
 * there is an excellent
 * <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/tutorial/cdeftutorial.html" target="man">CDEF tutorial</a>.
 * </p>
 *
 * @see RrdBackend
 * @see RrdBackendFactory
 */
public class RrdDb implements RrdUpdater {
	/** See {@link #getLockMode() getLockMode()} for explanation */
	public static final int NO_LOCKS = 0;
	/** See {@link #getLockMode() getLockMode()} for explanation */
	public static final int WAIT_IF_LOCKED = 1;
	/** See {@link #getLockMode() getLockMode()} for explanation */
	public static final int EXCEPTION_IF_LOCKED = 2;

    // static final String RRDTOOL = "rrdtool";
	static final int XML_INITIAL_BUFFER_CAPACITY = 100000; // bytes
	private static int lockMode = NO_LOCKS;

	private RrdBackend backend;
	private RrdAllocator allocator = new RrdAllocator();

	private Header header;
	private Datasource[] datasources;
	private Archive[] archives;

	private boolean closed = false;

	/**
	 * <p>Constructor used to create new RRD object from the definition. This RRD object will be backed
	 * with a storage (backend) of the default type. Initially, storage type defaults to "NIO"
	 * (RRD bytes will be put in a file on the disk). Default storage type can be changed with a static
	 * {@link RrdBackendFactory#setDefaultFactory(String)} method call.</p>
	 *
	 * <p>New RRD file structure is specified with an object of class
	 * {@link org.jrobin.core.RrdDef <b>RrdDef</b>}. The underlying RRD storage is created as soon
	 * as the constructor returns.</p>
	 *
	 * <p>Typical scenario:</p>
	 *
	 * <pre>
	 * // create new RRD definition
     * RrdDef def = new RrdDef("test.rrd", 300);
     * def.addDatasource("input", "COUNTER", 600, 0, Double.NaN);
     * def.addDatasource("output", "COUNTER", 600, 0, Double.NaN);
     * def.addArchive("AVERAGE", 0.5, 1, 600);
     * def.addArchive("AVERAGE", 0.5, 6, 700);
     * def.addArchive("AVERAGE", 0.5, 24, 797);
     * def.addArchive("AVERAGE", 0.5, 288, 775);
     * def.addArchive("MAX", 0.5, 1, 600);
     * def.addArchive("MAX", 0.5, 6, 700);
     * def.addArchive("MAX", 0.5, 24, 797);
     * def.addArchive("MAX", 0.5, 288, 775);
     *
     * // RRD definition is now completed, create the database!
     * RrdDb rrd = new RrdDb(def);
	 * // new RRD file has been created on your disk
	 * </pre>
	 *
	 * @param rrdDef Object describing the structure of the new RRD file.
	 * @throws IOException Thrown in case of I/O error.
	 * @throws RrdException Thrown if invalid RrdDef object is supplied.
	 */
	public RrdDb(RrdDef rrdDef) throws RrdException, IOException {
		this(rrdDef, RrdFileBackendFactory.getDefaultFactory());
	}

	/**
	 * <p>Constructor used to create new RRD object from the definition object but with a storage
	 * (backend) different from default.</p>
	 *
	 * <p>JRobin uses <i>factories</i> to create RRD backend objecs. There are three different
	 * backend factories supplied with JRobin, and each factory has its unique name:</p>
	 *
	 * <ul>
	 * <li><b>FILE</b>: backends created from this factory will store RRD data to files by using
	 * java.io.* classes and methods
	 * <li><b>NIO</b>: backends created from this factory will store RRD data to files by using
	 * java.nio.* classes and methods
	 * <li><b>MEMORY</b>: backends created from this factory will store RRD data in memory. This might
	 * be useful in runtime environments which prohibit disk utilization, or for storing temporary,
	 * non-critical data (it gets lost as soon as JVM exits).
	 * </ul>
	 *
	 * <p>For example, to create RRD in memory, use the following code</p>
	 * <pre>
	 * RrdBackendFactory factory = RrdBackendFactory.getFactory("MEMORY");
	 * RrdDb rrdDb = new RrdDb(rrdDef, factory);
	 * rrdDb.close();
	 * </pre>
	 *
	 * <p>New RRD file structure is specified with an object of class
	 * {@link org.jrobin.core.RrdDef <b>RrdDef</b>}. The underlying RRD storage is created as soon
	 * as the constructor returns.</p>
	 * @param rrdDef RRD definition object
	 * @param factory The factory which will be used to create storage for this RRD
	 * @throws RrdException Thrown if invalid factory or definition is supplied
	 * @throws IOException Thrown in case of I/O error
	 * @see RrdBackendFactory
	 */
	public RrdDb(RrdDef rrdDef, RrdBackendFactory factory) throws RrdException, IOException {
		rrdDef.validate();
		String path = rrdDef.getPath();
		backend = factory.open(path, false, lockMode);
		backend.setLength(rrdDef.getEstimatedSize());
		// create header
		header = new Header(this, rrdDef);
		// create datasources
        DsDef[] dsDefs = rrdDef.getDsDefs();
		datasources = new Datasource[dsDefs.length];
		for(int i = 0; i < dsDefs.length; i++) {
			datasources[i] = new Datasource(this, dsDefs[i]);
		}
		// create archives
		ArcDef[] arcDefs = rrdDef.getArcDefs();
		archives = new Archive[arcDefs.length];
		for(int i = 0; i < arcDefs.length; i++) {
			archives[i] = new Archive(this, arcDefs[i]);
		}
		backend.afterCreate();
	}

	/**
	 * <p>Constructor used to open already existing RRD. This RRD object will be backed
	 * with a storage (backend) of the default type (file on the disk). Constructor
	 * obtains read or read/write access to this RRD.</p>
	 *
	 * @param path Path to existing RRD.
	 * @param readOnly Should be set to <code>false</code> if you want to update
	 * the underlying RRD. If you want just to fetch data from the RRD file
	 * (read-only access), specify <code>true</code>. If you try to update RRD file
	 * open in read-only mode (<code>readOnly</code> set to <code>true</code>),
	 * <code>IOException</code> will be thrown.
	 * @throws IOException Thrown in case of I/O error.
	 * @throws RrdException Thrown in case of JRobin specific error.
	 */
	public RrdDb(String path, boolean readOnly)	throws IOException, RrdException {
		this(path, readOnly, RrdBackendFactory.getDefaultFactory());
	}

	/**
	 * <p>Constructor used to open already existing RRD backed
	 * with a storage (backend) different from default. Constructor
	 * obtains read or read/write access to this RRD.</p>
	 *
	 * @param path Path to existing RRD.
	 * @param readOnly Should be set to <code>false</code> if you want to update
	 * the underlying RRD. If you want just to fetch data from the RRD file
	 * (read-only access), specify <code>true</code>. If you try to update RRD file
	 * open in read-only mode (<code>readOnly</code> set to <code>true</code>),
	 * <code>IOException</code> will be thrown.
	 * @param factory Backend factory which will be used for this RRD.
	 * @throws IOException Thrown in case of I/O error.
	 * @throws RrdException Thrown in case of JRobin specific error.
	 * @see RrdBackendFactory
	 */
	public RrdDb(String path, boolean readOnly, RrdBackendFactory factory)
			throws IOException, RrdException {
		// opens existing RRD file - throw exception if the file does not exist...
		if(!factory.exists(path)) {
			throw new IOException("Could not open " + path + " [non existent]");
		}
		backend = factory.open(path, readOnly, lockMode);
		// restore header
		header = new Header(this, (RrdDef) null);
		header.validateHeader();
		// restore datasources
		int dsCount = header.getDsCount();
		datasources = new Datasource[dsCount];
		for(int i = 0; i < dsCount; i++) {
			datasources[i] = new Datasource(this, null);
		}
		// restore archives
		int arcCount = header.getArcCount();
		archives = new Archive[arcCount];
		for(int i = 0; i < arcCount; i++) {
			archives[i] = new Archive(this, null);
		}
	}

	/**
	 * <p>Constructor used to open already existing RRD in R/W mode, with a default storage
	 * (backend) type (file on the disk).
	 *
	 * @param path Path to existing RRD.
	 * @throws IOException Thrown in case of I/O error.
	 * @throws RrdException Thrown in case of JRobin specific error.
	 */
	public RrdDb(String path) throws IOException, RrdException {
		this(path, false);
	}

	/**
	 * <p>Constructor used to open already existing RRD in R/W mode with a storage (backend) type
	 * different from default.</p>
	 *
	 * @param path Path to existing RRD.
	 * @param factory Backend factory used to create this RRD.
	 * @throws IOException Thrown in case of I/O error.
	 * @throws RrdException Thrown in case of JRobin specific error.
 	 * @see RrdBackendFactory
	 */
	public RrdDb(String path, RrdBackendFactory factory) throws IOException, RrdException {
		this(path, false, factory);
	}

	/**
	 * <p>Constructor used to create new RRD from XML dump. Newly created RRD will be backed
	 * with a default storage (backend) type (file on the disk). JRobin and RRDTool
	 * use the same format for XML dump and this constructor should be used to
	 * (re)create JRobin RRD from XML. In other words, it is possible to convert
	 * RRDTool RRD files to JRobin RRD files: first, dump the content of RRDTool
	 * RRD file (use command line):</p>
	 *
	 * <code>rrdtool dump original.rrd > original.xml</code>
	 *
	 * <p>Than, use file <code>original.xml</code> to create JRobin RRD file
	 * <code>copy.rrd</code>:</p>
	 *
	 * <code>RrdDb rrd = new RrdDb("copy.rrd", "original.xml");</code>
	 *
	 * <p>See documentation for {@link #dumpXml(java.lang.String) dumpXml()} method
	 * how to convert JRobin files to RRDTool format.</p>
	 *
	 * @param rrdPath Path to RRD file which will be created
	 * @param xmlPath Path to file containing XML dump of RRDTool's or JRobin's RRD file
	 * @throws IOException Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 */
	public RrdDb(String rrdPath, String xmlPath) throws IOException, RrdException {
		this(rrdPath, xmlPath, RrdBackendFactory.getDefaultFactory());
	}

    /**
	 * <p>Constructor used to create new RRD from XML dump but with a storage (backend) type
	 * different from default.</p>
	 *
	 * @param rrdPath Path to RRD which will be created
	 * @param xmlPath Path to file containing XML dump of RRDTool's or JRobin's RRD file
	 * @param factory Backend factory which will be used to create storage (backend) for this RRD.
	 * @throws IOException Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 * @see RrdBackendFactory
	 */
	public RrdDb(String rrdPath, String xmlPath, RrdBackendFactory factory)
			throws IOException, RrdException {
		backend = factory.open(rrdPath, false, lockMode);
		DataImporter reader;
		if(xmlPath.startsWith("rrdtool:/")) {
			String rrdToolPath = xmlPath.substring("rrdtool:/".length());
			reader = new RrdToolReader(rrdToolPath);
		}
		else if(xmlPath.startsWith("xml:/")) {
			xmlPath = xmlPath.substring("xml:/".length());
			reader = new XmlReader(xmlPath);
		}
		else {
			reader = new XmlReader(xmlPath);
		}
		backend.setLength(reader.getEstimatedSize());
		// create header
		header = new Header(this, reader);
		// create datasources
		datasources = new Datasource[reader.getDsCount()];
		for(int i = 0; i < datasources.length; i++) {
			datasources[i] = new Datasource(this, reader, i);
		}
		// create archives
		archives = new Archive[reader.getArcCount()];
		for(int i = 0; i < archives.length; i++) {
			archives[i] = new Archive(this, reader, i);
		}
		reader.release();
		// XMLReader is a rather huge DOM tree, release memory ASAP
		reader = null;
		backend.afterCreate();
	}

	/**
	 * Closes RRD. No further operations are allowed on this RrdDb object.

⌨️ 快捷键说明

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