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

📄 dataprocessor.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.data;

import org.jrobin.core.*;

import java.io.IOException;
import java.util.*;

/**
 * Class which should be used for all calculations based on the data fetched from RRD files. This class
 * supports ordinary DEF datasources (defined in RRD files), CDEF datasources (RPN expressions evaluation),
 * SDEF (static datasources - extension of JRobin) and PDEF (plottables, see
 * {@link Plottable Plottable} for more information.<p>
 * <p/>
 * Typical class usage:<p>
 * <pre>
 * final long t1 = ...
 * final long t2 = ...
 * DataProcessor dp = new DataProcessor(t1, t2);
 * // DEF datasource
 * dp.addDatasource("x", "demo.rrd", "some_source", "AVERAGE");
 * // DEF datasource
 * dp.addDatasource("y", "demo.rrd", "some_other_source", "AVERAGE");
 * // CDEF datasource, z = (x + y) / 2
 * dp.addDatasource("z", "x,y,+,2,/");
 * // ACTION!
 * dp.processData();
 * // Dump calculated values
 * System.out.println(dp.dump());
 * </pre>
 */
public class DataProcessor implements ConsolFuns {
	/**
	 * Constant representing the default number of pixels on a JRobin graph (will be used if
	 * no other value is specified with {@link #setStep(long) setStep()} method.
	 */
	public static final int DEFAULT_PIXEL_COUNT = 600;
	private static final double DEFAULT_PERCENTILE = 95.0; // %

	private int pixelCount = DEFAULT_PIXEL_COUNT;

	/**
	 * Constant that defines the default {@link RrdDbPool} usage policy. Defaults to <code>false</code>
	 * (i.e. the pool will not be used to fetch data from RRD files)
	 */
	public static final boolean DEFAULT_POOL_USAGE_POLICY = false;
	private boolean poolUsed = DEFAULT_POOL_USAGE_POLICY;

	private final long tStart;
	private long tEnd, timestamps[];
	private long lastRrdArchiveUpdateTime = 0;
	// this will be adjusted later
	private long step = 0;
	// resolution to be used for RRD fetch operation
	private long fetchRequestResolution = 1;

	// the order is important, ordinary HashMap is unordered
	private Map<String, Source> sources = new LinkedHashMap<String, Source>();

	private Def[] defSources;

	/**
	 * Creates new DataProcessor object for the given time span. Ending timestamp may be set to zero.
	 * In that case, the class will try to find the optimal ending timestamp based on the last update time of
	 * RRD files processed with the {@link #processData()} method.
	 *
	 * @param t1 Starting timestamp in seconds without milliseconds
	 * @param t2 Ending timestamp in seconds without milliseconds
	 * @throws RrdException Thrown if invalid timestamps are supplied
	 */
	public DataProcessor(long t1, long t2) throws RrdException {
		if ((t1 < t2 && t1 > 0 && t2 > 0) || (t1 > 0 && t2 == 0)) {
			this.tStart = t1;
			this.tEnd = t2;
		}
		else {
			throw new RrdException("Invalid timestamps specified: " + t1 + ", " + t2);
		}
	}

	/**
	 * Creates new DataProcessor object for the given time span. Ending date may be set to null.
	 * In that case, the class will try to find optimal ending date based on the last update time of
	 * RRD files processed with the {@link #processData()} method.
	 *
	 * @param d1 Starting date
	 * @param d2 Ending date
	 * @throws RrdException Thrown if invalid timestamps are supplied
	 */
	public DataProcessor(Date d1, Date d2) throws RrdException {
		this(Util.getTimestamp(d1), d2 != null ? Util.getTimestamp(d2) : 0);
	}

	/**
	 * Creates new DataProcessor object for the given time span. Ending date may be set to null.
	 * In that case, the class will try to find optimal ending date based on the last update time of
	 * RRD files processed with the {@link #processData()} method.
	 *
	 * @param gc1 Starting Calendar date
	 * @param gc2 Ending Calendar date
	 * @throws RrdException Thrown if invalid timestamps are supplied
	 */
	public DataProcessor(Calendar gc1, Calendar gc2) throws RrdException {
		this(Util.getTimestamp(gc1), gc2 != null ? Util.getTimestamp(gc2) : 0);
	}

	/**
	 * Returns boolean value representing {@link org.jrobin.core.RrdDbPool RrdDbPool} usage policy.
	 *
	 * @return true, if the pool will be used internally to fetch data from RRD files, false otherwise.
	 */
	public boolean isPoolUsed() {
		return poolUsed;
	}

	/**
	 * Sets the {@link org.jrobin.core.RrdDbPool RrdDbPool} usage policy.
	 *
	 * @param poolUsed true, if the pool should be used to fetch data from RRD files, false otherwise.
	 */
	public void setPoolUsed(boolean poolUsed) {
		this.poolUsed = poolUsed;
	}

	/**
	 * Sets the number of pixels (target graph width). This number is used only to calculate pixel coordinates
	 * for JRobin graphs (methods {@link #getValuesPerPixel(String)} and {@link #getTimestampsPerPixel()}),
	 * but has influence neither on datasource values calculated with the
	 * {@link #processData()} method nor on aggregated values returned from {@link #getAggregates(String)}
	 * and similar methods. In other words, aggregated values will not change once you decide to change
	 * the dimension of your graph.<p>
	 * <p/>
	 * The default number of pixels is defined by constant {@link #DEFAULT_PIXEL_COUNT}
	 * and can be changed with a {@link #setPixelCount(int)} method.
	 *
	 * @param pixelCount The number of pixels. If you process RRD data in order to display it on the graph,
	 *                   this should be the width of your graph.
	 */
	public void setPixelCount(int pixelCount) {
		this.pixelCount = pixelCount;
	}

