mirror of
https://github.com/i2p/i2p.i2p.git
synced 2026-05-25 14:14:59 +00:00
Console: Update rrd4j to version 3.9
This commit is contained in:
+1
-1
@@ -267,7 +267,7 @@ Applications:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
See licenses/LICENSE-ECLIPSE-1.0.html
|
||||
|
||||
RRD4J 3.8 (jrobin.jar):
|
||||
RRD4J 3.9 (jrobin.jar):
|
||||
Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor.
|
||||
Copyright (c) 2011 The OpenNMS Group, Inc.
|
||||
Copyright 2011 The RRD4J Authors.
|
||||
|
||||
@@ -184,7 +184,7 @@ public class PerfectStringHash implements Hash<String> {
|
||||
* such that <code>hash(values[i]) == i</code>.
|
||||
*/
|
||||
|
||||
public PerfectStringHash(final String values[]) {
|
||||
public PerfectStringHash(final String[] values) {
|
||||
final int length = values.length;
|
||||
if (length == 0) throw new IllegalArgumentException("No values supplied");
|
||||
|
||||
@@ -242,7 +242,7 @@ public class PerfectStringHash implements Hash<String> {
|
||||
final int[] pivots = new int[offset * 2];
|
||||
for (int i = 0; i < length;) {
|
||||
final int runLength = runLengths[i];
|
||||
if (runLength > 1) generatePivots(values, i, runLength, pivots, (int) offsets[i << 1]);
|
||||
if (runLength > 1) generatePivots(values, i, runLength, pivots, offsets[i << 1]);
|
||||
i += runLength;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.rrd4j.ConsolFun;
|
||||
* </ul>
|
||||
* For the complete explanation of all archive definition parameters, see RRDTool's
|
||||
* <a href="http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html" target="man">rrdcreate man page</a>
|
||||
*
|
||||
*
|
||||
* @author Sasa Markovic
|
||||
*/
|
||||
|
||||
@@ -9,10 +9,10 @@ import java.io.IOException;
|
||||
* @author Sasa Markovic
|
||||
*/
|
||||
public class ArcState implements RrdUpdater<ArcState> {
|
||||
private Archive parentArc;
|
||||
private final Archive parentArc;
|
||||
|
||||
private RrdDouble<ArcState> accumValue;
|
||||
private RrdLong<ArcState> nanSteps;
|
||||
private final RrdDouble<ArcState> accumValue;
|
||||
private final RrdLong<ArcState> nanSteps;
|
||||
|
||||
ArcState(Archive parentArc, boolean shouldInitialize) throws IOException {
|
||||
this.parentArc = parentArc;
|
||||
|
||||
@@ -143,7 +143,7 @@ public class Archive implements RrdUpdater<Archive> {
|
||||
}
|
||||
}
|
||||
// update robin in bulk
|
||||
int bulkUpdateCount = (int) Math.min(numUpdates / steps.get(), (long) rows.get());
|
||||
int bulkUpdateCount = (int) Math.min(numUpdates / steps.get(), rows.get());
|
||||
robin.bulkStore(value, bulkUpdateCount);
|
||||
// update remaining steps
|
||||
long remainingUpdates = numUpdates % steps.get();
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface DataHolder {
|
||||
* 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;
|
||||
boolean DEFAULT_POOL_USAGE_POLICY = false;
|
||||
|
||||
/**
|
||||
* Returns boolean value representing {@link org.rrd4j.core.RrdDbPool RrdDbPool} usage policy.
|
||||
@@ -164,7 +164,7 @@ public interface DataHolder {
|
||||
/**
|
||||
* Creates a datasource that performs a variable calculation on an
|
||||
* another named datasource to yield a single combined timestamp/value.
|
||||
*
|
||||
* <p>
|
||||
* Requires that the other datasource has already been defined; otherwise, it'll
|
||||
* end up with no data
|
||||
*
|
||||
|
||||
@@ -28,9 +28,9 @@ public class Datasource implements RrdUpdater<Datasource> {
|
||||
private final RrdDouble<Datasource> minValue, maxValue;
|
||||
|
||||
// state variables
|
||||
private RrdDouble<Datasource> lastValue;
|
||||
private RrdLong<Datasource> nanSeconds;
|
||||
private RrdDouble<Datasource> accumValue;
|
||||
private final RrdDouble<Datasource> lastValue;
|
||||
private final RrdLong<Datasource> nanSeconds;
|
||||
private final RrdDouble<Datasource> accumValue;
|
||||
|
||||
Datasource(RrdDb parentDb, DsDef dsDef) throws IOException {
|
||||
boolean shouldInitialize = dsDef != null;
|
||||
@@ -476,4 +476,3 @@ public class Datasource implements RrdUpdater<Datasource> {
|
||||
return parentDb.getRrdAllocator();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.rrd4j.ConsolFun;
|
||||
import org.rrd4j.data.Aggregates;
|
||||
@@ -43,14 +44,14 @@ public class FetchData {
|
||||
// anything funny will do
|
||||
private static final String RPN_SOURCE_NAME = "WHERE THE SPEECHLES UNITE IN A SILENT ACCORD";
|
||||
|
||||
private FetchRequest request;
|
||||
private final FetchRequest request;
|
||||
private String[] dsNames;
|
||||
private long[] timestamps;
|
||||
private double[][] values;
|
||||
|
||||
private Archive matchingArchive;
|
||||
private long arcStep;
|
||||
private long arcEndTime;
|
||||
private final Archive matchingArchive;
|
||||
private final long arcStep;
|
||||
private final long arcEndTime;
|
||||
|
||||
FetchData(Archive matchingArchive, FetchRequest request) throws IOException {
|
||||
this.matchingArchive = matchingArchive;
|
||||
@@ -279,7 +280,7 @@ public class FetchData {
|
||||
}
|
||||
|
||||
private static String padWithBlanks(String input, int width) {
|
||||
StringBuilder buff = new StringBuilder("");
|
||||
StringBuilder buff = new StringBuilder();
|
||||
int diff = width - input.length();
|
||||
while (diff-- > 0) {
|
||||
buff.append(' ');
|
||||
@@ -350,11 +351,10 @@ public class FetchData {
|
||||
* @param rpnExpression RRDTool-like RPN expression
|
||||
* @return Object containing all aggregated values
|
||||
* @throws java.lang.IllegalArgumentException Thrown if invalid RPN expression is supplied
|
||||
* @throws java.io.IOException if any.
|
||||
* @deprecated This method is deprecated. Uses instance of {@link org.rrd4j.data.Variable}, used with {@link org.rrd4j.data.DataProcessor#addDatasource(String, String, Variable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Aggregates getRpnAggregates(String rpnExpression) throws IOException {
|
||||
public Aggregates getRpnAggregates(String rpnExpression) {
|
||||
DataProcessor dataProcessor = createDataProcessor(rpnExpression);
|
||||
return dataProcessor.getAggregates(RPN_SOURCE_NAME);
|
||||
}
|
||||
@@ -402,9 +402,8 @@ public class FetchData {
|
||||
* Dumps fetch data to output stream in XML format. A flush is issued at the end of the xml generation.
|
||||
*
|
||||
* @param outputStream Output stream to dump fetch data to
|
||||
* @throws java.io.IOException Thrown in case of I/O error
|
||||
*/
|
||||
public void exportXml(OutputStream outputStream) throws IOException {
|
||||
public void exportXml(OutputStream outputStream) {
|
||||
//No auto flush for XmlWriter, it will be flushed once, when export is finished
|
||||
try (XmlWriter writer = new XmlWriter(outputStream, false)) {
|
||||
writer.startTag("fetch_data");
|
||||
@@ -447,7 +446,7 @@ public class FetchData {
|
||||
* @throws java.io.IOException Thrown in case of I/O error
|
||||
*/
|
||||
public void exportXml(String filepath) throws IOException {
|
||||
try(OutputStream outputStream = new FileOutputStream(filepath)) {
|
||||
try (OutputStream outputStream = Files.newOutputStream(Paths.get(filepath))) {
|
||||
exportXml(outputStream);
|
||||
}
|
||||
}
|
||||
@@ -456,9 +455,8 @@ public class FetchData {
|
||||
* Dumps fetch data in XML format.
|
||||
*
|
||||
* @return String containing XML formatted fetch data
|
||||
* @throws java.io.IOException Thrown in case of I/O error
|
||||
*/
|
||||
public String exportXml() throws IOException {
|
||||
public String exportXml() {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
exportXml(outputStream);
|
||||
return outputStream.toString();
|
||||
|
||||
@@ -17,11 +17,11 @@ import java.util.Set;
|
||||
* @author Sasa Markovic
|
||||
*/
|
||||
public class FetchRequest {
|
||||
private RrdDb parentDb;
|
||||
private ConsolFun consolFun;
|
||||
private long fetchStart;
|
||||
private long fetchEnd;
|
||||
private long resolution;
|
||||
private final RrdDb parentDb;
|
||||
private final ConsolFun consolFun;
|
||||
private final long fetchStart;
|
||||
private final long fetchEnd;
|
||||
private final long resolution;
|
||||
private String[] filter;
|
||||
|
||||
FetchRequest(RrdDb parentDb, ConsolFun consolFun, long fetchStart, long fetchEnd, long resolution) {
|
||||
@@ -74,7 +74,7 @@ public class FetchRequest {
|
||||
* @param filter Set of datasource names to fetch data for.
|
||||
*/
|
||||
public void setFilter(Set<String> filter) {
|
||||
this.filter = filter.toArray(new String[filter.size()]);
|
||||
this.filter = filter.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,18 +23,19 @@ public class Header implements RrdUpdater<Header> {
|
||||
static final String RRDTOOL_VERSION3 = "0003";
|
||||
private static final String[] VERSIONS = {"version 0.1", "version 0.2"};
|
||||
|
||||
private RrdDb parentDb;
|
||||
private final RrdDb parentDb;
|
||||
private int version = -1;
|
||||
|
||||
private RrdString<Header> signature;
|
||||
private RrdLong<Header> step;
|
||||
private RrdInt<Header> dsCount, arcCount;
|
||||
private RrdLong<Header> lastUpdateTime;
|
||||
private final RrdString<Header> signature;
|
||||
private final RrdLong<Header> step;
|
||||
private final RrdInt<Header> dsCount;
|
||||
private final RrdInt<Header> arcCount;
|
||||
private final RrdLong<Header> lastUpdateTime;
|
||||
|
||||
Header(RrdDb parentDb, RrdDef rrdDef) throws IOException {
|
||||
this.parentDb = parentDb;
|
||||
|
||||
String initSignature = null;
|
||||
String initSignature;
|
||||
if(rrdDef != null) {
|
||||
version = rrdDef.getVersion();
|
||||
initSignature = SIGNATURE + ", " + VERSIONS[version - 1];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class to represent archive values for a single datasource. Robin class is the heart of
|
||||
@@ -18,7 +19,7 @@ class RobinArray implements Robin {
|
||||
private final Archive parentArc;
|
||||
private final RrdInt<Robin> pointer;
|
||||
private final RrdDoubleArray<Robin> values;
|
||||
private int rows;
|
||||
private final int rows;
|
||||
|
||||
RobinArray(Archive parentArc, int rows, boolean shouldInitialize) throws IOException {
|
||||
this.parentArc = parentArc;
|
||||
@@ -104,9 +105,7 @@ class RobinArray implements Robin {
|
||||
/** {@inheritDoc} */
|
||||
public void setValues(double newValue) throws IOException {
|
||||
double[] values = new double[rows];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = newValue;
|
||||
}
|
||||
Arrays.fill(values, newValue);
|
||||
update(values);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class to represent archive values for a single datasource. Robin class is the heart of
|
||||
@@ -18,10 +19,10 @@ class RobinMatrix implements Robin {
|
||||
private final Archive parentArc;
|
||||
private final RrdInt<Archive> pointer;
|
||||
private final RrdDoubleMatrix<Archive> values;
|
||||
private int rows;
|
||||
private int column;
|
||||
private final int rows;
|
||||
private final int column;
|
||||
|
||||
RobinMatrix(Archive parentArc, RrdDoubleMatrix<Archive> values, RrdInt<Archive> pointer, int column) throws IOException {
|
||||
RobinMatrix(Archive parentArc, RrdDoubleMatrix<Archive> values, RrdInt<Archive> pointer, int column) {
|
||||
this.parentArc = parentArc;
|
||||
this.pointer = pointer;
|
||||
this.values = values;
|
||||
@@ -101,9 +102,7 @@ class RobinMatrix implements Robin {
|
||||
*/
|
||||
public void setValues(double newValue) throws IOException {
|
||||
double[] values = new double[rows];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = newValue;
|
||||
}
|
||||
Arrays.fill(values, newValue);
|
||||
update(values);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An internal usage class.
|
||||
*
|
||||
@@ -14,7 +12,7 @@ public class RrdAllocator {
|
||||
super();
|
||||
}
|
||||
|
||||
long allocate(long byteCount) throws IOException {
|
||||
long allocate(long byteCount) {
|
||||
long pointer = allocationPointer;
|
||||
allocationPointer += byteCount;
|
||||
return pointer;
|
||||
|
||||
@@ -239,8 +239,8 @@ public abstract class RrdBackend {
|
||||
int count = values.length;
|
||||
byte[] image = new byte[8 * count];
|
||||
int k = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
byte[] b = getDoubleBytes(values[i]);
|
||||
for (double value : values) {
|
||||
byte[] b = getDoubleBytes(value);
|
||||
image[k++] = b[0];
|
||||
image[k++] = b[1];
|
||||
image[k++] = b[2];
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.lang.annotation.Target;
|
||||
@Retention(RUNTIME)
|
||||
@Target(TYPE)
|
||||
public @interface RrdBackendAnnotation {
|
||||
public static boolean DEFAULT_CACHING_ALLOWED = true;
|
||||
boolean DEFAULT_CACHING_ALLOWED = true;
|
||||
String name();
|
||||
boolean cachingAllowed() default DEFAULT_CACHING_ALLOWED;
|
||||
String scheme() default "";
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* Factory classes are used to create concrete {@link org.rrd4j.core.RrdBackend} implementations.
|
||||
* Each factory creates unlimited number of specific backend objects.
|
||||
*
|
||||
* <p>
|
||||
* Rrd4j supports six different backend types (backend factories) out of the box:
|
||||
* <ul>
|
||||
* <li>{@link org.rrd4j.core.RrdRandomAccessFileBackend}: objects of this class are created from the
|
||||
@@ -88,7 +88,7 @@ public abstract class RrdBackendFactory implements Closeable {
|
||||
factories.put(safeFactory.name, safeFactory);
|
||||
defaultFactory = factories.get(DEFAULTFACTORY);
|
||||
}
|
||||
private static RrdBackendFactory defaultFactory;
|
||||
private static final RrdBackendFactory defaultFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,10 +541,9 @@ public abstract class RrdBackendFactory implements Closeable {
|
||||
* Determines if the header should be validated.
|
||||
*
|
||||
* @param path Storage path
|
||||
* @throws java.io.IOException if header validation fails
|
||||
* @return a boolean.
|
||||
*/
|
||||
protected boolean shouldValidateHeader(String path) throws IOException {
|
||||
protected boolean shouldValidateHeader(String path) {
|
||||
return validateHeader;
|
||||
}
|
||||
|
||||
@@ -552,10 +551,9 @@ public abstract class RrdBackendFactory implements Closeable {
|
||||
* Determines if the header should be validated.
|
||||
*
|
||||
* @param uri Storage URI
|
||||
* @throws java.io.IOException if header validation fails
|
||||
* @return a boolean.
|
||||
*/
|
||||
protected boolean shouldValidateHeader(URI uri) throws IOException {
|
||||
protected boolean shouldValidateHeader(URI uri) {
|
||||
return shouldValidateHeader(getPath(uri));
|
||||
}
|
||||
|
||||
|
||||
@@ -64,10 +64,9 @@ public abstract class RrdByteArrayBackend extends ByteBufferBackend {
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>It will reserves a memory section as a RRD storage.</p>
|
||||
*
|
||||
* @throws java.lang.IllegalArgumentException if length is bigger that the possible length.
|
||||
*
|
||||
*/
|
||||
protected void setLength(long length) throws IOException {
|
||||
protected void setLength(long length) {
|
||||
if (length < 0 || length > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Illegal length: " + length);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class RrdDb implements RrdUpdater<RrdDb>, Closeable {
|
||||
try (DataImporter rrdImporter = resoleImporter(externalPath, importer)) {
|
||||
if (usePool) {
|
||||
try (RrdDb db = resolvePool(pool).requestRrdDb(rrdUri, factory, importer)) {
|
||||
};
|
||||
}
|
||||
} else {
|
||||
try (RrdDb db = new RrdDb(path, rrdUri, null, rrdImporter, factory, null)) {
|
||||
}
|
||||
@@ -210,7 +210,7 @@ public class RrdDb implements RrdUpdater<RrdDb>, Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used to memorized the pool, without generating a loop
|
||||
* Internal method used to memorize the pool, without generating a loop
|
||||
* @param pool
|
||||
* @return
|
||||
*/
|
||||
@@ -1220,7 +1220,7 @@ public class RrdDb implements RrdUpdater<RrdDb>, Closeable {
|
||||
* <p>
|
||||
* Use <code>original.xml</code> file to create the corresponding RRDTool file
|
||||
* (from your command line):
|
||||
*
|
||||
* <p>
|
||||
* <code>rrdtool restore copy.rrd original.xml</code>
|
||||
*
|
||||
* @param filename Path to XML file which will be created.
|
||||
|
||||
@@ -60,14 +60,14 @@ public class RrdDbPool {
|
||||
final Lock lock;
|
||||
final boolean placeholder;
|
||||
final URI uri;
|
||||
RrdEntry(URI canonicalPath) throws InterruptedException {
|
||||
RrdEntry(URI canonicalPath) {
|
||||
placeholder = false;
|
||||
uri = canonicalPath;
|
||||
inuse = new ReentrantReadWriteLock();
|
||||
lock = inuse.writeLock();
|
||||
waitempty = new CountDownLatch(1);
|
||||
}
|
||||
RrdEntry(RrdEntry parent) throws InterruptedException {
|
||||
RrdEntry(RrdEntry parent) {
|
||||
assert ! parent.placeholder;
|
||||
placeholder = true;
|
||||
uri = parent.uri;
|
||||
@@ -243,7 +243,7 @@ public class RrdDbPool {
|
||||
}
|
||||
|
||||
private enum ACTION {
|
||||
SWAP, DROP;
|
||||
SWAP, DROP
|
||||
}
|
||||
|
||||
private void passNext(ACTION a, RrdEntry e) {
|
||||
@@ -297,7 +297,7 @@ public class RrdDbPool {
|
||||
return;
|
||||
}
|
||||
URI dburi = rrdDb.getCanonicalUri();
|
||||
RrdEntry ref = null;
|
||||
RrdEntry ref;
|
||||
try {
|
||||
ref = getEntry(dburi, false);
|
||||
} catch (InterruptedException e) {
|
||||
@@ -375,10 +375,9 @@ public class RrdDbPool {
|
||||
* Wait for a empty reference with no usage
|
||||
* @param uri
|
||||
* @return an reference with no usage
|
||||
* @throws IOException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private RrdEntry waitEmpty(URI uri) throws IOException, InterruptedException {
|
||||
private RrdEntry waitEmpty(URI uri) throws InterruptedException {
|
||||
RrdEntry ref = getEntry(uri, true);
|
||||
try {
|
||||
while (ref.count != 0) {
|
||||
@@ -401,16 +400,14 @@ public class RrdDbPool {
|
||||
* @param uri
|
||||
* @return an reference with no usage
|
||||
* @throws InterruptedException
|
||||
* @throws IOException
|
||||
*/
|
||||
private RrdEntry requestEmpty(URI uri) throws InterruptedException, IOException {
|
||||
RrdEntry ref = waitEmpty(uri);
|
||||
return ref;
|
||||
private RrdEntry requestEmpty(URI uri) throws InterruptedException {
|
||||
return waitEmpty(uri);
|
||||
}
|
||||
|
||||
RrdDb requestRrdDb(URI uri, RrdBackendFactory factory) throws IOException {
|
||||
uri = factory.getCanonicalUri(uri);
|
||||
RrdEntry ref = null;
|
||||
RrdEntry ref;
|
||||
try {
|
||||
ref = getEntry(uri, true);
|
||||
|
||||
@@ -625,10 +622,9 @@ public class RrdDbPool {
|
||||
*
|
||||
* @param rrdDb RrdDb reference for which informations is needed.
|
||||
* @return the number of request for this RRD.
|
||||
* @throws java.io.IOException if any
|
||||
* @throws java.lang.IllegalStateException if the thread was interrupted
|
||||
*/
|
||||
public int getOpenCount(RrdDb rrdDb) throws IOException {
|
||||
public int getOpenCount(RrdDb rrdDb) {
|
||||
return getCanonicalUriUsage(rrdDb.getCanonicalUri());
|
||||
}
|
||||
|
||||
@@ -638,10 +634,9 @@ public class RrdDbPool {
|
||||
*
|
||||
* @param path RRD's path for which informations is needed.
|
||||
* @return the number of request for this RRD.
|
||||
* @throws java.io.IOException if any
|
||||
* @throws java.lang.IllegalStateException if the thread was interrupted
|
||||
*/
|
||||
public int getOpenCount(String path) throws IOException {
|
||||
public int getOpenCount(String path) {
|
||||
return getCanonicalUriUsage(defaultFactory.getCanonicalUri(defaultFactory.getUri(path)));
|
||||
}
|
||||
|
||||
@@ -650,10 +645,9 @@ public class RrdDbPool {
|
||||
*
|
||||
* @param uri RRD's URI for which informations is needed.
|
||||
* @return the number of request for this RRD.
|
||||
* @throws java.io.IOException if any
|
||||
* @throws java.lang.IllegalStateException if the thread was interrupted
|
||||
*/
|
||||
public int getOpenCount(URI uri) throws IOException {
|
||||
public int getOpenCount(URI uri) {
|
||||
return getCanonicalUriUsage(checkFactory(uri).getCanonicalUri(uri));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
@@ -59,8 +59,8 @@ public class RrdDef {
|
||||
private long step = DEFAULT_STEP;
|
||||
private int version = DEFAULTVERSION;
|
||||
|
||||
private List<DsDef> dsDefs = new ArrayList<>();
|
||||
private List<ArcDef> arcDefs = new ArrayList<>();
|
||||
private final List<DsDef> dsDefs = new ArrayList<>();
|
||||
private final List<ArcDef> arcDefs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* <p>Creates new RRD definition object with the given path.
|
||||
@@ -189,12 +189,19 @@ public class RrdDef {
|
||||
|
||||
/**
|
||||
* Returns path for the new RRD. It's extracted from the URI. If it's an opaque URI, it return the scheme specific part.
|
||||
* <br>
|
||||
* It's not a reliable way to resolve an file path. Instead, one should use <code> Paths.get(def.getUri())</code>
|
||||
* when the URI scheme is file.
|
||||
*
|
||||
* @return path to the new RRD which should be created
|
||||
*/
|
||||
public String getPath() {
|
||||
if (uri.isOpaque()) {
|
||||
return uri.getSchemeSpecificPart();
|
||||
} else if ("file".equals(uri.getScheme())) {
|
||||
// Windows path from URI returns strange results.
|
||||
// Ensure that's a compliant path
|
||||
return Paths.get(uri).toString();
|
||||
} else {
|
||||
return uri.getPath();
|
||||
}
|
||||
@@ -516,7 +523,7 @@ public class RrdDef {
|
||||
* @return Array of data source definition objects
|
||||
*/
|
||||
public DsDef[] getDsDefs() {
|
||||
return dsDefs.toArray(new DsDef[dsDefs.size()]);
|
||||
return dsDefs.toArray(new DsDef[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,13 +591,7 @@ public class RrdDef {
|
||||
}
|
||||
|
||||
void saveSingleDatasource(String dsName) {
|
||||
Iterator<DsDef> it = dsDefs.iterator();
|
||||
while (it.hasNext()) {
|
||||
DsDef dsDef = it.next();
|
||||
if (!dsDef.getDsName().equals(dsName)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
dsDefs.removeIf(dsDef -> !dsDef.getDsName().equals(dsName));
|
||||
}
|
||||
|
||||
void removeArchive(ConsolFun consolFun, int steps) {
|
||||
|
||||
@@ -60,6 +60,7 @@ import java.util.Calendar;
|
||||
* <li>There is a strong relation between the XML template syntax and the syntax of
|
||||
* {@link org.rrd4j.core.RrdDef} class methods. If you are not sure what some XML tag means, check javadoc
|
||||
* for the corresponding class.
|
||||
* <li>the path to the rrd can be specified either as a file path using path element or as an uri using a url tag</li>
|
||||
* <li>starting timestamp can be supplied either as a long integer
|
||||
* (like: 1000243567) or as an ISO formatted string (like: 2004-02-21 12:25:45)
|
||||
* <li>whitespaces are not harmful
|
||||
|
||||
@@ -6,11 +6,11 @@ class RrdDouble<U extends RrdUpdater<U>> extends RrdPrimitive<U> {
|
||||
private double cache;
|
||||
private boolean cached = false;
|
||||
|
||||
RrdDouble(RrdUpdater<U> updater, boolean isConstant) throws IOException {
|
||||
RrdDouble(RrdUpdater<U> updater, boolean isConstant) {
|
||||
super(updater, RrdDouble.RRD_DOUBLE, isConstant);
|
||||
}
|
||||
|
||||
RrdDouble(RrdUpdater<U> updater) throws IOException {
|
||||
RrdDouble(RrdUpdater<U> updater) {
|
||||
super(updater, RrdDouble.RRD_DOUBLE, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package org.rrd4j.core;
|
||||
import java.io.IOException;
|
||||
|
||||
class RrdDoubleArray<U extends RrdUpdater<U>> extends RrdPrimitive<U> {
|
||||
private int length;
|
||||
private final int length;
|
||||
|
||||
RrdDoubleArray(RrdUpdater<U> updater, int length) throws IOException {
|
||||
RrdDoubleArray(RrdUpdater<U> updater, int length) {
|
||||
super(updater, RrdPrimitive.RRD_DOUBLE, length, false);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ class RrdEnum<U extends RrdUpdater<U>, E extends Enum<E>> extends RrdPrimitive<U
|
||||
private E cache;
|
||||
private final Class<E> clazz;
|
||||
|
||||
RrdEnum(RrdUpdater<U> updater, boolean isConstant, Class<E> clazz) throws IOException {
|
||||
RrdEnum(RrdUpdater<U> updater, boolean isConstant, Class<E> clazz) {
|
||||
super(updater, RrdPrimitive.RRD_STRING, isConstant);
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
RrdEnum(RrdUpdater<U> updater, Class<E> clazz) throws IOException {
|
||||
RrdEnum(RrdUpdater<U> updater, Class<E> clazz) {
|
||||
this(updater, false, clazz);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ class RrdInt<U extends RrdUpdater<U>> extends RrdPrimitive<U> {
|
||||
private int cache;
|
||||
private boolean cached = false;
|
||||
|
||||
RrdInt(RrdUpdater<U> updater, boolean isConstant) throws IOException {
|
||||
RrdInt(RrdUpdater<U> updater, boolean isConstant) {
|
||||
super(updater, RrdPrimitive.RRD_INT, isConstant);
|
||||
}
|
||||
|
||||
RrdInt(RrdUpdater<U> updater) throws IOException {
|
||||
RrdInt(RrdUpdater<U> updater) {
|
||||
this(updater, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ class RrdLong<U extends RrdUpdater<U>> extends RrdPrimitive<U> {
|
||||
private long cache;
|
||||
private boolean cached = false;
|
||||
|
||||
RrdLong(RrdUpdater<U> updater, boolean isConstant) throws IOException {
|
||||
RrdLong(RrdUpdater<U> updater, boolean isConstant) {
|
||||
super(updater, RrdPrimitive.RRD_LONG, isConstant);
|
||||
}
|
||||
|
||||
RrdLong(RrdUpdater<U> updater) throws IOException {
|
||||
RrdLong(RrdUpdater<U> updater) {
|
||||
this(updater, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -21,11 +20,11 @@ public class RrdMemoryBackend extends ByteBufferBackend {
|
||||
protected RrdMemoryBackend(String path, AtomicReference<ByteBuffer> refbb) {
|
||||
super(path);
|
||||
this.refbb = refbb;
|
||||
Optional.ofNullable(refbb).map(r -> r.get()).ifPresent(this::setByteBuffer);
|
||||
Optional.ofNullable(refbb).map(AtomicReference::get).ifPresent(this::setByteBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setLength(long length) throws IOException {
|
||||
protected void setLength(long length) {
|
||||
if (length < 0 || length > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Illegal length: " + length);
|
||||
}
|
||||
@@ -34,7 +33,7 @@ public class RrdMemoryBackend extends ByteBufferBackend {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() throws IOException {
|
||||
public long getLength() {
|
||||
return Optional.ofNullable(refbb.get()).map(ByteBuffer::capacity).orElse(0);
|
||||
}
|
||||
|
||||
@@ -42,10 +41,9 @@ public class RrdMemoryBackend extends ByteBufferBackend {
|
||||
* This method is required by the base class definition, but it does not
|
||||
* releases any memory resources at all.
|
||||
*
|
||||
* @throws java.io.IOException if any.
|
||||
*/
|
||||
@Override
|
||||
protected void close() throws IOException {
|
||||
protected void close() {
|
||||
// Don't release ressources, as backend are cached by the factory and reused
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
@@ -28,8 +27,8 @@ public class RrdMemoryBackendFactory extends RrdBackendFactory {
|
||||
*
|
||||
* Creates RrdMemoryBackend object.
|
||||
*/
|
||||
protected RrdBackend open(String id, boolean readOnly) throws IOException {
|
||||
AtomicReference<ByteBuffer> refbb = backends.computeIfAbsent(id, i -> new AtomicReference<ByteBuffer>());
|
||||
protected RrdBackend open(String id, boolean readOnly) {
|
||||
AtomicReference<ByteBuffer> refbb = backends.computeIfAbsent(id, i -> new AtomicReference<>());
|
||||
return new RrdMemoryBackend(id, refbb);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class RrdNioBackend extends ByteBufferBackend implements RrdFileBackend {
|
||||
private static final Object unsafe;
|
||||
static {
|
||||
// Temporary variable, because destinations variables are final
|
||||
// And it interfere with exceptions
|
||||
// And it interferes with exceptions
|
||||
Method cleanerMethodTemp;
|
||||
Method cleanMethodTemp;
|
||||
Method invokeCleanerTemp;
|
||||
@@ -99,11 +99,7 @@ public class RrdNioBackend extends ByteBufferBackend implements RrdFileBackend {
|
||||
}
|
||||
try {
|
||||
if (!readOnly && threadPool != null) {
|
||||
Runnable syncRunnable = new Runnable() {
|
||||
public void run() {
|
||||
sync();
|
||||
}
|
||||
};
|
||||
Runnable syncRunnable = this::sync;
|
||||
syncRunnableHandle = threadPool.scheduleWithFixedDelay(syncRunnable, syncPeriod, syncPeriod, TimeUnit.SECONDS);
|
||||
}
|
||||
} catch (RuntimeException rte) {
|
||||
@@ -193,7 +189,7 @@ public class RrdNioBackend extends ByteBufferBackend implements RrdFileBackend {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalPath() throws IOException {
|
||||
public String getCanonicalPath() {
|
||||
return Paths.get(getPath()).toAbsolutePath().normalize().toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ public class RrdNioBackendFactory extends RrdFileBackendFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
if (syncThreadPool != null) {
|
||||
syncThreadPool.shutdown();
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@ abstract class RrdPrimitive<U extends RrdUpdater<U>> {
|
||||
static final int RRD_INT = 0, RRD_LONG = 1, RRD_DOUBLE = 2, RRD_STRING = 3;
|
||||
static final int[] RRD_PRIM_SIZES = {4, 8, 8, 2 * STRING_LENGTH};
|
||||
|
||||
private RrdBackend backend;
|
||||
private int byteCount;
|
||||
private final RrdBackend backend;
|
||||
private final int byteCount;
|
||||
private final long pointer;
|
||||
private final boolean cachingAllowed;
|
||||
|
||||
RrdPrimitive(RrdUpdater<U> updater, int type, boolean isConstant) throws IOException {
|
||||
RrdPrimitive(RrdUpdater<U> updater, int type, boolean isConstant) {
|
||||
this(updater, type, 1, isConstant);
|
||||
}
|
||||
|
||||
RrdPrimitive(RrdUpdater<U> updater, int type, int count, boolean isConstant) throws IOException {
|
||||
RrdPrimitive(RrdUpdater<U> updater, int type, int count, boolean isConstant) {
|
||||
this.backend = updater.getRrdBackend();
|
||||
this.byteCount = RRD_PRIM_SIZES[type] * count;
|
||||
this.pointer = updater.getRrdAllocator().allocate(byteCount);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class RrdRandomAccessFileBackend extends RrdBackend implements RrdFileBac
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCanonicalPath() throws IOException {
|
||||
public String getCanonicalPath() {
|
||||
return Paths.get(getPath()).toAbsolutePath().normalize().toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import java.io.IOException;
|
||||
class RrdString<U extends RrdUpdater<U>> extends RrdPrimitive<U> {
|
||||
private String cache;
|
||||
|
||||
RrdString(RrdUpdater<U> updater, boolean isConstant) throws IOException {
|
||||
RrdString(RrdUpdater<U> updater, boolean isConstant) {
|
||||
super(updater, RrdPrimitive.RRD_STRING, isConstant);
|
||||
}
|
||||
|
||||
RrdString(RrdUpdater<U> updater) throws IOException {
|
||||
RrdString(RrdUpdater<U> updater) {
|
||||
this(updater, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class RrdToolReader extends DataImporter {
|
||||
return rrd.getHeader().getDSCount();
|
||||
}
|
||||
|
||||
public int getArcCount() throws IOException {
|
||||
public int getArcCount() {
|
||||
return rrd.getNumArchives();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class RrdToolReader extends DataImporter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DsType getDsType(int dsIndex) throws IOException {
|
||||
public DsType getDsType(int dsIndex) {
|
||||
return rrd.getDataSource(dsIndex).getType().getDsType();
|
||||
}
|
||||
|
||||
@@ -79,19 +79,19 @@ class RrdToolReader extends DataImporter {
|
||||
return rrd.getArchive(arcIndex).getPdpCount();
|
||||
}
|
||||
|
||||
public int getRows(int arcIndex) throws IOException {
|
||||
public int getRows(int arcIndex) {
|
||||
return rrd.getArchive(arcIndex).getRowCount();
|
||||
}
|
||||
|
||||
public double getStateAccumValue(int arcIndex, int dsIndex) throws IOException {
|
||||
public double getStateAccumValue(int arcIndex, int dsIndex) {
|
||||
return rrd.getArchive(arcIndex).getCDPStatusBlock(dsIndex).getValue();
|
||||
}
|
||||
|
||||
public int getStateNanSteps(int arcIndex, int dsIndex) throws IOException {
|
||||
public int getStateNanSteps(int arcIndex, int dsIndex) {
|
||||
return rrd.getArchive(arcIndex).getCDPStatusBlock(dsIndex).getUnknownDatapoints();
|
||||
}
|
||||
|
||||
public double[] getValues(int arcIndex, int dsIndex) throws IOException {
|
||||
public double[] getValues(int arcIndex, int dsIndex) {
|
||||
return rrd.getArchive(arcIndex).getValues()[dsIndex];
|
||||
}
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ public class RrdToolkit {
|
||||
}
|
||||
List<String> fileList = new LinkedList<>();
|
||||
traverseDirectory(new File(directory), extension, resursive, fileList);
|
||||
String[] result = fileList.toArray(new String[fileList.size()]);
|
||||
String[] result = fileList.toArray(new String[0]);
|
||||
Arrays.sort(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -54,15 +54,12 @@ public class Util {
|
||||
// directory under $USER_HOME used for demo graphs storing
|
||||
static final String RRD4J_DIR = "rrd4j-demo";
|
||||
|
||||
static final ThreadLocal<NumberFormat> df = new ThreadLocal<NumberFormat>() {
|
||||
@Override
|
||||
protected NumberFormat initialValue() {
|
||||
DecimalFormat ldf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
|
||||
ldf.applyPattern(PATTERN);
|
||||
ldf.setPositivePrefix("+");
|
||||
return ldf;
|
||||
}
|
||||
};
|
||||
static final ThreadLocal<NumberFormat> df = ThreadLocal.withInitial(() -> {
|
||||
DecimalFormat ldf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
|
||||
ldf.applyPattern(PATTERN);
|
||||
ldf.setPositivePrefix("+");
|
||||
return ldf;
|
||||
});
|
||||
|
||||
private static final Pattern SPRINTF_PATTERN = Pattern.compile("([^%]|^)%([^a-zA-Z%]*)l(f|g|e)");
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ import java.util.Locale;
|
||||
|
||||
class XmlReader extends DataImporter {
|
||||
|
||||
private Element root;
|
||||
private Node[] dsNodes, arcNodes;
|
||||
private final Element root;
|
||||
private final Node[] dsNodes;
|
||||
private final Node[] arcNodes;
|
||||
|
||||
XmlReader(String xmlFilePath) throws IOException {
|
||||
root = Util.Xml.getRootElement(new File(xmlFilePath));
|
||||
|
||||
@@ -24,8 +24,8 @@ public abstract class XmlTemplate {
|
||||
private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING);
|
||||
|
||||
protected Element root;
|
||||
private HashMap<String, Object> valueMap = new HashMap<>();
|
||||
private HashSet<Node> validatedNodes = new HashSet<>();
|
||||
private final HashMap<String, Object> valueMap = new HashMap<>();
|
||||
private final HashSet<Node> validatedNodes = new HashSet<>();
|
||||
|
||||
/**
|
||||
* <p>Constructor for XmlTemplate.</p>
|
||||
@@ -85,7 +85,7 @@ public abstract class XmlTemplate {
|
||||
* @param value value to be set in the XML template
|
||||
*/
|
||||
public void setVariable(String name, int value) {
|
||||
valueMap.put(name, Integer.valueOf(value));
|
||||
valueMap.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ public abstract class XmlTemplate {
|
||||
* @param value value to be set in the XML template
|
||||
*/
|
||||
public void setVariable(String name, long value) {
|
||||
valueMap.put(name, Long.valueOf(value));
|
||||
valueMap.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ public abstract class XmlTemplate {
|
||||
* @param value value to be set in the XML template
|
||||
*/
|
||||
public void setVariable(String name, double value) {
|
||||
valueMap.put(name, Double.valueOf(value));
|
||||
valueMap.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +185,7 @@ public abstract class XmlTemplate {
|
||||
/**
|
||||
* Returns the list of variables that should be set in this template.
|
||||
*
|
||||
* @return List of variable names as an array of strings.
|
||||
* @return Array of variable names as an array of strings.
|
||||
*/
|
||||
public String[] getVariables() {
|
||||
ArrayList<String> list = new ArrayList<>();
|
||||
@@ -198,7 +198,7 @@ public abstract class XmlTemplate {
|
||||
}
|
||||
}
|
||||
|
||||
return list.toArray(new String[list.size()]);
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,7 +301,7 @@ public abstract class XmlTemplate {
|
||||
String var = matcher.group(1);
|
||||
if (valueMap.containsKey(var)) {
|
||||
// mapping found
|
||||
result.append(templateValue.substring(lastMatchEnd, matcher.start()));
|
||||
result.append(templateValue, lastMatchEnd, matcher.start());
|
||||
result.append(valueMap.get(var).toString());
|
||||
lastMatchEnd = matcher.end();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class XmlWriter implements AutoCloseable {
|
||||
}
|
||||
|
||||
private final PrintWriter writer;
|
||||
private final StringBuilder indent = new StringBuilder("");
|
||||
private final StringBuilder indent = new StringBuilder();
|
||||
private final Deque<String> openTags = new LinkedList<>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core.jrrd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
@@ -21,7 +20,7 @@ import java.util.Locale;
|
||||
*/
|
||||
public class Archive {
|
||||
|
||||
private static enum rra_par_en {RRA_cdp_xff_val, RRA_hw_alpha};
|
||||
private enum rra_par_en {RRA_cdp_xff_val, RRA_hw_alpha}
|
||||
|
||||
final RRDatabase db;
|
||||
/** Header offset within file in bytes */
|
||||
@@ -47,7 +46,7 @@ public class Archive {
|
||||
/** Cached content */
|
||||
private double[][] values;
|
||||
|
||||
Archive(RRDatabase db) throws IOException {
|
||||
Archive(RRDatabase db) {
|
||||
|
||||
this.db = db;
|
||||
|
||||
@@ -74,9 +73,9 @@ public class Archive {
|
||||
return type;
|
||||
}
|
||||
|
||||
void loadCDPStatusBlocks(RRDFile file, int numBlocks) throws IOException {
|
||||
void loadCDPStatusBlocks(RRDFile file, int numBlocks) {
|
||||
|
||||
cdpStatusBlocks = new ArrayList<CDPStatusBlock>();
|
||||
cdpStatusBlocks = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
cdpStatusBlocks.add(new CDPStatusBlock(file));
|
||||
@@ -103,11 +102,11 @@ public class Archive {
|
||||
return cdpStatusBlocks.iterator();
|
||||
}
|
||||
|
||||
void loadCurrentRow(RRDFile file) throws IOException {
|
||||
void loadCurrentRow(RRDFile file) {
|
||||
currentRow = file.readLong();
|
||||
}
|
||||
|
||||
void loadData(RRDFile file, int dsCount) throws IOException {
|
||||
void loadData(RRDFile file, int dsCount) {
|
||||
|
||||
dataOffset = file.getFilePointer();
|
||||
|
||||
@@ -115,8 +114,7 @@ public class Archive {
|
||||
file.skipBytes(Constants.SIZE_OF_DOUBLE * rowCount * dsCount);
|
||||
}
|
||||
|
||||
void loadData(DataChunk chunk)
|
||||
throws IOException {
|
||||
void loadData(DataChunk chunk) {
|
||||
|
||||
long rowIndexPointer;
|
||||
|
||||
@@ -186,18 +184,14 @@ public class Archive {
|
||||
|
||||
int cdpIndex = 0;
|
||||
|
||||
for (Iterator<CDPStatusBlock> i = cdpStatusBlocks.iterator(); i.hasNext();) {
|
||||
CDPStatusBlock cdp = i.next();
|
||||
|
||||
for (CDPStatusBlock cdp : cdpStatusBlocks) {
|
||||
s.print(sb);
|
||||
s.print(cdpIndex);
|
||||
s.print("].value = ");
|
||||
|
||||
double value = cdp.value;
|
||||
|
||||
s.println(Double.isNaN(value)
|
||||
? "NaN"
|
||||
: numberFormat.format(value));
|
||||
s.println(Double.isNaN(value) ? "NaN" : numberFormat.format(value));
|
||||
s.print(sb);
|
||||
s.print(cdpIndex++);
|
||||
s.print("].unknown_datapoints = ");
|
||||
@@ -206,97 +200,89 @@ public class Archive {
|
||||
}
|
||||
|
||||
void toXml(PrintStream s) {
|
||||
s.println("\t<rra>");
|
||||
s.print("\t\t<cf> ");
|
||||
s.print(type);
|
||||
s.println(" </cf>");
|
||||
s.print("\t\t<pdp_per_row> ");
|
||||
s.print(pdpCount);
|
||||
s.print(" </pdp_per_row> <!-- ");
|
||||
s.print(db.header.pdpStep * pdpCount);
|
||||
s.println(" seconds -->");
|
||||
s.print("\t\t<xff> ");
|
||||
s.print(xff);
|
||||
s.println(" </xff>");
|
||||
s.println();
|
||||
s.println("\t\t<cdp_prep>");
|
||||
|
||||
try {
|
||||
s.println("\t<rra>");
|
||||
s.print("\t\t<cf> ");
|
||||
s.print(type);
|
||||
s.println(" </cf>");
|
||||
s.print("\t\t<pdp_per_row> ");
|
||||
s.print(pdpCount);
|
||||
s.print(" </pdp_per_row> <!-- ");
|
||||
s.print(db.header.pdpStep * pdpCount);
|
||||
s.println(" seconds -->");
|
||||
s.print("\t\t<xff> ");
|
||||
s.print(xff);
|
||||
s.println(" </xff>");
|
||||
s.println();
|
||||
s.println("\t\t<cdp_prep>");
|
||||
for (CDPStatusBlock cdpStatusBlock : cdpStatusBlocks) {
|
||||
cdpStatusBlock.toXml(s);
|
||||
}
|
||||
|
||||
for (int i = 0; i < cdpStatusBlocks.size(); i++) {
|
||||
cdpStatusBlocks.get(i).toXml(s);
|
||||
s.println("\t\t</cdp_prep>");
|
||||
s.println("\t\t<database>");
|
||||
|
||||
long timer = -(rowCount - 1);
|
||||
int counter = 0;
|
||||
int row = currentRow;
|
||||
|
||||
db.rrdFile.seek(dataOffset + (row + 1) * db.header.dsCount * Constants.SIZE_OF_DOUBLE);
|
||||
|
||||
long lastUpdate = db.lastUpdate.getTime() / 1000;
|
||||
int pdpStep = db.header.pdpStep;
|
||||
NumberFormat numberFormat = new DecimalFormat("0.0000000000E0", DecimalFormatSymbols.getInstance(Locale.US));
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
|
||||
while (counter++ < rowCount) {
|
||||
row++;
|
||||
|
||||
if (row == rowCount) {
|
||||
row = 0;
|
||||
|
||||
db.rrdFile.seek(dataOffset);
|
||||
}
|
||||
|
||||
s.println("\t\t</cdp_prep>");
|
||||
s.println("\t\t<database>");
|
||||
long now = (lastUpdate - lastUpdate % (pdpCount * pdpStep))
|
||||
+ (timer * pdpCount * pdpStep);
|
||||
|
||||
long timer = -(rowCount - 1);
|
||||
int counter = 0;
|
||||
int row = currentRow;
|
||||
timer++;
|
||||
|
||||
db.rrdFile.seek(dataOffset + (row + 1) * db.header.dsCount * Constants.SIZE_OF_DOUBLE);
|
||||
s.print("\t\t\t<!-- ");
|
||||
s.print(dateFormat.format(new Date(now * 1000)));
|
||||
s.print(" / ");
|
||||
s.print(now);
|
||||
s.print(" --> ");
|
||||
|
||||
long lastUpdate = db.lastUpdate.getTime() / 1000;
|
||||
int pdpStep = db.header.pdpStep;
|
||||
NumberFormat numberFormat = new DecimalFormat("0.0000000000E0", DecimalFormatSymbols.getInstance(Locale.US));
|
||||
SimpleDateFormat dateFormat =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
s.println("<row>");
|
||||
for (int col = 0; col < db.header.dsCount; col++) {
|
||||
s.print("<v> ");
|
||||
|
||||
while (counter++ < rowCount) {
|
||||
row++;
|
||||
double value = db.rrdFile.readDouble();
|
||||
|
||||
if (row == rowCount) {
|
||||
row = 0;
|
||||
|
||||
db.rrdFile.seek(dataOffset);
|
||||
// NumberFormat doesn't know how to handle NaN
|
||||
if (Double.isNaN(value)) {
|
||||
s.print("NaN");
|
||||
}
|
||||
else {
|
||||
s.print(numberFormat.format(value));
|
||||
}
|
||||
|
||||
long now = (lastUpdate - lastUpdate % (pdpCount * pdpStep))
|
||||
+ (timer * pdpCount * pdpStep);
|
||||
|
||||
timer++;
|
||||
|
||||
s.print("\t\t\t<!-- ");
|
||||
s.print(dateFormat.format(new Date(now * 1000)));
|
||||
s.print(" / ");
|
||||
s.print(now);
|
||||
s.print(" --> ");
|
||||
|
||||
s.println("<row>");
|
||||
for (int col = 0; col < db.header.dsCount; col++) {
|
||||
s.print("<v> ");
|
||||
|
||||
double value = db.rrdFile.readDouble();
|
||||
|
||||
// NumberFormat doesn't know how to handle NaN
|
||||
if (Double.isNaN(value)) {
|
||||
s.print("NaN");
|
||||
}
|
||||
else {
|
||||
s.print(numberFormat.format(value));
|
||||
}
|
||||
|
||||
s.print(" </v>");
|
||||
}
|
||||
|
||||
s.println("</row>");
|
||||
s.print(" </v>");
|
||||
}
|
||||
|
||||
s.println("\t\t</database>");
|
||||
s.println("\t</rra>");
|
||||
}
|
||||
catch (IOException e) { // Is the best thing to do here?
|
||||
throw new RuntimeException(e.getMessage());
|
||||
s.println("</row>");
|
||||
}
|
||||
|
||||
s.println("\t\t</database>");
|
||||
s.println("\t</rra>");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Getter for the field <code>values</code>.</p>
|
||||
*
|
||||
* @return an array of double.
|
||||
* @throws java.io.IOException if any.
|
||||
*/
|
||||
public double[][] getValues() throws IOException {
|
||||
public double[][] getValues() {
|
||||
if (values != null) {
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core.jrrd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ import java.io.PrintStream;
|
||||
*/
|
||||
public class CDPStatusBlock {
|
||||
|
||||
private static enum cdp_par_en {
|
||||
private enum cdp_par_en {
|
||||
CDP_val, CDP_unkn_pdp_cnt, CDP_hw_intercept, CDP_hw_last_intercept, CDP_hw_slope,
|
||||
CDP_hw_last_slope, CDP_null_count,
|
||||
CDP_last_null_count, CDP_primary_val, CDP_secondary_val
|
||||
@@ -27,7 +26,7 @@ public class CDPStatusBlock {
|
||||
final double secondary_value;
|
||||
final double primary_value;
|
||||
|
||||
CDPStatusBlock(RRDFile file) throws IOException {
|
||||
CDPStatusBlock(RRDFile file) {
|
||||
//Should read MAX_CDP_PAR_EN = 10
|
||||
//Size should be 0x50
|
||||
offset = file.getFilePointer();
|
||||
|
||||
@@ -2,25 +2,25 @@ package org.rrd4j.core.jrrd;
|
||||
|
||||
interface Constants {
|
||||
/** Constant <code>DS_NAM_SIZE=20</code> */
|
||||
final int DS_NAM_SIZE = 20;
|
||||
int DS_NAM_SIZE = 20;
|
||||
/** Constant <code>DST_SIZE=20</code> */
|
||||
final int DST_SIZE = 20;
|
||||
int DST_SIZE = 20;
|
||||
/** Constant <code>CF_NAM_SIZE=20</code> */
|
||||
final int CF_NAM_SIZE = 20;
|
||||
int CF_NAM_SIZE = 20;
|
||||
/** Constant <code>LAST_DS_LEN=30</code> */
|
||||
final int LAST_DS_LEN = 30;
|
||||
int LAST_DS_LEN = 30;
|
||||
/** Constant <code>COOKIE="RRD"</code> */
|
||||
static final String COOKIE = "RRD";
|
||||
String COOKIE = "RRD";
|
||||
/** Constant <code>MAX_SUPPORTED_VERSION=3</code> */
|
||||
public static final int MAX_SUPPORTED_VERSION = 3;
|
||||
int MAX_SUPPORTED_VERSION = 3;
|
||||
/** Constant <code>UNDEFINED_VERSION="UNDEF"</code> */
|
||||
public static final String UNDEFINED_VERSION = "UNDEF";
|
||||
String UNDEFINED_VERSION = "UNDEF";
|
||||
/** Constant <code>UNDEFINED_VERSION_AS_INT=-1</code> */
|
||||
public static final int UNDEFINED_VERSION_AS_INT = -1;
|
||||
int UNDEFINED_VERSION_AS_INT = -1;
|
||||
/** Constant <code>VERSION_WITH_LAST_UPDATE_SEC=3</code> */
|
||||
public static int VERSION_WITH_LAST_UPDATE_SEC = 3;
|
||||
int VERSION_WITH_LAST_UPDATE_SEC = 3;
|
||||
/** Constant <code>FLOAT_COOKIE=8.642135E130</code> */
|
||||
static final double FLOAT_COOKIE = 8.642135E130;
|
||||
double FLOAT_COOKIE = 8.642135E130;
|
||||
/** Constant <code>SIZE_OF_DOUBLE=8</code> */
|
||||
public static final int SIZE_OF_DOUBLE = 8;
|
||||
int SIZE_OF_DOUBLE = 8;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core.jrrd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
@@ -12,7 +11,7 @@ import java.text.NumberFormat;
|
||||
*/
|
||||
public class DataSource {
|
||||
|
||||
private static enum ds_param_en { DS_mrhb_cnt, DS_min_val, DS_max_val, DS_cde }
|
||||
private enum ds_param_en { DS_mrhb_cnt, DS_min_val, DS_max_val, DS_cde }
|
||||
|
||||
private final long offset;
|
||||
private final long size;
|
||||
@@ -24,7 +23,7 @@ public class DataSource {
|
||||
// initialized during RRDatabase construction
|
||||
private PDPStatusBlock pdpStatusBlock;
|
||||
|
||||
DataSource(RRDFile file) throws IOException {
|
||||
DataSource(RRDFile file) {
|
||||
|
||||
offset = file.getFilePointer();
|
||||
name = file.readString(Constants.DS_NAM_SIZE);
|
||||
@@ -37,7 +36,7 @@ public class DataSource {
|
||||
size = file.getFilePointer() - offset;
|
||||
}
|
||||
|
||||
void loadPDPStatusBlock(RRDFile file) throws IOException {
|
||||
void loadPDPStatusBlock(RRDFile file) {
|
||||
pdpStatusBlock = new PDPStatusBlock(file);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.rrd4j.core.jrrd;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Instances of this class model the primary data point status from an RRD file.
|
||||
*
|
||||
@@ -10,14 +8,14 @@ import java.io.IOException;
|
||||
*/
|
||||
public class PDPStatusBlock {
|
||||
|
||||
private long offset;
|
||||
private long size;
|
||||
String lastReading;
|
||||
int unknownSeconds;
|
||||
double value;
|
||||
private static enum pdp_par_en {PDP_unkn_sec_cnt, PDP_val};
|
||||
private final long offset;
|
||||
private final long size;
|
||||
final String lastReading;
|
||||
final int unknownSeconds;
|
||||
final double value;
|
||||
private enum pdp_par_en {PDP_unkn_sec_cnt, PDP_val}
|
||||
|
||||
PDPStatusBlock(RRDFile file) throws IOException {
|
||||
PDPStatusBlock(RRDFile file) {
|
||||
|
||||
offset = file.getFilePointer();
|
||||
lastReading = file.readString(Constants.LAST_DS_LEN);
|
||||
|
||||
@@ -64,7 +64,7 @@ class RRDFile implements Constants {
|
||||
if (!ok) {
|
||||
try {
|
||||
close();
|
||||
} catch (Throwable ignored) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
// and then rethrow
|
||||
}
|
||||
@@ -134,15 +134,15 @@ class RRDFile implements Constants {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
double readDouble() throws IOException {
|
||||
double readDouble() {
|
||||
return mappedByteBuffer.getDouble();
|
||||
}
|
||||
|
||||
int readInt() throws IOException {
|
||||
int readInt() {
|
||||
return mappedByteBuffer.getInt();
|
||||
}
|
||||
|
||||
int readLong() throws IOException {
|
||||
int readLong() {
|
||||
if(longSize == 4) {
|
||||
return mappedByteBuffer.getInt();
|
||||
}
|
||||
@@ -151,20 +151,20 @@ class RRDFile implements Constants {
|
||||
}
|
||||
}
|
||||
|
||||
String readString(int maxLength) throws IOException {
|
||||
String readString(int maxLength) {
|
||||
byte[] array = new byte[maxLength];
|
||||
mappedByteBuffer.get(array);
|
||||
|
||||
return new String(array, 0, maxLength).trim();
|
||||
}
|
||||
|
||||
void skipBytes(int n) throws IOException {
|
||||
void skipBytes(int n) {
|
||||
mappedByteBuffer.position(mappedByteBuffer.position() + n);
|
||||
}
|
||||
|
||||
int align(int boundary) throws IOException {
|
||||
int align(int boundary) {
|
||||
|
||||
int skip = (int) (boundary - (mappedByteBuffer.position() % boundary)) % boundary;
|
||||
int skip = (boundary - (mappedByteBuffer.position() % boundary)) % boundary;
|
||||
|
||||
if (skip != 0) {
|
||||
mappedByteBuffer.position(mappedByteBuffer.position() + skip);
|
||||
@@ -173,15 +173,15 @@ class RRDFile implements Constants {
|
||||
return skip;
|
||||
}
|
||||
|
||||
int align() throws IOException {
|
||||
int align() {
|
||||
return align(alignment);
|
||||
}
|
||||
|
||||
long info() throws IOException {
|
||||
long info() {
|
||||
return mappedByteBuffer.position();
|
||||
}
|
||||
|
||||
long getFilePointer() throws IOException {
|
||||
long getFilePointer() {
|
||||
return mappedByteBuffer.position();
|
||||
}
|
||||
|
||||
@@ -191,13 +191,13 @@ class RRDFile implements Constants {
|
||||
}
|
||||
}
|
||||
|
||||
void read(ByteBuffer bb) throws IOException{
|
||||
void read(ByteBuffer bb) {
|
||||
int count = bb.remaining();
|
||||
bb.put((ByteBuffer) mappedByteBuffer.duplicate().limit(mappedByteBuffer.position() + count));
|
||||
mappedByteBuffer.position(mappedByteBuffer.position() + count);
|
||||
}
|
||||
|
||||
UnivalArray getUnivalArray(int size) throws IOException {
|
||||
UnivalArray getUnivalArray(int size) {
|
||||
return new UnivalArray(this, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +63,10 @@ public class RRDatabase implements Closeable {
|
||||
rrdFile = new RRDFile(file);
|
||||
header = new Header(rrdFile);
|
||||
|
||||
nameindex = new HashMap<String, Integer>(header.dsCount);
|
||||
nameindex = new HashMap<>(header.dsCount);
|
||||
|
||||
// Load the data sources
|
||||
dataSources = new ArrayList<DataSource>(header.dsCount);
|
||||
dataSources = new ArrayList<>(header.dsCount);
|
||||
|
||||
for (int i = 0; i < header.dsCount; i++) {
|
||||
DataSource ds = new DataSource(rrdFile);
|
||||
@@ -75,7 +75,7 @@ public class RRDatabase implements Closeable {
|
||||
}
|
||||
|
||||
// Load the archives
|
||||
archives = new ArrayList<Archive>(header.rraCount);
|
||||
archives = new ArrayList<>(header.rraCount);
|
||||
|
||||
for (int i = 0; i < header.rraCount; i++) {
|
||||
Archive archive = new Archive(this);
|
||||
@@ -214,7 +214,7 @@ public class RRDatabase implements Closeable {
|
||||
|
||||
ArrayList<Archive> getArchiveList(ConsolidationFunctionType type) {
|
||||
|
||||
ArrayList<Archive> subset = new ArrayList<Archive>();
|
||||
ArrayList<Archive> subset = new ArrayList<>();
|
||||
|
||||
for (Archive archive : archives) {
|
||||
if (archive.getType().equals(type)) {
|
||||
@@ -449,7 +449,7 @@ public class RRDatabase implements Closeable {
|
||||
* Outputs the content of the database to the given print stream
|
||||
* as a stream of XML. The XML format is almost identical to that produced by
|
||||
* <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/manual/rrddump.html">rrdtool dump</a>
|
||||
*
|
||||
* <p>
|
||||
* A flush is issued at the end of the XML generation, so auto flush of the PrintStream can be set to false
|
||||
*
|
||||
* @param s the PrintStream to send the XML to.
|
||||
@@ -470,7 +470,7 @@ public class RRDatabase implements Closeable {
|
||||
s.print("\t<lastupdate> ");
|
||||
s.print(lastUpdate.getTime() / 1000);
|
||||
s.print(" </lastupdate> <!-- ");
|
||||
s.print(lastUpdate.toString());
|
||||
s.print(lastUpdate);
|
||||
s.println(" -->");
|
||||
s.println();
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.core.jrrd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@@ -19,9 +18,8 @@ class UnivalArray {
|
||||
*
|
||||
* @param file the RRdFile
|
||||
* @param size the numer of elements in the array
|
||||
* @throws java.io.IOException if any.
|
||||
*/
|
||||
public UnivalArray(RRDFile file, int size) throws IOException {
|
||||
public UnivalArray(RRDFile file, int size) {
|
||||
sizeoflong = file.getBits();
|
||||
buffer = ByteBuffer.allocate(size * 8);
|
||||
if(file.isBigEndian())
|
||||
|
||||
@@ -4,8 +4,6 @@ import org.rrd4j.core.Util;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
@@ -44,12 +42,6 @@ public class Epoch extends JFrame {
|
||||
private final SimpleDateFormat[] parsers = new SimpleDateFormat[supportedFormats.length];
|
||||
private final String helpText;
|
||||
|
||||
private final Timer timer = new Timer(1000, new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
showTimestamp();
|
||||
}
|
||||
});
|
||||
|
||||
private final JLabel topLabel = new JLabel("Enter timestamp or readable date:");
|
||||
private final JTextField inputField = new JTextField(25);
|
||||
private final JButton convertButton = new JButton("Convert");
|
||||
@@ -73,6 +65,7 @@ public class Epoch extends JFrame {
|
||||
tooltipBuff.append("Copyright (c) 2013-2020 The RRD4J Authors. Copyright (c) 2001-2005 Sasa Markovic and Ciaran Treanor. Copyright (c) 2013 The OpenNMS Group, Inc. Licensed under the Apache License, Version 2.0.</html>");
|
||||
helpText = tooltipBuff.toString();
|
||||
constructUI();
|
||||
Timer timer = new Timer(1000, e -> showTimestamp());
|
||||
timer.start();
|
||||
}
|
||||
|
||||
@@ -83,17 +76,10 @@ public class Epoch extends JFrame {
|
||||
c.add(inputField, BorderLayout.WEST);
|
||||
c.add(convertButton, BorderLayout.CENTER);
|
||||
convertButton.setToolTipText(helpText);
|
||||
convertButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
convert();
|
||||
}
|
||||
});
|
||||
convertButton.addActionListener(e -> convert());
|
||||
c.add(helpButton, BorderLayout.EAST);
|
||||
helpButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JOptionPane.showMessageDialog(helpButton, helpText, "Epoch Help", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
});
|
||||
helpButton.addActionListener(
|
||||
e -> JOptionPane.showMessageDialog(helpButton, helpText, "Epoch Help", JOptionPane.INFORMATION_MESSAGE));
|
||||
inputField.requestFocus();
|
||||
getRootPane().setDefaultButton(convertButton);
|
||||
setResizable(false);
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.time.Instant;
|
||||
* Class which parses at-style time specification (described in detail on the rrdfetch man page),
|
||||
* used in all RRDTool commands. This code is in most parts just a java port of Tobi's parsetime.c
|
||||
* code.
|
||||
*
|
||||
* <p>
|
||||
* For years written with two digits, any year before 38 will be post 2000.
|
||||
*
|
||||
*/
|
||||
@@ -14,8 +14,8 @@ public class TimeParser {
|
||||
private static final int PREVIOUS_OP = -1;
|
||||
|
||||
TimeToken token;
|
||||
TimeScanner scanner;
|
||||
TimeSpec spec;
|
||||
final TimeScanner scanner;
|
||||
final TimeSpec spec;
|
||||
|
||||
int op = TimeToken.PLUS;
|
||||
int prev_multiplier = -1;
|
||||
@@ -104,7 +104,7 @@ public class TimeParser {
|
||||
* the scanner state to what it was at entry, and returns without setting anything.
|
||||
*/
|
||||
private void timeOfDay() {
|
||||
int hour = 0;
|
||||
int hour;
|
||||
int minute = 0;
|
||||
/* save token status in case we must abort */
|
||||
scanner.saveState();
|
||||
@@ -183,8 +183,8 @@ public class TimeParser {
|
||||
|
||||
private void day() {
|
||||
long mday = 0;
|
||||
long wday = 0;
|
||||
long mon = 0;
|
||||
long wday;
|
||||
long mon;
|
||||
long year = spec.year;
|
||||
switch (token.token_id) {
|
||||
case TimeToken.YESTERDAY:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.rrd4j.core.timespec;
|
||||
|
||||
class TimeScanner {
|
||||
private String dateString;
|
||||
private final String dateString;
|
||||
|
||||
private int pos, pos_save;
|
||||
private TimeToken token, token_save;
|
||||
@@ -108,7 +108,7 @@ class TimeScanner {
|
||||
}
|
||||
|
||||
TimeToken nextToken() {
|
||||
StringBuilder buffer = new StringBuilder("");
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
while (pos < dateString.length()) {
|
||||
char c = dateString.charAt(pos++);
|
||||
if (Character.isWhitespace(c) || c == '_' || c == ',') {
|
||||
|
||||
@@ -20,7 +20,7 @@ public class TimeSpec {
|
||||
int wday;
|
||||
int dyear, dmonth, dday, dhour, dmin, dsec;
|
||||
|
||||
String dateString;
|
||||
final String dateString;
|
||||
|
||||
TimeSpec context;
|
||||
|
||||
@@ -135,4 +135,3 @@ public class TimeSpec {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class Aggregates {
|
||||
public String dump() {
|
||||
StringBuilder bl = new StringBuilder();
|
||||
for(ConsolFun cf: ConsolFun.values()) {
|
||||
bl.append(cf.name() + '=' + Util.formatDouble(this.getAggregate(cf)));
|
||||
bl.append(cf.name()).append('=').append(Util.formatDouble(this.getAggregate(cf)));
|
||||
}
|
||||
return bl.toString();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class Aggregator {
|
||||
private final long timestamps[], step;
|
||||
private final long[] timestamps;
|
||||
private final long step;
|
||||
private final double[] values;
|
||||
|
||||
Aggregator(long[] timestamps, double[] values) {
|
||||
@@ -60,13 +61,13 @@ class Aggregator {
|
||||
}
|
||||
|
||||
double getPercentile(long tStart, long tEnd, double percentile) {
|
||||
List<Double> valueList = new ArrayList<Double>();
|
||||
List<Double> valueList = new ArrayList<>();
|
||||
// create a list of included datasource values (different from NaN)
|
||||
for (int i = 0; i < timestamps.length; i++) {
|
||||
long left = Math.max(timestamps[i] - step, tStart);
|
||||
long right = Math.min(timestamps[i], tEnd);
|
||||
if (right > left && !Double.isNaN(values[i])) {
|
||||
valueList.add(Double.valueOf(values[i]));
|
||||
valueList.add(values[i]);
|
||||
}
|
||||
}
|
||||
// create an array to work with
|
||||
@@ -74,7 +75,7 @@ class Aggregator {
|
||||
if (count > 1) {
|
||||
double[] valuesCopy = new double[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
valuesCopy[i] = valueList.get(i).doubleValue();
|
||||
valuesCopy[i] = valueList.get(i);
|
||||
}
|
||||
// sort array
|
||||
Arrays.sort(valuesCopy);
|
||||
@@ -90,4 +91,3 @@ class Aggregator {
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import java.util.Date;
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CubicSplineInterpolator extends Plottable {
|
||||
private double[] x;
|
||||
private double[] y;
|
||||
private final double[] x;
|
||||
private final double[] y;
|
||||
|
||||
// second derivates come here
|
||||
private double[] y2;
|
||||
@@ -104,6 +104,7 @@ public class CubicSplineInterpolator extends Plottable {
|
||||
for (int i = 0; i < x.length - 1 && ok; i++) {
|
||||
if (x[i] >= x[i + 1] || Double.isNaN(y[i])) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class DataProcessor implements DataHolder {
|
||||
|
||||
private long tStart;
|
||||
private long tEnd;
|
||||
private long timestamps[];
|
||||
private long[] timestamps;
|
||||
private long lastRrdArchiveUpdateTime = 0;
|
||||
// this will be adjusted later
|
||||
private long step = 0;
|
||||
@@ -74,7 +74,7 @@ public class DataProcessor implements DataHolder {
|
||||
private TimeZone tz = TimeZone.getDefault();
|
||||
|
||||
// the order is important, ordinary HashMap is unordered
|
||||
private Map<String, Source> sources = new LinkedHashMap<String, Source>();
|
||||
private final Map<String, Source> sources = new LinkedHashMap<>();
|
||||
|
||||
private Def[] defSources;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class DataProcessor implements DataHolder {
|
||||
* 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.
|
||||
*
|
||||
* <p>
|
||||
* It use the time zone for starting calendar date.
|
||||
*
|
||||
* @param gc1 Starting Calendar date
|
||||
@@ -365,7 +365,7 @@ public class DataProcessor implements DataHolder {
|
||||
|
||||
/**
|
||||
* This method is just an alias for {@link #getPercentile(String)} method.
|
||||
*
|
||||
* <p>
|
||||
* Used by ISPs which charge for bandwidth utilization on a "95th percentile" basis.<p>
|
||||
*
|
||||
* The 95th percentile is the highest source value left when the top 5% of a numerically sorted set
|
||||
@@ -430,7 +430,7 @@ public class DataProcessor implements DataHolder {
|
||||
* @return array of datasource names
|
||||
*/
|
||||
public String[] getSourceNames() {
|
||||
return sources.keySet().toArray(new String[sources.keySet().size()]);
|
||||
return sources.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,7 +570,7 @@ public class DataProcessor implements DataHolder {
|
||||
/**
|
||||
* Creates a datasource that performs a percentile calculation on an
|
||||
* another named datasource to yield a single value.
|
||||
*
|
||||
* <p>
|
||||
* Requires that the other datasource has already been defined; otherwise, it'll
|
||||
* end up with no data
|
||||
*
|
||||
@@ -588,7 +588,7 @@ public class DataProcessor implements DataHolder {
|
||||
/**
|
||||
* Creates a datasource that performs a variable calculation on an
|
||||
* another named datasource to yield a single combined timestamp/value.
|
||||
*
|
||||
* <p>
|
||||
* Requires that the other datasource has already been defined; otherwise, it'll
|
||||
* end up with no data
|
||||
*
|
||||
@@ -606,7 +606,7 @@ public class DataProcessor implements DataHolder {
|
||||
/**
|
||||
* Creates a datasource that performs a variable calculation on an
|
||||
* another named datasource to yield a single combined timestamp/value.
|
||||
*
|
||||
* <p>
|
||||
* Requires that the other datasource has already been defined; otherwise, it'll
|
||||
* end up with no data
|
||||
*
|
||||
@@ -970,7 +970,7 @@ public class DataProcessor implements DataHolder {
|
||||
// PRIVATE METHODS
|
||||
|
||||
private void extractDefs() {
|
||||
defSources = sources.values().stream().filter(s -> s instanceof Def).toArray(Def[]::new);
|
||||
defSources = sources.values().stream().filter(Def.class::isInstance).toArray(Def[]::new);
|
||||
}
|
||||
|
||||
private void fetchRrdData() throws IOException {
|
||||
@@ -1006,7 +1006,7 @@ public class DataProcessor implements DataHolder {
|
||||
}
|
||||
if (!defSources[i].isLoaded()) {
|
||||
// not fetched yet
|
||||
Set<String> dsNames = new HashSet<String>();
|
||||
Set<String> dsNames = new HashSet<>();
|
||||
dsNames.add(defSources[i].getDsName());
|
||||
// look for all other datasources with the same path and the same consolidation function
|
||||
for (int j = i + 1; j < defSources.length; j++) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.rrd4j.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.rrd4j.ConsolFun;
|
||||
@@ -36,7 +35,7 @@ class Def extends Source {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
URI getCanonicalUri() throws IOException {
|
||||
URI getCanonicalUri() {
|
||||
return rrdUri;
|
||||
}
|
||||
|
||||
@@ -52,7 +51,7 @@ class Def extends Source {
|
||||
return backend;
|
||||
}
|
||||
|
||||
boolean isCompatibleWith(Def def) throws IOException {
|
||||
boolean isCompatibleWith(Def def) {
|
||||
return getCanonicalUri().equals(def.getCanonicalUri()) &&
|
||||
getConsolFun() == def.consolFun &&
|
||||
((backend == null && def.backend == null) ||
|
||||
|
||||
@@ -16,5 +16,5 @@ public interface IPlottable {
|
||||
* @param timestamp Timestamp in seconds for the datapoint.
|
||||
* @return Double value of the datapoint.
|
||||
*/
|
||||
public double getValue(long timestamp);
|
||||
double getValue(long timestamp);
|
||||
}
|
||||
|
||||
@@ -48,14 +48,14 @@ public class LinearInterpolator extends Plottable {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
LINEAR,
|
||||
REGRESSION;
|
||||
REGRESSION
|
||||
}
|
||||
|
||||
private int lastIndexUsed = 0;
|
||||
private Method interpolationMethod = Method.LINEAR;
|
||||
|
||||
private long[] timestamps;
|
||||
private double[] values;
|
||||
private final long[] timestamps;
|
||||
private final double[] values;
|
||||
|
||||
// used only if INTERPOLATE_BESTFIT is specified
|
||||
double b0 = Double.NaN;
|
||||
@@ -117,6 +117,7 @@ public class LinearInterpolator extends Plottable {
|
||||
for (int i = 0; i < timestamps.length - 1 && ok; i++) {
|
||||
if (timestamps[i] >= timestamps[i + 1]) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
|
||||
@@ -41,7 +41,7 @@ class Normalizer {
|
||||
long t2 = Math.min(rawTimestamps[rawSeg], timestamps[fillSeg]);
|
||||
if (t1 < t2) {
|
||||
values[fillSeg] = Util.sum(values[fillSeg], (t2 - t1) * rawValues[rawSeg]);
|
||||
weights[fillSeg] = Util.sum(weights[fillSeg], (double)(t2 - t1));
|
||||
weights[fillSeg] = Util.sum(weights[fillSeg], (t2 - t1));
|
||||
}
|
||||
else {
|
||||
overlap = false;
|
||||
|
||||
@@ -396,7 +396,7 @@ class RpnCalculator {
|
||||
@Override
|
||||
void do_method(RpnCalculator c, State s) {
|
||||
TimeZone tz = s.getTimeZone();
|
||||
c.push((double)(c.timestamps[s.slot] + ((long) tz.getOffset(c.timestamps[s.slot]) / 1000D)));
|
||||
c.push(c.timestamps[s.slot] + ((long) tz.getOffset(c.timestamps[s.slot]) / 1000D));
|
||||
}
|
||||
},
|
||||
TKN_YEAR("YEAR") {
|
||||
@@ -569,7 +569,7 @@ class RpnCalculator {
|
||||
}
|
||||
|
||||
/* the real calculation */
|
||||
double val = Double.NaN;
|
||||
double val;
|
||||
|
||||
/* the info on the datasource */
|
||||
double[] vals = c.dataProcessor.getValues(c.tokens[s.rpi-1].variable);
|
||||
@@ -615,7 +615,7 @@ class RpnCalculator {
|
||||
val = Double.NaN;
|
||||
if (s.token.id == TKN_PREDICT) { /* the average */
|
||||
if (count > 0) {
|
||||
val = sum / (double) count;
|
||||
val = sum / count;
|
||||
}
|
||||
} else {
|
||||
if (count > 1) { /* the sigma case */
|
||||
@@ -649,14 +649,14 @@ class RpnCalculator {
|
||||
private static final PerfectStringHash perfect;
|
||||
static
|
||||
{
|
||||
List<String> tokenStrings = new ArrayList<String>(Token_Symbol.values().length);
|
||||
List<String> tokenStrings = new ArrayList<>(Token_Symbol.values().length);
|
||||
for(Token_Symbol s: Token_Symbol.values()) {
|
||||
if(! s.token_string.isEmpty()) {
|
||||
tokenStrings.add(s.token_string);
|
||||
}
|
||||
}
|
||||
|
||||
String[] array = tokenStrings.toArray(new String[tokenStrings.size()]);
|
||||
String[] array = tokenStrings.toArray(new String[0]);
|
||||
perfect = new PerfectStringHash(array);
|
||||
symbols = new Token_Symbol[tokenStrings.size()];
|
||||
for(Token_Symbol s: Token_Symbol.values()) {
|
||||
@@ -683,7 +683,7 @@ class RpnCalculator {
|
||||
this.sourceName = sourceName;
|
||||
this.dataProcessor = dataProcessor;
|
||||
this.timestamps = dataProcessor.getTimestamps();
|
||||
this.timeStep = (double)(timestamps[1] - timestamps[0]);
|
||||
this.timeStep = (timestamps[1] - timestamps[0]);
|
||||
this.calculatedValues = new double[timestamps.length];
|
||||
this.sourcesNames = Arrays.asList(dataProcessor.getSourceNames());
|
||||
String[] tokensString = rpnExpression.split(" *, *");
|
||||
@@ -767,7 +767,7 @@ class RpnCalculator {
|
||||
|
||||
private static final class RpnStack {
|
||||
private static final int MAX_STACK_SIZE = 1000;
|
||||
private double[] stack = new double[MAX_STACK_SIZE];
|
||||
private final double[] stack = new double[MAX_STACK_SIZE];
|
||||
private int pos = 0;
|
||||
|
||||
void push(double x) {
|
||||
|
||||
@@ -34,7 +34,7 @@ abstract class Source {
|
||||
* @param tStart
|
||||
* @param tEnd
|
||||
* @return
|
||||
* @deprecated This method is deprecated. Uses instance of {@link org.rrd4j.data.Variable}, used with DataProcessor.addDatasource(String, String, Variable)
|
||||
* @deprecated This method is deprecated. Uses instance of {@link org.rrd4j.data.Variable}, used with {@link org.rrd4j.data.DataProcessor#addDatasource(String, String, Variable)}
|
||||
*/
|
||||
@Deprecated
|
||||
Aggregates getAggregates(long tStart, long tEnd) {
|
||||
@@ -47,7 +47,7 @@ abstract class Source {
|
||||
* @param tEnd
|
||||
* @param percentile
|
||||
* @return
|
||||
* @deprecated This method is deprecated. Uses instance of {@link org.rrd4j.data.Variable.PERCENTILE}, used with DataProcessor.addDatasource(String, String, Variable)
|
||||
* @deprecated This method is deprecated. Uses instance of {@link org.rrd4j.data.Variable.PERCENTILE}, used with {@link org.rrd4j.data.DataProcessor#addDatasource(String, String, Variable)}
|
||||
*/
|
||||
@Deprecated
|
||||
double getPercentile(long tStart, long tEnd, double percentile) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.rrd4j.core.Util;
|
||||
|
||||
/**
|
||||
* An abstract class to help extract single value from a set of value (VDEF in rrdtool)
|
||||
*
|
||||
* <p>
|
||||
* It can be used to add new fancy statistical calculation with rrd values
|
||||
*
|
||||
*/
|
||||
@@ -30,7 +30,7 @@ public abstract class Variable {
|
||||
public String toString() {
|
||||
return "Value [value=" + value + ", timestamp=" + timestamp + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static final Value INVALIDVALUE = new Value(0, Double.NaN);
|
||||
|
||||
@@ -101,7 +101,7 @@ public abstract class Variable {
|
||||
|
||||
/**
|
||||
* This method is call with the needed values, extracted from the datasource to do the calculation.
|
||||
*
|
||||
* <p>
|
||||
* Value is to be filled with both the double value and a possible timestamp, when it's used to find
|
||||
* a specific point
|
||||
*
|
||||
@@ -111,7 +111,7 @@ public abstract class Variable {
|
||||
* @param end the end of the period
|
||||
* @return a filled Value object
|
||||
*/
|
||||
protected abstract Value fill(long timestamps[], double[] values, long start, long end);
|
||||
protected abstract Value fill(long[] timestamps, double[] values, long start, long end);
|
||||
|
||||
/**
|
||||
* Find the first valid data point and it's timestamp
|
||||
@@ -266,8 +266,8 @@ public abstract class Variable {
|
||||
*
|
||||
*/
|
||||
static final class PercentElem {
|
||||
long timestamp;
|
||||
double value;
|
||||
final long timestamp;
|
||||
final double value;
|
||||
|
||||
PercentElem(int pos, long timestamp, double value) {
|
||||
this.timestamp = timestamp;
|
||||
@@ -305,7 +305,7 @@ public abstract class Variable {
|
||||
*/
|
||||
static final class ComparPercentElemen implements Comparator<PercentElem>, Serializable {
|
||||
@Override
|
||||
public final int compare(PercentElem arg0, PercentElem arg1) {
|
||||
public int compare(PercentElem arg0, PercentElem arg1) {
|
||||
if (Double.isNaN(arg0.value) && Double.isNaN(arg1.value))
|
||||
return Long.signum(arg0.timestamp - arg1.timestamp);
|
||||
else if (Double.isNaN(arg0.value))
|
||||
@@ -346,7 +346,7 @@ public abstract class Variable {
|
||||
@Override
|
||||
protected Value fill(long[] timestamps, double[] values, long start, long end) {
|
||||
// valuesSet will be a set with NaN packet at the start
|
||||
SortedSet<PercentElem> valuesSet = new TreeSet<PercentElem>(new ComparPercentElemen());
|
||||
SortedSet<PercentElem> valuesSet = new TreeSet<>(new ComparPercentElemen());
|
||||
for (int i = 0 ; i < values.length ; i++) {
|
||||
valuesSet.add(new PercentElem(i, timestamps[i], values[i]));
|
||||
}
|
||||
@@ -356,7 +356,7 @@ public abstract class Variable {
|
||||
valuesSet = valuesSet.tailSet(new PercentElem(0, 0, Double.NEGATIVE_INFINITY ));
|
||||
}
|
||||
|
||||
PercentElem[] element = (PercentElem[]) valuesSet.toArray(new PercentElem[valuesSet.size()]);
|
||||
PercentElem[] element = valuesSet.toArray(new PercentElem[0]);
|
||||
int pos = Math.round(percentile * (element.length - 1) / 100);
|
||||
// if we have anything left...
|
||||
if (pos >= 0) {
|
||||
@@ -395,15 +395,13 @@ public abstract class Variable {
|
||||
double SUMxx = 0.0;
|
||||
double lslslope;
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
double value = values[i];
|
||||
|
||||
for (double value : values) {
|
||||
if (!Double.isNaN(value)) {
|
||||
cnt++;
|
||||
|
||||
SUMx += lslstep;
|
||||
SUMxx += lslstep * lslstep;
|
||||
SUMy += value;
|
||||
SUMy += value;
|
||||
SUMxy += lslstep * value;
|
||||
|
||||
}
|
||||
@@ -438,15 +436,13 @@ public abstract class Variable {
|
||||
double lslslope;
|
||||
double lslint;
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
double value = values[i];
|
||||
|
||||
for (double value : values) {
|
||||
if (!Double.isNaN(value)) {
|
||||
cnt++;
|
||||
|
||||
SUMx += lslstep;
|
||||
SUMxx += lslstep * lslstep;
|
||||
SUMy += value;
|
||||
SUMy += value;
|
||||
SUMxy += lslstep * value;
|
||||
}
|
||||
lslstep++;
|
||||
@@ -481,15 +477,13 @@ public abstract class Variable {
|
||||
double SUMyy = 0.0;
|
||||
double lslcorrel;
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
double value = values[i];
|
||||
|
||||
for (double value : values) {
|
||||
if (!Double.isNaN(value)) {
|
||||
cnt++;
|
||||
|
||||
SUMx += lslstep;
|
||||
SUMxx += lslstep * lslstep;
|
||||
SUMy += value;
|
||||
SUMy += value;
|
||||
SUMxy += lslstep * value;
|
||||
SUMyy += value * value;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public class ConstantArea extends Area {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
void assignValues(DataProcessor dproc) {
|
||||
values = new double[dproc.getTimestamps().length];
|
||||
Arrays.fill(values, value);
|
||||
|
||||
@@ -14,6 +14,7 @@ public class ConstantLine extends Line {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
void assignValues(DataProcessor dproc) {
|
||||
values = new double[dproc.getTimestamps().length];
|
||||
Arrays.fill(values, value);
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Arrays;
|
||||
*/
|
||||
public interface DownSampler {
|
||||
|
||||
public class DataSet {
|
||||
class DataSet {
|
||||
public final long[] timestamps;
|
||||
public final double[] values;
|
||||
public DataSet(long[] timestamps, double[] values) {
|
||||
@@ -25,6 +25,6 @@ public interface DownSampler {
|
||||
|
||||
}
|
||||
|
||||
public DataSet downsize(long[] timestamps, double[] values);
|
||||
DataSet downsize(long[] timestamps, double[] values);
|
||||
|
||||
}
|
||||
|
||||
@@ -50,5 +50,5 @@ public enum ElementsNames {
|
||||
/**
|
||||
* The y-axis color
|
||||
*/
|
||||
yaxis;
|
||||
yaxis
|
||||
}
|
||||
|
||||
@@ -8,12 +8,8 @@ import java.awt.Stroke;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
@@ -182,7 +178,7 @@ class ImageWorker {
|
||||
|
||||
// Some format can't manage 16M colors images
|
||||
// JPEG don't like transparency
|
||||
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equals(imgProvider.getMIMETypes()[0].toLowerCase())) {
|
||||
if (! imgProvider.canEncodeImage(outputImage) || "image/jpeg".equalsIgnoreCase(imgProvider.getMIMETypes()[0])) {
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
outputImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
@@ -208,15 +204,14 @@ class ImageWorker {
|
||||
}
|
||||
}
|
||||
|
||||
InputStream saveImage(String path, ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
void saveImage(String path, ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
makeImage(Paths.get(path).toFile(), writer, iwp);
|
||||
return new BufferedInputStream(new FileInputStream(path));
|
||||
}
|
||||
|
||||
InputStream getImageBytes(ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
byte[] getImageBytes(ImageWriter writer, ImageWriteParam iwp) throws IOException {
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream(IMG_BUFFER_CAPACITY)){
|
||||
makeImage(stream, writer, iwp);
|
||||
return new ByteArrayInputStream(stream.toByteArray());
|
||||
return stream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,14 @@ import java.util.List;
|
||||
class LegendComposer implements RrdGraphConstants {
|
||||
private final RrdGraphDef gdef;
|
||||
private final ImageWorker worker;
|
||||
private int legX, legY;
|
||||
private final int legX;
|
||||
private int legY;
|
||||
private final int legWidth;
|
||||
|
||||
private double interLegendSpace;
|
||||
private double leading;
|
||||
private double smallLeading;
|
||||
private double boxSpace;
|
||||
private final double interLegendSpace;
|
||||
private final double leading;
|
||||
private final double smallLeading;
|
||||
private final double boxSpace;
|
||||
|
||||
LegendComposer(RrdGraph rrdGraph, int legX, int legY, int legWidth) {
|
||||
this.gdef = rrdGraph.gdef;
|
||||
@@ -46,7 +47,7 @@ class LegendComposer implements RrdGraphConstants {
|
||||
private double width;
|
||||
private int spaceCount;
|
||||
private boolean noJustification;
|
||||
private List<CommentText> comments = new ArrayList<CommentText>();
|
||||
private final List<CommentText> comments = new ArrayList<>();
|
||||
|
||||
Line() {
|
||||
clear();
|
||||
|
||||
@@ -10,10 +10,10 @@ class Mapper {
|
||||
this.im = rrdGraph.im;
|
||||
pixieX = (double) im.xsize / (double) (im.end - im.start);
|
||||
if (!gdef.logarithmic) {
|
||||
pixieY = (double) im.ysize / (im.maxval - im.minval);
|
||||
pixieY = im.ysize / (im.maxval - im.minval);
|
||||
}
|
||||
else {
|
||||
pixieY = (double) im.ysize / (ValueAxisLogarithmic.log10(im.maxval) - ValueAxisLogarithmic.log10(im.minval));
|
||||
pixieY = im.ysize / (ValueAxisLogarithmic.log10(im.maxval) - ValueAxisLogarithmic.log10(im.minval));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,15 @@ class Mapper {
|
||||
this.im = im;
|
||||
pixieX = (double) im.xsize / (double) (im.end - im.start);
|
||||
if (!gdef.logarithmic) {
|
||||
pixieY = (double) im.ysize / (im.maxval - im.minval);
|
||||
pixieY = im.ysize / (im.maxval - im.minval);
|
||||
}
|
||||
else {
|
||||
pixieY = (double) im.ysize / (Math.log10(im.maxval) - Math.log10(im.minval));
|
||||
pixieY = im.ysize / (Math.log10(im.maxval) - Math.log10(im.minval));
|
||||
}
|
||||
}
|
||||
|
||||
int xtr(double mytime) {
|
||||
return (int) ((double) im.xorigin + pixieX * (mytime - im.start));
|
||||
return (int) (im.xorigin + pixieX * (mytime - im.start));
|
||||
}
|
||||
|
||||
int ytr(double value) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import org.rrd4j.data.DataProcessor;
|
||||
import org.rrd4j.data.IPlottable;
|
||||
|
||||
class PDef extends Source {
|
||||
private IPlottable plottable;
|
||||
private final IPlottable plottable;
|
||||
|
||||
PDef(String name, IPlottable plottable) {
|
||||
super(name);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.rrd4j.graph;
|
||||
|
||||
class PathIterator {
|
||||
private double[] y;
|
||||
private final double[] y;
|
||||
private int pos = 0;
|
||||
|
||||
PathIterator(double[] y) {
|
||||
|
||||
@@ -26,10 +26,12 @@ class PrintText extends CommentText {
|
||||
this.strftime = strftime;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isPrint() {
|
||||
return !includedInGraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
void resolveText(Locale l, DataProcessor dproc, ValueScaler valueScaler) {
|
||||
super.resolveText(l, dproc, valueScaler);
|
||||
Value v = dproc.getVariable(srcName);
|
||||
|
||||
@@ -7,6 +7,10 @@ import java.awt.Graphics;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Stroke;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
@@ -172,10 +176,27 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
|
||||
private void saveImage() throws IOException {
|
||||
if (! RrdGraphConstants.IN_MEMORY_IMAGE.equals(gdef.filename)) {
|
||||
info.stream = worker.saveImage(gdef.filename, writer, param);
|
||||
Path imgpath = Paths.get(gdef.filename);
|
||||
worker.saveImage(gdef.filename, writer, param);
|
||||
info.bytesSource = () -> {
|
||||
try {
|
||||
return Files.readAllBytes(imgpath);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to read image bytes", e);
|
||||
}
|
||||
};
|
||||
info.bytesCount = () -> {
|
||||
try {
|
||||
return (int) Files.size(imgpath);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to read image informations", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
info.stream = worker.getImageBytes(writer, param);
|
||||
byte[] content = worker.getImageBytes(writer, param);
|
||||
info.bytesSource = () -> Arrays.copyOf(content, content.length);
|
||||
info.bytesCount = () -> content.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,10 +269,9 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
worker.drawString(gdef.title, x, y, gdef.getFont(FONTTAG_TITLE), gdef.getColor(ElementsNames.font));
|
||||
}
|
||||
if (gdef.verticalLabel != null) {
|
||||
int x = PADDING_LEFT;
|
||||
int y = im.yorigin - im.ysize / 2 + (int) worker.getStringWidth(gdef.verticalLabel, gdef.getFont(FONTTAG_UNIT)) / 2;
|
||||
int ascent = (int) worker.getFontAscent(gdef.getFont(FONTTAG_UNIT));
|
||||
worker.transform(x, y, -Math.PI / 2);
|
||||
worker.transform(PADDING_LEFT, y, -Math.PI / 2);
|
||||
worker.drawString(gdef.verticalLabel, 0, ascent, gdef.getFont(FONTTAG_UNIT), gdef.getColor(ElementsNames.font));
|
||||
worker.reset();
|
||||
}
|
||||
@@ -375,8 +395,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
im.xorigin + im.xsize + 4,
|
||||
};
|
||||
double[] Xarrow_y = {
|
||||
im.yorigin - 3,
|
||||
im.yorigin + 0,
|
||||
im.yorigin - 3, im.yorigin,
|
||||
im.yorigin + 3,
|
||||
};
|
||||
worker.fillPolygon(Xarrow_x, im.yorigin + 3.0, Xarrow_y, arrowColor);
|
||||
@@ -428,7 +447,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
im.xorigin = 0;
|
||||
}
|
||||
else {
|
||||
im.xorigin = (int) (PADDING_LEFT + im.unitslength * getFontCharWidth(FontTag.UNIT));
|
||||
im.xorigin = (int) (PADDING_LEFT + im.unitslength * getFontCharWidth(FONTTAG_AXIS));
|
||||
}
|
||||
|
||||
if (!gdef.onlyGraph && gdef.verticalLabel != null) {
|
||||
@@ -452,7 +471,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
}
|
||||
else {
|
||||
im.xgif = PADDING_RIGHT + im.xsize + im.xorigin;
|
||||
im.ygif = im.yorigin + (int) (PADDING_PLOT * getFontHeight(FONTTAG_DEFAULT));
|
||||
im.ygif = im.yorigin + (int) (PADDING_PLOT * getFontHeight(FONTTAG_AXIS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,10 +585,10 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
}
|
||||
}
|
||||
else {
|
||||
im.minval = (double) im.ylabfact * im.ygridstep *
|
||||
Math.floor(im.minval / ((double) im.ylabfact * im.ygridstep));
|
||||
im.maxval = (double) im.ylabfact * im.ygridstep *
|
||||
Math.ceil(im.maxval / ((double) im.ylabfact * im.ygridstep));
|
||||
im.minval = im.ylabfact * im.ygridstep *
|
||||
Math.floor(im.minval / (im.ylabfact * im.ygridstep));
|
||||
im.maxval = im.ylabfact * im.ygridstep *
|
||||
Math.ceil(im.maxval / (im.ylabfact * im.ygridstep));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -658,7 +677,7 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
|
||||
private void fetchData() throws IOException {
|
||||
dproc = new DataProcessor(gdef.startTime, gdef.endTime);
|
||||
dproc.setPixelCount(im.xsize);
|
||||
dproc.setPixelCount(gdef.width);
|
||||
if (gdef.poolUsed) {
|
||||
dproc.setPoolUsed(gdef.poolUsed);
|
||||
dproc.setPool(gdef.getPool());
|
||||
|
||||
@@ -293,32 +293,32 @@ public interface RrdGraphConstants {
|
||||
/**
|
||||
* The file that contains font configuration searched in the class path. The default value is <code>/rrd4jfonts.properties</code>
|
||||
*/
|
||||
public static final String PROPERTYFONTSPROPERTIES = "org.rrd4j.fonts.properties";
|
||||
String PROPERTYFONTSPROPERTIES = "org.rrd4j.fonts.properties";
|
||||
/**
|
||||
* A possible URL to a configuration file.
|
||||
*/
|
||||
public static final String PROPERTYFONTSURL = "org.rrd4j.fonts.properties.url";
|
||||
String PROPERTYFONTSURL = "org.rrd4j.fonts.properties.url";
|
||||
/**
|
||||
* The name of the plain font, used to define the {@link #DEFAULT_SMALL_FONT} and the {@link GATOR_FONT}. To be found in the classpath.
|
||||
* The name of the plain font, used to define the {@link #DEFAULT_SMALL_FONT} and the {@link RrdGraphDef#GATOR_FONT}. To be found in the classpath.
|
||||
*/
|
||||
public static final String PROPERTYFONTPLAIN = "org.rrd4j.font.plain";
|
||||
String PROPERTYFONTPLAIN = "org.rrd4j.font.plain";
|
||||
/**
|
||||
* The name of the bold font, used to define the {@link #DEFAULT_LARGE_FONT}. To be found in the classpath.
|
||||
*/
|
||||
public static final String PROPERTYFONTBOLD = "org.rrd4j.font.bold";
|
||||
String PROPERTYFONTBOLD = "org.rrd4j.font.bold";
|
||||
/**
|
||||
* An URL to the plain font, used to define the {@link #DEFAULT_SMALL_FONT} and the {@link GATOR_FONT}.
|
||||
* An URL to the plain font, used to define the {@link #DEFAULT_SMALL_FONT} and the {@link RrdGraphDef#GATOR_FONT}.
|
||||
*/
|
||||
public static final String PROPERTYFONTPLAINURL = "org.rrd4j.font.plain.url";
|
||||
String PROPERTYFONTPLAINURL = "org.rrd4j.font.plain.url";
|
||||
/**
|
||||
* An URL to the bold font, used to define the {@link #DEFAULT_LARGE_FONT}.
|
||||
*/
|
||||
public static final String PROPERTYFONTBOLDURL = "org.rrd4j.font.bold.url";
|
||||
String PROPERTYFONTBOLDURL = "org.rrd4j.font.bold.url";
|
||||
|
||||
/**
|
||||
* Font constructor, to use embedded fonts. Not really useful outside internal use for RRD4J.
|
||||
*/
|
||||
static class FontConstructor {
|
||||
class FontConstructor {
|
||||
private static final Properties fileProps = new Properties();
|
||||
static {
|
||||
refreshConf();
|
||||
@@ -364,7 +364,7 @@ public interface RrdGraphConstants {
|
||||
*/
|
||||
public static Font getFont(int type, int size) {
|
||||
/*
|
||||
Function<String, InputStream> fontStream = null;
|
||||
Function<String, InputStream> fontStream;
|
||||
String fontPath = fileProps.getProperty(type == Font.BOLD ? PROPERTYFONTBOLDURL : PROPERTYFONTPLAINURL);
|
||||
if (fontPath!= null) {
|
||||
fontStream = s -> {
|
||||
@@ -391,15 +391,15 @@ public interface RrdGraphConstants {
|
||||
/**
|
||||
* Default graph small font
|
||||
*/
|
||||
static final Font DEFAULT_SMALL_FONT = FontConstructor.getFont(Font.PLAIN, 10);
|
||||
Font DEFAULT_SMALL_FONT = FontConstructor.getFont(Font.PLAIN, 10);
|
||||
/**
|
||||
* Default graph large font
|
||||
*/
|
||||
static final Font DEFAULT_LARGE_FONT = FontConstructor.getFont(Font.BOLD, 12);
|
||||
Font DEFAULT_LARGE_FONT = FontConstructor.getFont(Font.BOLD, 12);
|
||||
/**
|
||||
* Font for the Gator
|
||||
*/
|
||||
static final Font GATOR_FONT = FontConstructor.getFont(Font.PLAIN, 9);
|
||||
Font GATOR_FONT = FontConstructor.getFont(Font.PLAIN, 9);
|
||||
/**
|
||||
* Used internally
|
||||
*/
|
||||
@@ -466,7 +466,7 @@ public interface RrdGraphConstants {
|
||||
/**
|
||||
* Allowed font tag names which can be used in {@link org.rrd4j.graph.RrdGraphDef#setFont(org.rrd4j.graph.RrdGraphConstants.FontTag, java.awt.Font)} method
|
||||
*/
|
||||
public enum FontTag {
|
||||
enum FontTag {
|
||||
/**
|
||||
* Index of the default font. Used in {@link org.rrd4j.graph.RrdGraphDef#setFont(org.rrd4j.graph.RrdGraphConstants.FontTag, java.awt.Font)}
|
||||
*/
|
||||
@@ -508,7 +508,7 @@ public interface RrdGraphConstants {
|
||||
|
||||
FontTag FONTTAG_AXIS = FontTag.AXIS;
|
||||
|
||||
FontTag FONTTAG_UNIT = FontTag.AXIS;
|
||||
FontTag FONTTAG_UNIT = FontTag.UNIT;
|
||||
|
||||
FontTag FONTTAG_LEGEND = FontTag.LEGEND;
|
||||
|
||||
|
||||
@@ -172,9 +172,9 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
Stroke tickStroke = TICK_STROKE;
|
||||
DownSampler downsampler = null;
|
||||
|
||||
final List<Source> sources = new ArrayList<Source>();
|
||||
final List<CommentText> comments = new ArrayList<CommentText>();
|
||||
final List<PlotElement> plotElements = new ArrayList<PlotElement>();
|
||||
final List<Source> sources = new ArrayList<>();
|
||||
final List<CommentText> comments = new ArrayList<>();
|
||||
final List<PlotElement> plotElements = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates RrdGraphDef object and sets default time span (default ending time is 'now',
|
||||
@@ -580,9 +580,9 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets image format.
|
||||
* ImageIO is used to save the image, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to save the image, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param imageFormat Any value as return by {@link javax.imageio.ImageIO#getReaderFormatNames}
|
||||
* @param imageFormat Any value as return by {@link ImageIO#getReaderFormatNames}
|
||||
*/
|
||||
public void setImageFormat(String imageFormat) {
|
||||
this.imageFormat = imageFormat;
|
||||
@@ -590,7 +590,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets background image.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param backgroundImage Path to background image
|
||||
*/
|
||||
@@ -600,7 +600,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets background image.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param backgroundImageUrl URL to background image
|
||||
*/
|
||||
@@ -619,7 +619,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets canvas background image. Canvas image is printed on canvas area, under canvas color and plot.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param canvasImage Path to canvas image
|
||||
*/
|
||||
@@ -629,7 +629,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets canvas background image. Canvas image is printed on canvas area, under canvas color and plot.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param canvasUrl URL to canvas image
|
||||
*/
|
||||
@@ -648,7 +648,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets overlay image. Overlay image is printed on the top of the image, once it is completely created.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param overlayImage Path to overlay image
|
||||
*/
|
||||
@@ -658,7 +658,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
|
||||
/**
|
||||
* Sets overlay image. Overlay image is printed on the top of the image, once it is completely created.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using https://github.com/geosolutions-it/imageio-ext.
|
||||
* ImageIO is used to download, so any supported format by ImageIO can be used, and it can be extended using <a href="https://github.com/geosolutions-it/imageio-ext">...</a>.
|
||||
*
|
||||
* @param overlayImage URL to overlay image
|
||||
*/
|
||||
@@ -1118,7 +1118,7 @@ public class RrdGraphDef implements RrdGraphConstants, DataHolder {
|
||||
/**
|
||||
* Creates a datasource that performs a variable calculation on an
|
||||
* another named datasource to yield a single combined timestamp/value.
|
||||
*
|
||||
* <p>
|
||||
* Requires that the other datasource has already been defined; otherwise, it'll
|
||||
* end up with no data
|
||||
*
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package org.rrd4j.graph;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Class to represent successfully created Rrd4j graph. Objects of this class are created by method
|
||||
@@ -12,9 +11,10 @@ import java.util.List;
|
||||
public class RrdGraphInfo {
|
||||
String filename;
|
||||
int width, height;
|
||||
InputStream stream;
|
||||
Supplier<byte[]> bytesSource;
|
||||
Supplier<Integer> bytesCount;
|
||||
String imgInfo;
|
||||
private List<String> printLines = new ArrayList<String>();
|
||||
private final List<String> printLines = new ArrayList<>();
|
||||
|
||||
RrdGraphInfo() {
|
||||
// cannot instantiate this class
|
||||
@@ -58,16 +58,7 @@ public class RrdGraphInfo {
|
||||
* @throws IllegalStateException if the images bytes are unavailable or can't be read
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
try {
|
||||
byte[] content = new byte[stream.available()];
|
||||
int read = stream.read(content);
|
||||
if (read != content.length) {
|
||||
throw new IllegalStateException("Unable to read image buffer");
|
||||
}
|
||||
return content;
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to read image bytes", e);
|
||||
}
|
||||
return bytesSource.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +67,7 @@ public class RrdGraphInfo {
|
||||
* @return An array of formatted PRINT lines
|
||||
*/
|
||||
public String[] getPrintLines() {
|
||||
return printLines.toArray(new String[printLines.size()]);
|
||||
return printLines.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,11 +86,7 @@ public class RrdGraphInfo {
|
||||
* @throws IllegalStateException if the images bytes are unavailable
|
||||
*/
|
||||
public int getByteCount() {
|
||||
try {
|
||||
return stream.available();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Unable to read image bytes", e);
|
||||
}
|
||||
return bytesCount.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,7 @@ class Stack extends SourcedPlotElement {
|
||||
super(srcName, color, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
void assignValues(DataProcessor dproc) {
|
||||
double[] parentValues = parent.getValues();
|
||||
double[] procValues = dproc.getValues(srcName);
|
||||
@@ -40,6 +41,7 @@ class Stack extends SourcedPlotElement {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Paint getParentColor() {
|
||||
return parent.color;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.rrd4j.graph;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Paint;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
|
||||
import org.rrd4j.core.Util;
|
||||
|
||||
@@ -106,6 +108,10 @@ class ValueAxis extends Axis {
|
||||
}
|
||||
gridstep = selectedYLabel.grid * im.magfact;
|
||||
labfact = findLabelFactor(selectedYLabel);
|
||||
if(labfact == -1) {
|
||||
// as a fallback, use the largest label factor of the selected label
|
||||
labfact = selectedYLabel.labelFacts[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -116,13 +122,14 @@ class ValueAxis extends Axis {
|
||||
int sgrid = (int) (im.minval / gridstep - 1);
|
||||
int egrid = (int) (im.maxval / gridstep + 1);
|
||||
double scaledstep = gridstep / im.magfact;
|
||||
boolean fractional = isFractional(scaledstep, labfact);
|
||||
for (int i = sgrid; i <= egrid; i++) {
|
||||
int y = mapper.ytr(gridstep * i);
|
||||
if (y >= im.yorigin - im.ysize && y <= im.yorigin) {
|
||||
if (i % labfact == 0) {
|
||||
String graph_label;
|
||||
if (i == 0 || im.symbol == ' ') {
|
||||
if (scaledstep < 1) {
|
||||
if (fractional) {
|
||||
if (i != 0 && gdef.altYGrid) {
|
||||
graph_label = Util.sprintf(gdef.locale, labfmt, scaledstep * i);
|
||||
}
|
||||
@@ -135,7 +142,7 @@ class ValueAxis extends Axis {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (scaledstep < 1) {
|
||||
if (fractional) {
|
||||
graph_label = Util.sprintf(gdef.locale, "%4.1f %c", scaledstep * i, im.symbol);
|
||||
}
|
||||
else {
|
||||
@@ -163,7 +170,7 @@ class ValueAxis extends Axis {
|
||||
* If the graph covers positive and negative on the y-axis, then
|
||||
* desiredMinimumLabelCount is checked as well, to ensure the chosen YLabel definition
|
||||
* will result in the required number of labels
|
||||
*
|
||||
* <p>
|
||||
* Returns null if none are acceptable (none the right size or with
|
||||
* enough labels)
|
||||
*/
|
||||
@@ -237,6 +244,18 @@ class ValueAxis extends Axis {
|
||||
return range / im.magfact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if some or all labels have fractional part (other than zero).
|
||||
*/
|
||||
private static boolean isFractional(double scaledstep, int labfact) {
|
||||
if (scaledstep >= 1) {
|
||||
return false;
|
||||
}
|
||||
BigDecimal bd = BigDecimal.valueOf(scaledstep)
|
||||
.multiply(BigDecimal.valueOf(labfact), MathContext.DECIMAL32);
|
||||
return !(bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0);
|
||||
}
|
||||
|
||||
static class YLabel {
|
||||
final double grid;
|
||||
final int[] labelFacts;
|
||||
|
||||
@@ -43,7 +43,7 @@ class ValueAxisLogarithmic extends Axis {
|
||||
if (im.maxval == im.minval) {
|
||||
return false;
|
||||
}
|
||||
double pixpex = (double) im.ysize / (log10(im.maxval) - log10(im.minval));
|
||||
double pixpex = im.ysize / (log10(im.maxval) - log10(im.minval));
|
||||
if (Double.isNaN(pixpex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.rrd4j.graph;
|
||||
|
||||
class ValueScaler {
|
||||
static final String UNIT_UNKNOWN = "?";
|
||||
static final String UNIT_SYMBOLS[] = {
|
||||
static final String[] UNIT_SYMBOLS = {
|
||||
"a", "f", "p", "n", "u", "m", " ", "k", "M", "G", "T", "P", "E"
|
||||
};
|
||||
static final int SYMB_CENTER = 6;
|
||||
@@ -55,8 +55,8 @@ class ValueScaler {
|
||||
}
|
||||
|
||||
static class Scaled {
|
||||
double value;
|
||||
String unit;
|
||||
final double value;
|
||||
final String unit;
|
||||
|
||||
public Scaled(double value, String unit) {
|
||||
this.value = value;
|
||||
|
||||
Reference in New Issue
Block a user