Console: Update rrd4j to version 3.9

This commit is contained in:
zzz
2024-01-27 12:23:26 +00:00
parent ce5c75cb61
commit b0db90da49
80 changed files with 430 additions and 466 deletions
+1 -1
View File
@@ -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));
}
+12 -11
View File
@@ -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++) {
+2 -3
View File
@@ -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;