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

📄 rrddb.java

📁 jrobin,使用纯java实现的RRD数据库,使用RRD数据库来统计数据.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * @param rrdPath	  Path to RRD 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.
	 * @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 externalPath, RrdBackendFactory factory)
			throws IOException, RrdException {
		DataImporter reader;
		if (externalPath.startsWith(PREFIX_RRDTool)) {
			String rrdToolPath = externalPath.substring(PREFIX_RRDTool.length());
			reader = new RrdToolReader(rrdToolPath);
		}
		else if (externalPath.startsWith(PREFIX_XML)) {
			externalPath = externalPath.substring(PREFIX_XML.length());
			reader = new XmlReader(externalPath);
		}
		else {
			reader = new XmlReader(externalPath);
		}
		backend = factory.open(rrdPath, false);
		try {
			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();
		}
		catch (RrdException e) {
			backend.close();
			throw e;
		}
		catch (IOException e) {
			backend.close();
			throw e;
		}
	}

	/**
	 * Closes RRD. No further operations are allowed on this RrdDb object.
	 *
	 * @throws IOException Thrown in case of I/O related error.
	 */
	public synchronized void close() throws IOException {
		if (!closed) {
			closed = true;
			backend.close();
		}
	}

	/**
	 * Returns true if the RRD is closed.
	 *
	 * @return true if closed, false otherwise
	 */
	public boolean isClosed() {
		return closed;
	}

	/**
	 * Returns RRD header.
	 *
	 * @return Header object
	 */
	public Header getHeader() {
		return header;
	}

	/**
	 * Returns Datasource object for the given datasource index.
	 *
	 * @param dsIndex Datasource index (zero based)
	 * @return Datasource object
	 */
	public Datasource getDatasource(int dsIndex) {
		return datasources[dsIndex];
	}

	/**
	 * Returns Archive object for the given archive index.
	 *
	 * @param arcIndex Archive index (zero based)
	 * @return Archive object
	 */
	public Archive getArchive(int arcIndex) {
		return archives[arcIndex];
	}

	/**
	 * <p>Returns an array of datasource names defined in RRD.</p>
	 *
	 * @return Array of datasource names.
	 * @throws IOException Thrown in case of I/O error.
	 */
	public String[] getDsNames() throws IOException {
		int n = datasources.length;
		String[] dsNames = new String[n];
		for (int i = 0; i < n; i++) {
			dsNames[i] = datasources[i].getDsName();
		}
		return dsNames;
	}

	/**
	 * <p>Creates new sample with the given timestamp and all datasource values set to
	 * 'unknown'. Use returned <code>Sample</code> object to specify
	 * datasource values for the given timestamp. See documentation for
	 * {@link org.jrobin.core.Sample Sample} for an explanation how to do this.</p>
	 * <p/>
	 * <p>Once populated with data source values, call Sample's
	 * {@link org.jrobin.core.Sample#update() update()} method to actually
	 * store sample in the RRD associated with it.</p>
	 *
	 * @param time Sample timestamp rounded to the nearest second (without milliseconds).
	 * @return Fresh sample with the given timestamp and all data source values set to 'unknown'.
	 * @throws IOException Thrown in case of I/O error.
	 */
	public Sample createSample(long time) throws IOException {
		return new Sample(this, time);
	}

	/**
	 * <p>Creates new sample with the current timestamp and all data source values set to
	 * 'unknown'. Use returned <code>Sample</code> object to specify
	 * datasource values for the current timestamp. See documentation for
	 * {@link org.jrobin.core.Sample Sample} for an explanation how to do this.</p>
	 * <p/>
	 * <p>Once populated with data source values, call Sample's
	 * {@link org.jrobin.core.Sample#update() update()} method to actually
	 * store sample in the RRD associated with it.</p>
	 *
	 * @return Fresh sample with the current timestamp and all
	 *         data source values set to 'unknown'.
	 * @throws IOException Thrown in case of I/O error.
	 */
	public Sample createSample() throws IOException {
		return createSample(Util.getTime());
	}

	/**
	 * <p>Prepares fetch request to be executed on this RRD. Use returned
	 * <code>FetchRequest</code> object and its {@link org.jrobin.core.FetchRequest#fetchData() fetchData()}
	 * method to actually fetch data from the RRD file.</p>
	 *
	 * @param consolFun  Consolidation function to be used in fetch request. Allowed values are
	 *                   "AVERAGE", "MIN", "MAX" and "LAST" (these constants are conveniently defined in the
	 *                   {@link ConsolFuns} class).
	 * @param fetchStart Starting timestamp for fetch request.
	 * @param fetchEnd   Ending timestamp for fetch request.
	 * @param resolution Fetch resolution (see RRDTool's
	 *                   <a href="../../../../man/rrdfetch.html" target="man">rrdfetch man page</a> for an
	 *                   explanation of this parameter.
	 * @return Request object that should be used to actually fetch data from RRD.
	 * @throws RrdException In case of JRobin related error (invalid consolidation function or
	 *                      invalid time span).
	 */
	public FetchRequest createFetchRequest(String consolFun, long fetchStart, long fetchEnd,
										   long resolution) throws RrdException {
		return new FetchRequest(this, consolFun, fetchStart, fetchEnd, resolution);
	}

	/**
	 * <p>Prepares fetch request to be executed on this RRD. Use returned
	 * <code>FetchRequest</code> object and its {@link org.jrobin.core.FetchRequest#fetchData() fetchData()}
	 * method to actually fetch data from this RRD. Data will be fetched with the smallest
	 * possible resolution (see RRDTool's
	 * <a href="../../../../man/rrdfetch.html" target="man">rrdfetch man page</a>
	 * for the explanation of the resolution parameter).</p>
	 *
	 * @param consolFun  Consolidation function to be used in fetch request. Allowed values are
	 *                   "AVERAGE", "MIN", "MAX" and "LAST" (these constants are conveniently defined in the
	 *                   {@link ConsolFuns} class).
	 * @param fetchStart Starting timestamp for fetch request.
	 * @param fetchEnd   Ending timestamp for fetch request.
	 * @return Request object that should be used to actually fetch data from RRD.
	 * @throws RrdException In case of JRobin related error (invalid consolidation function or
	 *                      invalid time span).
	 */
	public FetchRequest createFetchRequest(String consolFun, long fetchStart, long fetchEnd)
			throws RrdException {
		return createFetchRequest(consolFun, fetchStart, fetchEnd, 1);
	}

	synchronized void store(Sample sample) throws IOException, RrdException {
		if (closed) {
			throw new RrdException("RRD already closed, cannot store this  sample");
		}
		long newTime = sample.getTime();
		long lastTime = header.getLastUpdateTime();
		if (lastTime >= newTime) {
			throw new RrdException("Bad sample timestamp " + newTime +
					". Last update time was " + lastTime + ", at least one second step is required");
		}
		double[] newValues = sample.getValues();
		for (int i = 0; i < datasources.length; i++) {
			double newValue = newValues[i];
			datasources[i].process(newTime, newValue);
		}
		header.setLastUpdateTime(newTime);
	}

	synchronized FetchData fetchData(FetchRequest request) throws IOException, RrdException {
		if (closed) {
			throw new RrdException("RRD already closed, cannot fetch data");
		}
		Archive archive = findMatchingArchive(request);
		return archive.fetchData(request);
	}

	public Archive findMatchingArchive(FetchRequest request) throws RrdException, IOException {
		String consolFun = request.getConsolFun();
		long fetchStart = request.getFetchStart();
		long fetchEnd = request.getFetchEnd();
		long resolution = request.getResolution();
		Archive bestFullMatch = null, bestPartialMatch = null;
		long bestStepDiff = 0, bestMatch = 0;
		for (Archive archive : archives) {
			if (archive.getConsolFun().equals(consolFun)) {
				long arcStep = archive.getArcStep();
				long arcStart = archive.getStartTime() - arcStep;
				long arcEnd = archive.getEndTime();
				long fullMatch = fetchEnd - fetchStart;
				if (arcEnd >= fetchEnd && arcStart <= fetchStart) {
					long tmpStepDiff = Math.abs(archive.getArcStep() - resolution);

					if (tmpStepDiff < bestStepDiff || bestFullMatch == null) {
						bestStepDiff = tmpStepDiff;
						bestFullMatch = archive;
					}
				}
				else {
					long tmpMatch = fullMatch;

					if (arcStart > fetchStart) {
						tmpMatch -= (arcStart - fetchStart);
					}
					if (arcEnd < fetchEnd) {
						tmpMatch -= (fetchEnd - arcEnd);
					}
					if (bestPartialMatch == null || bestMatch < tmpMatch) {
						bestPartialMatch = archive;
						bestMatch = tmpMatch;
					}
				}
			}
		}
		if (bestFullMatch != null) {
			return bestFullMatch;
		}
		else if (bestPartialMatch != null) {
			return bestPartialMatch;
		}
		else {
			throw new RrdException("RRD file does not contain RRA:" + consolFun + " archive");
		}
	}

	/**
	 * Finds the archive that best matches to the start time (time period being start-time until now)
	 * and requested resolution.
	 *
	 * @param consolFun  Consolidation function of the datasource.
	 * @param startTime  Start time of the time period in seconds.
	 * @param resolution Requested fetch resolution.
	 * @return Reference to the best matching archive.
	 * @throws IOException Thrown in case of I/O related error.
	 */
	public Archive findStartMatchArchive(String consolFun, long startTime, long resolution) throws IOException {
		long arcStep, diff;
		int fallBackIndex = 0;
		int arcIndex = -1;
		long minDiff = Long.MAX_VALUE;
		long fallBackDiff = Long.MAX_VALUE;

		for (int i = 0; i < archives.length; i++) {
			if (archives[i].getConsolFun().equals(consolFun)) {
				arcStep = archives[i].getArcStep();
				diff = Math.abs(resolution - arcStep);

				// Now compare start time, see if this archive encompasses the requested interval
				if (startTime >= archives[i].getStartTime()) {
					if (diff == 0)				// Best possible match either way
					{
						return archives[i];
					}
					else if (diff < minDiff) {
						minDiff = diff;
						arcIndex = i;
					}
				}
				else if (diff < fallBackDiff) {
					fallBackDiff = diff;
					fallBackIndex = i;
				}
			}
		}

		return (arcIndex >= 0 ? archives[arcIndex] : archives[fallBackIndex]);
	}

	/**
	 * <p>Returns string representing complete internal RRD state. The returned
	 * string can be printed to <code>stdout</code> and/or used for debugging purposes.</p>
	 *
	 * @return String representing internal RRD state.
	 * @throws IOException Thrown in case of I/O related error.
	 */
	public synchronized String dump() throws IOException {
		StringBuffer buffer = new StringBuffer();
		buffer.append(header.dump());
		for (Datasource datasource : datasources) {
			buffer.append(datasource.dump());
		}
		for (Archive archive : archives) {
			buffer.append(archive.dump());
		}
		return buffer.toString();
	}

	void archive(Datasource datasource, double value, long numUpdates)
			throws IOException, RrdException {
		int dsIndex = getDsIndex(datasource.getDsName());
		for (Archive archive : archives) {
			archive.archive(dsIndex, value, numUpdates);
		}
	}

	/**
	 * <p>Returns internal index number for the given datasource name. This index is heavily
	 * used by jrobin.graph package and has no value outside of it.</p>
	 *
	 * @param dsName Data source name.
	 * @return Internal index of the given data source name in this RRD.
	 * @throws RrdException Thrown in case of JRobin related error (invalid data source name,
	 *                      for example)
	 * @throws IOException  Thrown in case of I/O error.
	 */
	public int getDsIndex(String dsName) throws RrdException, IOException {
		for (int i = 0; i < datasources.length; i++) {
			if (datasources[i].getDsName().equals(dsName)) {
				return i;
			}
		}
		throw new RrdException("Unknown datasource name: " + dsName);
	}

	/**
	 * Checks presence of a specific datasource.
	 *
	 * @param dsName Datasource name to check
	 * @return <code>true</code> if datasource is present in this RRD, <code>false</code> otherwise
	 * @throws IOException Thrown in case of I/O error.
	 */
	public boolean containsDs(String dsName) throws IOException {
		for (Datasource datasource : datasources) {
			if (datasource.getDsName().equals(dsName)) {
				return true;
			}
		}
		return false;
	}

	Datasource[] getDatasources() {
		return datasources;
	}

	Archive[] getArchives() {
		return archives;
	}

	/**
	 * <p>Writes the RRD content to OutputStream using XML format. This format
	 * is fully compatible with RRDTool's XML dump format and can be used for conversion
	 * purposes or debugging.</p>

⌨️ 快捷键说明

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