	/**
	 * Returns the number of pixels (target graph width). See {@link #setPixelCount(int)} for more information.
	 *
	 * @return Target graph width
	 */
	public int getPixelCount() {
		return pixelCount;
	}

	/**
	 * Roughly corresponds to the --step option in RRDTool's graph/xport commands. Here is an explanation borrowed
	 * from RRDTool:<p>
	 * <p/>
	 * <i>"By default rrdgraph calculates the width of one pixel in the time
	 * domain and tries to get data at that resolution from the RRD. With
	 * this switch you can override this behavior. If you want rrdgraph to
	 * get data at 1 hour resolution from the RRD, then you can set the
	 * step to 3600 seconds. Note, that a step smaller than 1 pixel will
	 * be silently ignored."</i><p>
	 * <p/>
	 * I think this option is not that useful, but it's here just for compatibility.<p>
	 *
	 * @param step Time step at which data should be fetched from RRD files. If this method is not used,
	 *             the step will be equal to the smallest RRD step of all processed RRD files. If no RRD file is processed,
	 *             the step will be roughly equal to the with of one graph pixel (in seconds).
	 */
	public void setStep(long step) {
		this.step = step;
	}

	/**
	 * Returns the time step used for data processing. Initially, this method returns zero.
	 * Once {@link #processData()} is finished, the method will return the real value used for
	 * all internal computations. Roughly corresponds to the --step option in RRDTool's graph/xport commands.
	 *
	 * @return Step used for data processing.
	 */
	public long getStep() {
		return step;
	}

	/**
	 * Returns desired RRD archive step (reslution) in seconds to be used while fetching data
	 * from RRD files. In other words, this value will used as the last parameter of
	 * {@link RrdDb#createFetchRequest(String, long, long, long) RrdDb.createFetchRequest()} method
	 * when this method is called internally by this DataProcessor.
	 *
	 * @return Desired archive step (fetch resolution) in seconds.
	 */
	public long getFetchRequestResolution() {
		return fetchRequestResolution;
	}

	/**
	 * Sets desired RRD archive step in seconds to be used internally while fetching data
	 * from RRD files. In other words, this value will used as the last parameter of
	 * {@link RrdDb#createFetchRequest(String, long, long, long) RrdDb.createFetchRequest()} method
	 * when this method is called internally by this DataProcessor. If this method is never called, fetch
	 * request resolution defaults to 1 (smallest possible archive step will be chosen automatically).
	 *
	 * @param fetchRequestResolution Desired archive step (fetch resoltuion) in seconds.
	 */
	public void setFetchRequestResolution(long fetchRequestResolution) {
		this.fetchRequestResolution = fetchRequestResolution;
	}

	/**
	 * Returns ending timestamp. Basically, this value is equal to the ending timestamp
	 * specified in the constructor. However, if the ending timestamps was zero, it
	 * will be replaced with the real timestamp when the {@link #processData()} method returns. The real
	 * value will be calculated from the last update times of processed RRD files.
	 *
	 * @return Ending timestamp in seconds
	 */
	public long getEndingTimestamp() {
		return tEnd;
	}

	/**
	 * Returns consolidated timestamps created with the {@link #processData()} method.
	 *
	 * @return array of timestamps in seconds
	 * @throws RrdException thrown if timestamps are not calculated yet
	 */
	public long[] getTimestamps() throws RrdException {
		if (timestamps == null) {
			throw new RrdException("Timestamps not calculated yet");
		}
		else {
			return timestamps;
		}
	}

	/**
	 * Returns calculated values for a single datasource. Corresponding timestamps can be obtained from
	 * the {@link #getTimestamps()} method.
	 *
	 * @param sourceName Datasource name
	 * @return an array of datasource values
	 * @throws RrdException Thrown if invalid datasource name is specified,
	 *                      or if datasource values are not yet calculated (method {@link #processData()}
	 *                      was not called)
	 */
	public double[] getValues(String sourceName) throws RrdException {
		Source source = getSource(sourceName);
		double[] values = source.getValues();
		if (values == null) {
			throw new RrdException("Values not available for source [" + sourceName + "]");
		}
		return values;
	}

	/**
	 * Returns single aggregated value for a single datasource.
	 *
	 * @param sourceName Datasource name
	 * @param consolFun  Consolidation function to be applied to fetched datasource values.
	 *                   Valid consolidation functions are MIN, MAX, LAST, FIRST, AVERAGE and TOTAL
	 *                   (these string constants are conveniently defined in the {@link ConsolFuns} class)
	 * @return MIN, MAX, LAST, FIRST, AVERAGE or TOTAL value calculated from the data
	 *         for the given datasource name
	 * @throws RrdException Thrown if invalid datasource name is specified,
	 *                      or if datasource values are not yet calculated (method {@link #processData()}
	 *                      was not called)
	 */
	public double getAggregate(String sourceName, String consolFun) throws RrdException {
		Source source = getSource(sourceName);
		return source.getAggregates(tStart, tEnd).getAggregate(consolFun);
	}

	/**
	 * Returns all (MIN, MAX, LAST, FIRST, AVERAGE and TOTAL) aggregated values for a single datasource.

⌨️ 快捷键说明

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