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

📄 rrddb.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.*;
import java.util.Date;

/**
 * <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 org.jrobin.core.RrdDef RrdDef}) or
 * from XML file (dumped content of RRDTool's or JRobin's RRD file).</p>
 * <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/>
 * <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/>
 * <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 {
	/**
	 * prefix to identify external XML file source used in various RrdDb constructors
	 */
	public static final String PREFIX_XML = "xml:/";
	/**
	 * prefix to identify external RRDTool file source used in various RrdDb constructors
	 */
	public static final String PREFIX_RRDTool = "rrdtool:/";

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

	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/>
	 * <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/>
	 * <p>Typical scenario:</p>
	 * <p/>
	 * <pre>
	 * // create new RRD definition
	 * RrdDef def = new RrdDef("test.rrd", 300);
	 * def.addDatasource("input", DsTypes.DT_COUNTER, 600, 0, Double.NaN);
	 * def.addDatasource("output", DsTypes.DT_COUNTER, 600, 0, Double.NaN);
	 * def.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 1, 600);
	 * def.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 6, 700);
	 * def.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 24, 797);
	 * def.addArchive(ConsolFuns.CF_AVERAGE, 0.5, 288, 775);
	 * def.addArchive(ConsolFuns.CF_MAX, 0.5, 1, 600);
	 * def.addArchive(ConsolFuns.CF_MAX, 0.5, 6, 700);
	 * def.addArchive(ConsolFuns.CF_MAX, 0.5, 24, 797);
	 * def.addArchive(ConsolFuns.CF_MAX, 0.5, 288, 775);
	 * <p/>
	 * // 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/>
	 * <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>
	 * <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/>
	 * <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/>
	 * <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);
		try {
			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]);
			}
		}
		catch (IOException e) {
			backend.close();
			throw e;
		}
	}

	/**
	 * <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 FileNotFoundException Thrown if the requested file does not exist.
	 * @throws IOException		   Thrown in case of general I/O error (bad RRD file, for example).
	 * @throws RrdException		  Thrown in case of JRobin specific error.
	 * @see RrdBackendFactory
	 */
	public RrdDb(String path, boolean readOnly, RrdBackendFactory factory)
			throws FileNotFoundException, IOException, RrdException {
		// opens existing RRD file - throw exception if the file does not exist...
		if (!factory.exists(path)) {
			throw new FileNotFoundException("Could not open " + path + " [non existent]");
		}
		backend = factory.open(path, readOnly);
		try {
			// 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);
			}
		}
		catch (RrdException e) {
			backend.close();
			throw e;
		}
		catch (IOException e) {
			backend.close();
			throw e;
		}
	}

	/**
	 * <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 RRD files from external file sources.
	 * Supported external file sources are:</p>
	 * <p/>
	 * <ul>
	 * <li>RRDTool/JRobin XML file dumps (i.e files created with <code>rrdtool dump</code> command).
	 * <li>RRDTool binary files.
	 * </ul>
	 * <p/>
	 * <p>Newly created RRD will be backed with a default storage (backend) type
	 * (file on the disk).</p>
	 * <p/>
	 * <p>JRobin and RRDTool use the same format for XML dump and this constructor should be used to
	 * (re)create JRobin RRD files from XML dumps. First, dump the content of a RRDTool
	 * RRD file (use command line):</p>
	 * <p/>
	 * <pre>
	 * rrdtool dump original.rrd > original.xml
	 * </pre>
	 * <p/>
	 * <p>Than, use the file <code>original.xml</code> to create JRobin RRD file named
	 * <code>copy.rrd</code>:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "original.xml");
	 * </pre>
	 * <p/>
	 * <p>or:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "xml:/original.xml");
	 * </pre>
	 * <p/>
	 * <p>See documentation for {@link #dumpXml(java.lang.String) dumpXml()} method
	 * to see how to convert JRobin files to RRDTool's format.</p>
	 * <p/>
	 * <p>To read RRDTool files directly, specify <code>rrdtool:/</code> prefix in the
	 * <code>externalPath</code> argument. For example, to create JRobin compatible file named
	 * <code>copy.rrd</code> from the file <code>original.rrd</code> created with RRDTool, use
	 * the following code:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "rrdtool:/original.rrd");
	 * </pre>
	 * <p/>
	 * <p>Note that the prefix <code>xml:/</code> or <code>rrdtool:/</code> is necessary to distinguish
	 * between XML and RRDTool's binary sources. If no prefix is supplied, XML format is assumed</p>
	 *
	 * @param rrdPath	  Path to a RRD file which will be created
	 * @param externalPath Path to an external file which should be imported, with an optional
	 *                     <code>xml:/</code> or <code>rrdtool:/</code> prefix.
	 * @throws IOException  Thrown in case of I/O error
	 * @throws RrdException Thrown in case of JRobin specific error
	 */
	public RrdDb(String rrdPath, String externalPath) throws IOException, RrdException {
		this(rrdPath, externalPath, RrdBackendFactory.getDefaultFactory());
	}

	/**
	 * <p>Constructor used to create RRD files from external file sources with a backend type
	 * different from default. Supported external file sources are:</p>
	 * <p/>
	 * <ul>
	 * <li>RRDTool/JRobin XML file dumps (i.e files created with <code>rrdtool dump</code> command).
	 * <li>RRDTool binary files.
	 * </ul>
	 * <p/>
	 * <p>JRobin and RRDTool use the same format for XML dump and this constructor should be used to
	 * (re)create JRobin RRD files from XML dumps. First, dump the content of a RRDTool
	 * RRD file (use command line):</p>
	 * <p/>
	 * <pre>
	 * rrdtool dump original.rrd > original.xml
	 * </pre>
	 * <p/>
	 * <p>Than, use the file <code>original.xml</code> to create JRobin RRD file named
	 * <code>copy.rrd</code>:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "original.xml");
	 * </pre>
	 * <p/>
	 * <p>or:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "xml:/original.xml");
	 * </pre>
	 * <p/>
	 * <p>See documentation for {@link #dumpXml(java.lang.String) dumpXml()} method
	 * to see how to convert JRobin files to RRDTool's format.</p>
	 * <p/>
	 * <p>To read RRDTool files directly, specify <code>rrdtool:/</code> prefix in the
	 * <code>externalPath</code> argument. For example, to create JRobin compatible file named
	 * <code>copy.rrd</code> from the file <code>original.rrd</code> created with RRDTool, use
	 * the following code:</p>
	 * <p/>
	 * <pre>
	 * RrdDb rrd = new RrdDb("copy.rrd", "rrdtool:/original.rrd");
	 * </pre>
	 * <p/>
	 * <p>Note that the prefix <code>xml:/</code> or <code>rrdtool:/</code> is necessary to distinguish
	 * between XML and RRDTool's binary sources. If no prefix is supplied, XML format is assumed</p>
	 *

⌨️ 快捷键说明

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