From: Tarus B. <ta...@us...> - 2006-12-21 18:03:16
|
Update of /cvsroot/jrobin/src/org/jrobin/core/jrrd In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv9082/org/jrobin/core/jrrd Modified Files: Archive.java CDPStatusBlock.java ConsolidationFunctionType.java Constants.java DataChunk.java DataSource.java DataSourceType.java Header.java PDPStatusBlock.java RRDException.java RRDFile.java RRDatabase.java Log Message: Adding the new 1.5.4 code Index: DataSourceType.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/DataSourceType.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DataSourceType.java 22 Jul 2004 09:34:10 -0000 1.1 --- DataSourceType.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,127 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * Class DataSourceType ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class DataSourceType { ! ! private static final int _COUNTER = 0; ! private static final String STR_COUNTER = "COUNTER"; ! ! /** ! * Field COUNTER ! */ ! public static final DataSourceType COUNTER = ! new DataSourceType(_COUNTER); ! private static final int _ABSOLUTE = 1; ! private static final String STR_ABSOLUTE = "ABSOLUTE"; ! ! /** ! * Field ABSOLUTE ! */ ! public static final DataSourceType ABSOLUTE = ! new DataSourceType(_ABSOLUTE); ! private static final int _GAUGE = 2; ! private static final String STR_GAUGE = "GAUGE"; ! ! /** ! * Field GAUGE ! */ ! public static final DataSourceType GAUGE = new DataSourceType(_GAUGE); ! private static final int _DERIVE = 3; ! private static final String STR_DERIVE = "DERIVE"; ! ! /** ! * Field DERIVE ! */ ! public static final DataSourceType DERIVE = new DataSourceType(_DERIVE); ! private int type; ! ! private DataSourceType(int type) { ! this.type = type; ! } ! ! /** ! * Returns a <code>DataSourceType</code> with the given name. ! * ! * @param s name of the <code>DataSourceType</code> required. ! * @return a <code>DataSourceType</code> with the given name. ! */ ! public static DataSourceType get(String s) { ! ! if (s.equalsIgnoreCase(STR_COUNTER)) { ! return COUNTER; ! } else if (s.equalsIgnoreCase(STR_ABSOLUTE)) { ! return ABSOLUTE; ! } else if (s.equalsIgnoreCase(STR_GAUGE)) { ! return GAUGE; ! } else if (s.equalsIgnoreCase(STR_DERIVE)) { ! return DERIVE; ! } else { ! throw new IllegalArgumentException("Invalid DataSourceType"); ! } ! } ! ! /** ! * Compares this object against the specified object. ! * ! * @return <code>true</code> if the objects are the same, ! * <code>false</code> otherwise. ! */ ! public boolean equals(Object obj) { ! ! if (!(obj instanceof DataSourceType)) { ! throw new IllegalArgumentException("Not a DataSourceType"); ! } ! ! return (((DataSourceType) obj).type == type) ! ? true ! : false; ! } ! ! /** ! * Returns a string representation of this object. ! * ! * @return a string representation of this object. ! */ ! public String toString() { ! ! String strType; ! ! switch (type) { ! ! case _COUNTER: ! strType = STR_COUNTER; ! break; ! ! case _ABSOLUTE: ! strType = STR_ABSOLUTE; ! break; ! ! case _GAUGE: ! strType = STR_GAUGE; ! break; ! ! case _DERIVE: ! strType = STR_DERIVE; ! break; ! ! default : ! // Don't you just hate it when you see a line like this? ! throw new RuntimeException("This should never happen"); ! } ! ! return strType; ! } ! } --- 1,131 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * Class DataSourceType ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class DataSourceType { ! ! private static final int _COUNTER = 0; ! private static final String STR_COUNTER = "COUNTER"; ! ! /** ! * Field COUNTER ! */ ! public static final DataSourceType COUNTER = ! new DataSourceType(_COUNTER); ! private static final int _ABSOLUTE = 1; ! private static final String STR_ABSOLUTE = "ABSOLUTE"; ! ! /** ! * Field ABSOLUTE ! */ ! public static final DataSourceType ABSOLUTE = ! new DataSourceType(_ABSOLUTE); ! private static final int _GAUGE = 2; ! private static final String STR_GAUGE = "GAUGE"; ! ! /** ! * Field GAUGE ! */ ! public static final DataSourceType GAUGE = new DataSourceType(_GAUGE); ! private static final int _DERIVE = 3; ! private static final String STR_DERIVE = "DERIVE"; ! ! /** ! * Field DERIVE ! */ ! public static final DataSourceType DERIVE = new DataSourceType(_DERIVE); ! private int type; ! ! private DataSourceType(int type) { ! this.type = type; ! } ! ! /** ! * Returns a <code>DataSourceType</code> with the given name. ! * ! * @param s name of the <code>DataSourceType</code> required. ! * @return a <code>DataSourceType</code> with the given name. ! */ ! public static DataSourceType get(String s) { ! ! if (s.equalsIgnoreCase(STR_COUNTER)) { ! return COUNTER; ! } ! else if (s.equalsIgnoreCase(STR_ABSOLUTE)) { ! return ABSOLUTE; ! } ! else if (s.equalsIgnoreCase(STR_GAUGE)) { ! return GAUGE; ! } ! else if (s.equalsIgnoreCase(STR_DERIVE)) { ! return DERIVE; ! } ! else { ! throw new IllegalArgumentException("Invalid DataSourceType"); ! } ! } ! ! /** ! * Compares this object against the specified object. ! * ! * @return <code>true</code> if the objects are the same, ! * <code>false</code> otherwise. ! */ ! public boolean equals(Object obj) { ! ! if (!(obj instanceof DataSourceType)) { ! throw new IllegalArgumentException("Not a DataSourceType"); ! } ! ! return (((DataSourceType) obj).type == type) ! ? true ! : false; ! } ! ! /** ! * Returns a string representation of this object. ! * ! * @return a string representation of this object. ! */ ! public String toString() { ! ! String strType; ! ! switch (type) { ! ! case _COUNTER: ! strType = STR_COUNTER; ! break; ! ! case _ABSOLUTE: ! strType = STR_ABSOLUTE; ! break; ! ! case _GAUGE: ! strType = STR_GAUGE; ! break; ! ! case _DERIVE: ! strType = STR_DERIVE; ! break; ! ! default : ! // Don't you just hate it when you see a line like this? ! throw new RuntimeException("This should never happen"); ! } ! ! return strType; ! } ! } Index: ConsolidationFunctionType.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/ConsolidationFunctionType.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ConsolidationFunctionType.java 22 Jul 2004 09:34:10 -0000 1.1 --- ConsolidationFunctionType.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,128 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * Class ConsolidationFunctionType ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class ConsolidationFunctionType { ! ! private static final int _AVERAGE = 0; ! private static final String STR_AVERAGE = "AVERAGE"; ! ! /** ! * Field AVERAGE ! */ ! public static final ConsolidationFunctionType AVERAGE = ! new ConsolidationFunctionType(_AVERAGE); ! private static final int _MIN = 1; ! private static final String STR_MIN = "MIN"; ! ! /** ! * Field MIN ! */ ! public static final ConsolidationFunctionType MIN = ! new ConsolidationFunctionType(_MIN); ! private static final int _MAX = 2; ! private static final String STR_MAX = "MAX"; ! ! /** ! * Field MAX ! */ ! public static final ConsolidationFunctionType MAX = ! new ConsolidationFunctionType(_MAX); ! private static final int _LAST = 3; ! private static final String STR_LAST = "LAST"; ! ! /** ! * Field LAST ! */ ! public static final ConsolidationFunctionType LAST = ! new ConsolidationFunctionType(_LAST); ! private int type; ! ! private ConsolidationFunctionType(int type) { ! this.type = type; ! } ! ! /** ! * Returns a <code>ConsolidationFunctionType</code> with the given name. ! * ! * @param s name of the <code>ConsolidationFunctionType</code> required. ! * @return a <code>ConsolidationFunctionType</code> with the given name. ! */ ! public static ConsolidationFunctionType get(String s) { ! ! if (s.equalsIgnoreCase(STR_AVERAGE)) { ! return AVERAGE; ! } else if (s.equalsIgnoreCase(STR_MIN)) { ! return MIN; ! } else if (s.equalsIgnoreCase(STR_MAX)) { ! return MAX; ! } else if (s.equalsIgnoreCase(STR_LAST)) { ! return LAST; ! } else { ! throw new IllegalArgumentException("Invalid ConsolidationFunctionType"); ! } ! } ! ! /** ! * Compares this object against the specified object. ! * ! * @return <code>true</code> if the objects are the same, ! * <code>false</code> otherwise. ! */ ! public boolean equals(Object o) { ! ! if (!(o instanceof ConsolidationFunctionType)) { ! throw new IllegalArgumentException("Not a ConsolidationFunctionType"); ! } ! ! return (((ConsolidationFunctionType) o).type == type) ! ? true ! : false; ! } ! ! /** ! * Returns a string representation of this object. ! * ! * @return a string representation of this object. ! */ ! public String toString() { ! ! String strType; ! ! switch (type) { ! ! case _AVERAGE: ! strType = STR_AVERAGE; ! break; ! ! case _MIN: ! strType = STR_MIN; ! break; ! ! case _MAX: ! strType = STR_MAX; ! break; ! ! case _LAST: ! strType = STR_LAST; ! break; ! ! default : ! throw new RuntimeException("This should never happen"); ! } ! ! return strType; ! } ! } --- 1,132 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * Class ConsolidationFunctionType ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class ConsolidationFunctionType { ! ! private static final int _AVERAGE = 0; ! private static final String STR_AVERAGE = "AVERAGE"; ! ! /** ! * Field AVERAGE ! */ ! public static final ConsolidationFunctionType AVERAGE = ! new ConsolidationFunctionType(_AVERAGE); ! private static final int _MIN = 1; ! private static final String STR_MIN = "MIN"; ! ! /** ! * Field MIN ! */ ! public static final ConsolidationFunctionType MIN = ! new ConsolidationFunctionType(_MIN); ! private static final int _MAX = 2; ! private static final String STR_MAX = "MAX"; ! ! /** ! * Field MAX ! */ ! public static final ConsolidationFunctionType MAX = ! new ConsolidationFunctionType(_MAX); ! private static final int _LAST = 3; ! private static final String STR_LAST = "LAST"; ! ! /** ! * Field LAST ! */ ! public static final ConsolidationFunctionType LAST = ! new ConsolidationFunctionType(_LAST); ! private int type; ! ! private ConsolidationFunctionType(int type) { ! this.type = type; ! } ! ! /** ! * Returns a <code>ConsolidationFunctionType</code> with the given name. ! * ! * @param s name of the <code>ConsolidationFunctionType</code> required. ! * @return a <code>ConsolidationFunctionType</code> with the given name. ! */ ! public static ConsolidationFunctionType get(String s) { ! ! if (s.equalsIgnoreCase(STR_AVERAGE)) { ! return AVERAGE; ! } ! else if (s.equalsIgnoreCase(STR_MIN)) { ! return MIN; ! } ! else if (s.equalsIgnoreCase(STR_MAX)) { ! return MAX; ! } ! else if (s.equalsIgnoreCase(STR_LAST)) { ! return LAST; ! } ! else { ! throw new IllegalArgumentException("Invalid ConsolidationFunctionType"); ! } ! } ! ! /** ! * Compares this object against the specified object. ! * ! * @return <code>true</code> if the objects are the same, ! * <code>false</code> otherwise. ! */ ! public boolean equals(Object o) { ! ! if (!(o instanceof ConsolidationFunctionType)) { ! throw new IllegalArgumentException("Not a ConsolidationFunctionType"); ! } ! ! return (((ConsolidationFunctionType) o).type == type) ! ? true ! : false; ! } ! ! /** ! * Returns a string representation of this object. ! * ! * @return a string representation of this object. ! */ ! public String toString() { ! ! String strType; ! ! switch (type) { ! ! case _AVERAGE: ! strType = STR_AVERAGE; ! break; ! ! case _MIN: ! strType = STR_MIN; ! break; ! ! case _MAX: ! strType = STR_MAX; ! break; ! ! case _LAST: ! strType = STR_LAST; ! break; ! ! default : ! throw new RuntimeException("This should never happen"); ! } ! ! return strType; ! } ! } Index: RRDException.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/RRDException.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RRDException.java 22 Jul 2004 09:34:10 -0000 1.1 --- RRDException.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,33 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * This exception may be throw if an error occurs while operating ! * on an RRD object. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class RRDException extends Exception { ! ! /** ! * Constructs an RRDException with no detail message. ! */ ! public RRDException() { ! super(); ! } ! ! /** ! * Constructs an RRDException with the specified detail message. ! */ ! public RRDException(String message) { ! super(message); ! } ! } --- 1,33 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! /** ! * This exception may be throw if an error occurs while operating ! * on an RRD object. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class RRDException extends Exception { ! ! /** ! * Constructs an RRDException with no detail message. ! */ ! public RRDException() { ! super(); ! } ! ! /** ! * Constructs an RRDException with the specified detail message. ! */ ! public RRDException(String message) { ! super(message); ! } ! } Index: Header.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/Header.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Header.java 22 Jul 2004 09:34:10 -0000 1.1 --- Header.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,112 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.*; ! ! /** ! * Instances of this class model the header section of an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class Header implements Constants { ! ! static final long offset = 0; ! long size; ! String version; ! int dsCount; ! int rraCount; ! int pdpStep; ! ! Header(RRDFile file) throws IOException { ! ! if (!file.readString(4).equals(COOKIE)) { ! throw new IOException("Invalid COOKIE"); ! } ! ! if (!(version = file.readString(5)).equals(VERSION)) { ! throw new IOException("Unsupported RRD version (" + version + ")"); ! } ! ! file.align(); ! ! // Consume the FLOAT_COOKIE ! file.readDouble(); ! ! dsCount = file.readInt(); ! rraCount = file.readInt(); ! pdpStep = file.readInt(); ! ! // Skip rest of stat_head_t.par ! file.align(); ! file.skipBytes(80); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the version of the database. ! * ! * @return the version of the database. ! */ ! public String getVersion() { ! return version; ! } ! ! /** ! * Returns the number of <code>DataSource</code>s in the database. ! * ! * @return the number of <code>DataSource</code>s in the database. ! */ ! public int getDSCount() { ! return dsCount; ! } ! ! /** ! * Returns the number of <code>Archive</code>s in the database. ! * ! * @return the number of <code>Archive</code>s in the database. ! */ ! public int getRRACount() { ! return rraCount; ! } ! ! /** ! * Returns the primary data point interval in seconds. ! * ! * @return the primary data point interval in seconds. ! */ ! public int getPDPStep() { ! return pdpStep; ! } ! ! /** ! * Returns a summary the contents of this header. ! * ! * @return a summary of the information contained in this header. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[Header: OFFSET=0x00, SIZE=0x"); ! ! sb.append(Long.toHexString(size)); ! sb.append(", version="); ! sb.append(version); ! sb.append(", dsCount="); ! sb.append(dsCount); ! sb.append(", rraCount="); ! sb.append(rraCount); ! sb.append(", pdpStep="); ! sb.append(pdpStep); ! sb.append("]"); ! ! return sb.toString(); ! } ! } --- 1,112 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.IOException; ! ! /** ! * Instances of this class model the header section of an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class Header implements Constants { ! ! static final long offset = 0; ! long size; ! String version; ! int dsCount; ! int rraCount; ! int pdpStep; ! ! Header(RRDFile file) throws IOException { ! ! if (!file.readString(4).equals(COOKIE)) { ! throw new IOException("Invalid COOKIE"); ! } ! ! if (!(version = file.readString(5)).equals(VERSION)) { ! throw new IOException("Unsupported RRD version (" + version + ")"); ! } ! ! file.align(); ! ! // Consume the FLOAT_COOKIE ! file.readDouble(); ! ! dsCount = file.readInt(); ! rraCount = file.readInt(); ! pdpStep = file.readInt(); ! ! // Skip rest of stat_head_t.par ! file.align(); ! file.skipBytes(80); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the version of the database. ! * ! * @return the version of the database. ! */ ! public String getVersion() { ! return version; ! } ! ! /** ! * Returns the number of <code>DataSource</code>s in the database. ! * ! * @return the number of <code>DataSource</code>s in the database. ! */ ! public int getDSCount() { ! return dsCount; ! } ! ! /** ! * Returns the number of <code>Archive</code>s in the database. ! * ! * @return the number of <code>Archive</code>s in the database. ! */ ! public int getRRACount() { ! return rraCount; ! } ! ! /** ! * Returns the primary data point interval in seconds. ! * ! * @return the primary data point interval in seconds. ! */ ! public int getPDPStep() { ! return pdpStep; ! } ! ! /** ! * Returns a summary the contents of this header. ! * ! * @return a summary of the information contained in this header. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[Header: OFFSET=0x00, SIZE=0x"); ! ! sb.append(Long.toHexString(size)); ! sb.append(", version="); ! sb.append(version); ! sb.append(", dsCount="); ! sb.append(dsCount); ! sb.append(", rraCount="); ! sb.append(rraCount); ! sb.append(", pdpStep="); ! sb.append(pdpStep); ! sb.append("]"); ! ! return sb.toString(); ! } ! } Index: Archive.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/Archive.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Archive.java 5 Nov 2004 12:22:52 -0000 1.2 --- Archive.java 21 Dec 2006 18:02:42 -0000 1.3 *************** *** 1,404 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.IOException; ! import java.io.PrintStream; ! import java.text.*; ! import java.util.*; ! ! /** ! * Instances of this class model an archive section of an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class Archive { ! ! RRDatabase db; ! long offset; ! long dataOffset; ! long size; ! ConsolidationFunctionType type; ! int rowCount; ! int pdpCount; ! double xff; ! ArrayList cdpStatusBlocks; ! int currentRow; ! ! private double[][] values; ! ! Archive(RRDatabase db) throws IOException { ! ! this.db = db; ! ! RRDFile file = db.rrdFile; ! ! offset = file.getFilePointer(); ! type = ! ConsolidationFunctionType.get(file.readString(Constants.CF_NAM_SIZE)); ! rowCount = file.readInt(); ! pdpCount = file.readInt(); ! ! file.align(); ! ! xff = file.readDouble(); ! ! // Skip rest of rra_def_t.par[] ! file.align(); ! file.skipBytes(72); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the type of function used to calculate the consolidated data point. ! * ! * @return the type of function used to calculate the consolidated data point. ! */ ! public ConsolidationFunctionType getType() { ! return type; ! } ! ! void loadCDPStatusBlocks(RRDFile file, int numBlocks) throws IOException { ! ! cdpStatusBlocks = new ArrayList(); ! ! for (int i = 0; i < numBlocks; i++) { ! cdpStatusBlocks.add(new CDPStatusBlock(file)); ! } ! } ! ! /** ! * Returns the <code>CDPStatusBlock</code> at the specified position in this archive. ! * ! * @param index index of <code>CDPStatusBlock</code> to return. ! * @return the <code>CDPStatusBlock</code> at the specified position in this archive. ! */ ! public CDPStatusBlock getCDPStatusBlock(int index) { ! return (CDPStatusBlock) cdpStatusBlocks.get(index); ! } ! ! /** ! * Returns an iterator over the CDP status blocks in this archive in proper sequence. ! * ! * @return an iterator over the CDP status blocks in this archive in proper sequence. ! * @see CDPStatusBlock ! */ ! public Iterator getCDPStatusBlocks() { ! return cdpStatusBlocks.iterator(); ! } ! ! void loadCurrentRow(RRDFile file) throws IOException { ! currentRow = file.readInt(); ! } ! ! void loadData(RRDFile file, int dsCount) throws IOException { ! ! dataOffset = file.getFilePointer(); ! ! // Skip over the data to position ourselves at the start of the next archive ! file.skipBytes(8 * rowCount * dsCount); ! } ! ! DataChunk loadData(DataChunk chunk) throws IOException { ! ! Calendar end = Calendar.getInstance(); ! Calendar start = (Calendar) end.clone(); ! ! start.add(Calendar.DATE, -1); ! ! loadData(chunk, start.getTime().getTime() / 1000, ! end.getTime().getTime() / 1000); ! return chunk; ! } ! ! void loadData(DataChunk chunk, long startTime, long endTime) ! throws IOException { ! ! long pointer; ! ! if (chunk.start < 0) { ! pointer = currentRow + 1; ! } else { ! pointer = currentRow + chunk.start + 1; ! } ! ! db.rrdFile.ras.seek(dataOffset + (pointer * 8)); ! //cat.debug("Archive Base: " + dataOffset + " Archive Pointer: " + pointer); ! //cat.debug("Start Offset: " + chunk.start + " End Offset: " ! // + (rowCount - chunk.end)); ! ! double[][] data = chunk.data; ! ! /* ! * This is also terrible - cleanup - CT ! */ ! int row = 0; ! for (int i = chunk.start; i < rowCount - chunk.end; i++, row++) { ! if (i < 0) { // no valid data yet ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = Double.NaN; ! } ! } else if (i >= rowCount) { // past valid data area ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = Double.NaN; ! } ! } else { // inside the valid are but the pointer has to be wrapped ! if (pointer >= rowCount) { ! pointer -= rowCount; ! ! db.rrdFile.ras.seek(dataOffset + (pointer * 8)); ! } ! ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = db.rrdFile.readDouble(); ! } ! ! pointer++; ! } ! } ! } ! ! void printInfo(PrintStream s, NumberFormat numberFormat, int index) { ! ! StringBuffer sb = new StringBuffer("rra["); ! ! sb.append(index); ! s.print(sb); ! s.print("].cf = \""); ! s.print(type); ! s.println("\""); ! s.print(sb); ! s.print("].rows = "); ! s.println(rowCount); ! s.print(sb); ! s.print("].pdp_per_row = "); ! s.println(pdpCount); ! s.print(sb); ! s.print("].xff = "); ! s.println(xff); ! sb.append("].cdp_prep["); ! ! int cdpIndex = 0; ! ! for (Iterator i = cdpStatusBlocks.iterator(); i.hasNext();) { ! CDPStatusBlock cdp = (CDPStatusBlock) i.next(); ! ! s.print(sb); ! s.print(cdpIndex); ! s.print("].value = "); ! ! double value = cdp.value; ! ! s.println(Double.isNaN(value) ! ? "NaN" ! : numberFormat.format(value)); ! s.print(sb); ! s.print(cdpIndex++); ! s.print("].unknown_datapoints = "); ! s.println(cdp.unknownDatapoints); ! } ! } ! ! void toXml(PrintStream s) { ! ! 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 (int i = 0; i < cdpStatusBlocks.size(); i++) { ! ((CDPStatusBlock) 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.ras.seek(dataOffset + (row + 1) * 16); ! ! long lastUpdate = db.lastUpdate.getTime() / 1000; ! int pdpStep = db.header.pdpStep; ! NumberFormat numberFormat = new DecimalFormat("0.0000000000E0"); ! SimpleDateFormat dateFormat = ! new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); ! ! while (counter++ < rowCount) { ! row++; ! ! if (row == rowCount) { ! row = 0; ! ! db.rrdFile.ras.seek(dataOffset); ! } ! ! 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(" --> "); ! ! 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.println("\t\t</database>"); ! s.println("\t</rra>"); ! } catch (IOException e) { // Is the best thing to do here? ! throw new RuntimeException(e.getMessage()); ! } ! } ! ! /* ! // THIS IS THE ORIGINAL CODE: BUGGY! Replaced by Sasa Markovic with a new method ! // Funny: the bug will appear only if dsCount != 2 :) ! public double[][] getValuesOriginal() throws IOException { ! if (values != null) { ! return values; ! } ! values = new double[db.header.dsCount][rowCount]; ! int row = currentRow; ! db.rrdFile.ras.seek(dataOffset + (row + 1) * 16); // <----- BUG (resolved below) ! for (int counter = 0; counter < rowCount; counter++) { ! row++; ! if (row == rowCount) { ! row = 0; ! db.rrdFile.ras.seek(dataOffset); ! } ! for (int col = 0; col < db.header.dsCount; col++) { ! double value = db.rrdFile.readDouble(); ! values[col][counter] = value; ! } ! } ! return values; ! } ! */ ! ! // Resolved bug from the original method (see above) ! public double[][] getValues() throws IOException { ! // OK PART ! if (values != null) { ! return values; ! } ! values = new double[db.header.dsCount][rowCount]; ! int row = currentRow; ! // HERE ARE THE DRAGONS! ! db.rrdFile.ras.seek(dataOffset + (row + 1) * db.header.dsCount * 8); ! // OK, TOO! ! for (int counter = 0; counter < rowCount; counter++) { ! row++; ! if (row == rowCount) { ! row = 0; ! db.rrdFile.ras.seek(dataOffset); ! } ! for (int col = 0; col < db.header.dsCount; col++) { ! double value = db.rrdFile.readDouble(); ! values[col][counter] = value; ! } ! } ! return values; ! } ! ! /** ! * Returns the number of primary data points required for a consolidated ! * data point in this archive. ! * ! * @return the number of primary data points required for a consolidated ! * data point in this archive. ! */ ! public int getPdpCount() { ! return pdpCount; ! } ! ! /** ! * Returns the number of entries in this archive. ! * ! * @return the number of entries in this archive. ! */ ! public int getRowCount() { ! return rowCount; ! } ! ! /** ! * Returns the X-Files Factor for this archive. ! * ! * @return the X-Files Factor for this archive. ! */ ! public double getXff() { ! return xff; ! } ! ! /** ! * Returns a summary the contents of this archive. ! * ! * @return a summary of the information contained in this archive. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[Archive: OFFSET=0x"); ! ! sb.append(Long.toHexString(offset)); ! sb.append(", SIZE=0x"); ! sb.append(Long.toHexString(size)); ! sb.append(", type="); ! sb.append(type); ! sb.append(", rowCount="); ! sb.append(rowCount); ! sb.append(", pdpCount="); ! sb.append(pdpCount); ! sb.append(", xff="); ! sb.append(xff); ! sb.append(", currentRow="); ! sb.append(currentRow); ! sb.append("]"); ! ! for (Iterator i = cdpStatusBlocks.iterator(); i.hasNext();) { ! CDPStatusBlock cdp = (CDPStatusBlock) i.next(); ! ! sb.append("\n\t\t"); ! sb.append(cdp.toString()); ! } ! ! return sb.toString(); ! } ! } --- 1,414 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.IOException; ! import java.io.PrintStream; ! import java.text.DecimalFormat; ! import java.text.NumberFormat; ! import java.text.SimpleDateFormat; ! import java.util.ArrayList; ! import java.util.Calendar; ! import java.util.Date; ! import java.util.Iterator; ! ! /** ! * Instances of this class model an archive section of an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class Archive { ! ! RRDatabase db; ! long offset; ! long dataOffset; ! long size; ! ConsolidationFunctionType type; ! int rowCount; ! int pdpCount; ! double xff; ! ArrayList<CDPStatusBlock> cdpStatusBlocks; ! int currentRow; ! ! private double[][] values; ! ! Archive(RRDatabase db) throws IOException { ! ! this.db = db; ! ! RRDFile file = db.rrdFile; ! ! offset = file.getFilePointer(); ! type = ! ConsolidationFunctionType.get(file.readString(Constants.CF_NAM_SIZE)); ! rowCount = file.readInt(); ! pdpCount = file.readInt(); ! ! file.align(); ! ! xff = file.readDouble(); ! ! // Skip rest of rra_def_t.par[] ! file.align(); ! file.skipBytes(72); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the type of function used to calculate the consolidated data point. ! * ! * @return the type of function used to calculate the consolidated data point. ! */ ! public ConsolidationFunctionType getType() { ! return type; ! } ! ! void loadCDPStatusBlocks(RRDFile file, int numBlocks) throws IOException { ! ! cdpStatusBlocks = new ArrayList<CDPStatusBlock>(); ! ! for (int i = 0; i < numBlocks; i++) { ! cdpStatusBlocks.add(new CDPStatusBlock(file)); ! } ! } ! ! /** ! * Returns the <code>CDPStatusBlock</code> at the specified position in this archive. ! * ! * @param index index of <code>CDPStatusBlock</code> to return. ! * @return the <code>CDPStatusBlock</code> at the specified position in this archive. ! */ ! public CDPStatusBlock getCDPStatusBlock(int index) { ! return cdpStatusBlocks.get(index); ! } ! ! /** ! * Returns an iterator over the CDP status blocks in this archive in proper sequence. ! * ! * @return an iterator over the CDP status blocks in this archive in proper sequence. ! * @see CDPStatusBlock ! */ ! public Iterator<CDPStatusBlock> getCDPStatusBlocks() { ! return cdpStatusBlocks.iterator(); ! } ! ! void loadCurrentRow(RRDFile file) throws IOException { ! currentRow = file.readInt(); ! } ! ! void loadData(RRDFile file, int dsCount) throws IOException { ! ! dataOffset = file.getFilePointer(); ! ! // Skip over the data to position ourselves at the start of the next archive ! file.skipBytes(8 * rowCount * dsCount); ! } ! ! DataChunk loadData(DataChunk chunk) throws IOException { ! ! Calendar end = Calendar.getInstance(); ! Calendar start = (Calendar) end.clone(); ! ! start.add(Calendar.DATE, -1); ! ! loadData(chunk, start.getTime().getTime() / 1000, ! end.getTime().getTime() / 1000); ! return chunk; ! } ! ! void loadData(DataChunk chunk, long startTime, long endTime) ! throws IOException { ! ! long pointer; ! ! if (chunk.start < 0) { ! pointer = currentRow + 1; ! } ! else { ! pointer = currentRow + chunk.start + 1; ! } ! ! db.rrdFile.ras.seek(dataOffset + (pointer * 8)); ! //cat.debug("Archive Base: " + dataOffset + " Archive Pointer: " + pointer); ! //cat.debug("Start Offset: " + chunk.start + " End Offset: " ! // + (rowCount - chunk.end)); ! ! double[][] data = chunk.data; ! ! /* ! * This is also terrible - cleanup - CT ! */ ! int row = 0; ! for (int i = chunk.start; i < rowCount - chunk.end; i++, row++) { ! if (i < 0) { // no valid data yet ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = Double.NaN; ! } ! } ! else if (i >= rowCount) { // past valid data area ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = Double.NaN; ! } ! } ! else { // inside the valid are but the pointer has to be wrapped ! if (pointer >= rowCount) { ! pointer -= rowCount; ! ! db.rrdFile.ras.seek(dataOffset + (pointer * 8)); ! } ! ! for (int ii = 0; ii < chunk.dsCount; ii++) { ! data[row][ii] = db.rrdFile.readDouble(); ! } ! ! pointer++; ! } ! } ! } ! ! void printInfo(PrintStream s, NumberFormat numberFormat, int index) { ! ! StringBuffer sb = new StringBuffer("rra["); ! ! sb.append(index); ! s.print(sb); ! s.print("].cf = \""); ! s.print(type); ! s.println("\""); ! s.print(sb); ! s.print("].rows = "); ! s.println(rowCount); ! s.print(sb); ! s.print("].pdp_per_row = "); ! s.println(pdpCount); ! s.print(sb); ! s.print("].xff = "); ! s.println(xff); ! sb.append("].cdp_prep["); ! ! int cdpIndex = 0; ! ! for (Iterator<CDPStatusBlock> i = cdpStatusBlocks.iterator(); i.hasNext();) { ! CDPStatusBlock cdp = i.next(); ! ! s.print(sb); ! s.print(cdpIndex); ! s.print("].value = "); ! ! double value = cdp.value; ! ! s.println(Double.isNaN(value) ! ? "NaN" ! : numberFormat.format(value)); ! s.print(sb); ! s.print(cdpIndex++); ! s.print("].unknown_datapoints = "); ! s.println(cdp.unknownDatapoints); ! } ! } ! ! void toXml(PrintStream s) { ! ! 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 (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.ras.seek(dataOffset + (row + 1) * 16); ! ! long lastUpdate = db.lastUpdate.getTime() / 1000; ! int pdpStep = db.header.pdpStep; ! NumberFormat numberFormat = new DecimalFormat("0.0000000000E0"); ! SimpleDateFormat dateFormat = ! new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); ! ! while (counter++ < rowCount) { ! row++; ! ! if (row == rowCount) { ! row = 0; ! ! db.rrdFile.ras.seek(dataOffset); ! } ! ! 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(" --> "); ! ! 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.println("\t\t</database>"); ! s.println("\t</rra>"); ! } ! catch (IOException e) { // Is the best thing to do here? ! throw new RuntimeException(e.getMessage()); ! } ! } ! ! /* ! // THIS IS THE ORIGINAL CODE: BUGGY! Replaced by Sasa Markovic with a new method ! // Funny: the bug will appear only if dsCount != 2 :) ! public double[][] getValuesOriginal() throws IOException { ! if (values != null) { ! return values; ! } ! values = new double[db.header.dsCount][rowCount]; ! int row = currentRow; ! db.rrdFile.ras.seek(dataOffset + (row + 1) * 16); // <----- BUG (resolved below) ! for (int counter = 0; counter < rowCount; counter++) { ! row++; ! if (row == rowCount) { ! row = 0; ! db.rrdFile.ras.seek(dataOffset); ! } ! for (int col = 0; col < db.header.dsCount; col++) { ! double value = db.rrdFile.readDouble(); ! values[col][counter] = value; ! } ! } ! return values; ! } ! */ ! ! // Resolved bug from the original method (see above) ! public double[][] getValues() throws IOException { ! // OK PART ! if (values != null) { ! return values; ! } ! values = new double[db.header.dsCount][rowCount]; ! int row = currentRow; ! // HERE ARE THE DRAGONS! ! db.rrdFile.ras.seek(dataOffset + (row + 1) * db.header.dsCount * 8); ! // OK, TOO! ! for (int counter = 0; counter < rowCount; counter++) { ! row++; ! if (row == rowCount) { ! row = 0; ! db.rrdFile.ras.seek(dataOffset); ! } ! for (int col = 0; col < db.header.dsCount; col++) { ! double value = db.rrdFile.readDouble(); ! values[col][counter] = value; ! } ! } ! return values; ! } ! ! /** ! * Returns the number of primary data points required for a consolidated ! * data point in this archive. ! * ! * @return the number of primary data points required for a consolidated ! * data point in this archive. ! */ ! public int getPdpCount() { ! return pdpCount; ! } ! ! /** ! * Returns the number of entries in this archive. ! * ! * @return the number of entries in this archive. ! */ ! public int getRowCount() { ! return rowCount; ! } ! ! /** ! * Returns the X-Files Factor for this archive. ! * ! * @return the X-Files Factor for this archive. ! */ ! public double getXff() { ! return xff; ! } ! ! /** ! * Returns a summary the contents of this archive. ! * ! * @return a summary of the information contained in this archive. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[Archive: OFFSET=0x"); ! ! sb.append(Long.toHexString(offset)); ! sb.append(", SIZE=0x"); ! sb.append(Long.toHexString(size)); ! sb.append(", type="); ! sb.append(type); ! sb.append(", rowCount="); ! sb.append(rowCount); ! sb.append(", pdpCount="); ! sb.append(pdpCount); ! sb.append(", xff="); ! sb.append(xff); ! sb.append(", currentRow="); ! sb.append(currentRow); ! sb.append("]"); ! ! for (Iterator<CDPStatusBlock> i = cdpStatusBlocks.iterator(); i.hasNext();) { ! CDPStatusBlock cdp = i.next(); ! ! sb.append("\n\t\t"); ! sb.append(cdp.toString()); ! } ! ! return sb.toString(); ! } ! } Index: RRDFile.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/RRDFile.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RRDFile.java 22 Jul 2004 09:34:10 -0000 1.1 --- RRDFile.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,169 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.*; ! ! /** ! * This class is a quick hack to read information from an RRD file. Writing ! * to RRD files is not currently supported. As I said, this is a quick hack. ! * Some thought should be put into the overall design of the file IO. ! * <p/> ! * Currently this can read RRD files that were generated on Solaris (Sparc) ! * and Linux (x86). ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class RRDFile implements Constants { ! ! boolean bigEndian; ! int alignment; ! RandomAccessFile ras; ! byte[] buffer; ! ! RRDFile(String name) throws IOException { ! this(new File(name)); ! } ! ! RRDFile(File file) throws IOException { ! ! ras = new RandomAccessFile(file, "r"); ! buffer = new byte[128]; ! ! initDataLayout(file); ! } ! ! private void initDataLayout(File file) throws IOException { ! ! if (file.exists()) { // Load the data formats from the file ! ras.read(buffer, 0, 24); ! ! int index; ! ! if ((index = indexOf(FLOAT_COOKIE_BIG_ENDIAN, buffer)) != -1) { ! bigEndian = true; ! } else if ((index = indexOf(FLOAT_COOKIE_LITTLE_ENDIAN, buffer)) ! != -1) { ! bigEndian = false; ! } else { ! throw new IOException("Invalid RRD file"); ! } ! ! switch (index) { ! ! case 12: ! alignment = 4; ! break; ! ! case 16: ! alignment = 8; ! break; ! ! default : ! throw new RuntimeException("Unsupported architecture"); ! } ! } else { // Default to data formats for this hardware architecture ! } ! ! ras.seek(0); // Reset file pointer to start of file ! } ! ! private int indexOf(byte[] pattern, byte[] array) { ! return (new String(array)).indexOf(new String(pattern)); ! } ! ! boolean isBigEndian() { ! return bigEndian; ! } ! ! int getAlignment() { ! return alignment; ! } ! ! double readDouble() throws IOException { ! ! //double value; ! byte[] tx = new byte[8]; ! ! ras.read(buffer, 0, 8); ! ! if (bigEndian) { ! tx = buffer; ! } else { ! for (int i = 0; i < 8; i++) { ! tx[7 - i] = buffer[i]; ! } ! } ! ! DataInputStream reverseDis = ! new DataInputStream(new ByteArrayInputStream(tx)); ! ! return reverseDis.readDouble(); ! } ! ! int readInt() throws IOException { ! return readInt(false); ! } ! ! int readInt(boolean dump) throws IOException { ! ! ras.read(buffer, 0, 4); ! ! int value; ! ! if (bigEndian) { ! value = (0xFF & buffer[3]) | ((0xFF & buffer[2]) << 8) ! | ((0xFF & buffer[1]) << 16) | ((0xFF & buffer[0]) << 24); ! } else { ! value = (0xFF & buffer[0]) | ((0xFF & buffer[1]) << 8) ! | ((0xFF & buffer[2]) << 16) | ((0xFF & buffer[3]) << 24); ! } ! ! return value; ! } ! ! String readString(int maxLength) throws IOException { ! ! ras.read(buffer, 0, maxLength); ! ! return new String(buffer, 0, maxLength).trim(); ! } ! ! void skipBytes(int n) throws IOException { ! ras.skipBytes(n); ! } ! ! int align(int boundary) throws IOException { ! ! int skip = (int) (boundary - (ras.getFilePointer() % boundary)) % boundary; ! ! if (skip != 0) { ! ras.skipBytes(skip); ! } ! ! return skip; ! } ! ! int align() throws IOException { ! return align(alignment); ! } ! ! long info() throws IOException { ! return ras.getFilePointer(); ! } ! ! long getFilePointer() throws IOException { ! return ras.getFilePointer(); ! } ! ! void close() throws IOException { ! ras.close(); ! } ! } --- 1,174 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.*; ! ! /** ! * This class is a quick hack to read information from an RRD file. Writing ! * to RRD files is not currently supported. As I said, this is a quick hack. ! * Some thought should be put into the overall design of the file IO. ! * <p/> ! * Currently this can read RRD files that were generated on Solaris (Sparc) ! * and Linux (x86). ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class RRDFile implements Constants { ! ! boolean bigEndian; ! int alignment; ! RandomAccessFile ras; ! byte[] buffer; ! ! RRDFile(String name) throws IOException { ! this(new File(name)); ! } ! ! RRDFile(File file) throws IOException { ! ! ras = new RandomAccessFile(file, "r"); ! buffer = new byte[128]; ! ! initDataLayout(file); ! } ! ! private void initDataLayout(File file) throws IOException { ! ! if (file.exists()) { // Load the data formats from the file ! ras.read(buffer, 0, 24); ! ! int index; ! ! if ((index = indexOf(FLOAT_COOKIE_BIG_ENDIAN, buffer)) != -1) { ! bigEndian = true; ! } ! else if ((index = indexOf(FLOAT_COOKIE_LITTLE_ENDIAN, buffer)) ! != -1) { ! bigEndian = false; ! } ! else { ! throw new IOException("Invalid RRD file"); ! } ! ! switch (index) { ! ! case 12: ! alignment = 4; ! break; ! ! case 16: ! alignment = 8; ! break; ! ! default : ! throw new RuntimeException("Unsupported architecture"); ! } ! } ! else { // Default to data formats for this hardware architecture ! } ! ! ras.seek(0); // Reset file pointer to start of file ! } ! ! private int indexOf(byte[] pattern, byte[] array) { ! return (new String(array)).indexOf(new String(pattern)); ! } ! ! boolean isBigEndian() { ! return bigEndian; ! } ! ! int getAlignment() { ! return alignment; ! } ! ! double readDouble() throws IOException { ! ! //double value; ! byte[] tx = new byte[8]; ! ! ras.read(buffer, 0, 8); ! ! if (bigEndian) { ! tx = buffer; ! } ! else { ! for (int i = 0; i < 8; i++) { ! tx[7 - i] = buffer[i]; ! } ! } ! ! DataInputStream reverseDis = ! new DataInputStream(new ByteArrayInputStream(tx)); ! ! return reverseDis.readDouble(); ! } ! ! int readInt() throws IOException { ! return readInt(false); ! } ! ! int readInt(boolean dump) throws IOException { ! ! ras.read(buffer, 0, 4); ! ! int value; ! ! if (bigEndian) { ! value = (0xFF & buffer[3]) | ((0xFF & buffer[2]) << 8) ! | ((0xFF & buffer[1]) << 16) | ((0xFF & buffer[0]) << 24); ! } ! else { ! value = (0xFF & buffer[0]) | ((0xFF & buffer[1]) << 8) ! | ((0xFF & buffer[2]) << 16) | ((0xFF & buffer[3]) << 24); ! } ! ! return value; ! } ! ! String readString(int maxLength) throws IOException { ! ! ras.read(buffer, 0, maxLength); ! ! return new String(buffer, 0, maxLength).trim(); ! } ! ! void skipBytes(int n) throws IOException { ! ras.skipBytes(n); ! } ! ! int align(int boundary) throws IOException { ! ! int skip = (int) (boundary - (ras.getFilePointer() % boundary)) % boundary; ! ! if (skip != 0) { ! ras.skipBytes(skip); ! } ! ! return skip; ! } ! ! int align() throws IOException { ! return align(alignment); ! } ! ! long info() throws IOException { ! return ras.getFilePointer(); ! } ! ! long getFilePointer() throws IOException { ! return ras.getFilePointer(); ! } ! ! void close() throws IOException { ! ras.close(); ! } ! } Index: Constants.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/Constants.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Constants.java 22 Jul 2004 09:34:10 -0000 1.1 --- Constants.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,26 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! interface Constants { ! ! int DS_NAM_SIZE = 20; ! int DST_SIZE = 20; ! int CF_NAM_SIZE = 20; ! int LAST_DS_LEN = 30; ! static String COOKIE = "RRD"; ! static String VERSION = "0001"; ! double FLOAT_COOKIE = 8.642135E130; ! static byte[] FLOAT_COOKIE_BIG_ENDIAN = {0x5B, 0x1F, 0x2B, 0x43, ! (byte) 0xC7, (byte) 0xC0, 0x25, ! 0x2F}; ! static byte[] FLOAT_COOKIE_LITTLE_ENDIAN = {0x2F, 0x25, (byte) 0xC0, ! (byte) 0xC7, 0x43, 0x2B, 0x1F, ! 0x5B}; ! } --- 1,26 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! interface Constants { ! ! int DS_NAM_SIZE = 20; ! int DST_SIZE = 20; ! int CF_NAM_SIZE = 20; ! int LAST_DS_LEN = 30; ! static String COOKIE = "RRD"; ! static String VERSION = "0001"; ! double FLOAT_COOKIE = 8.642135E130; ! static byte[] FLOAT_COOKIE_BIG_ENDIAN = {0x5B, 0x1F, 0x2B, 0x43, ! (byte) 0xC7, (byte) 0xC0, 0x25, ! 0x2F}; ! static byte[] FLOAT_COOKIE_LITTLE_ENDIAN = {0x2F, 0x25, (byte) 0xC0, ! (byte) 0xC7, 0x43, 0x2B, 0x1F, ! 0x5B}; ! } Index: CDPStatusBlock.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/CDPStatusBlock.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CDPStatusBlock.java 22 Jul 2004 09:34:10 -0000 1.1 --- CDPStatusBlock.java 21 Dec 2006 18:02:42 -0000 1.2 *************** *** 1,86 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.IOException; ! import java.io.PrintStream; ! ! /** ! * Instances of this class model the consolidation data point status from an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class CDPStatusBlock { ! ! long offset; ! long size; ! int unknownDatapoints; ! double value; ! ! CDPStatusBlock(RRDFile file) throws IOException { ! ! offset = file.getFilePointer(); ! value = file.readDouble(); ! unknownDatapoints = file.readInt(); ! ! // Skip rest of cdp_prep_t.scratch ! file.skipBytes(68); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the number of unknown primary data points that were integrated. ! * ! * @return the number of unknown primary data points that were integrated. ! */ ! public int getUnknownDatapoints() { ! return unknownDatapoints; ! } ! ! /** ! * Returns the value of this consolidated data point. ! * ! * @return the value of this consolidated data point. ! */ ! public double getValue() { ! return value; ! } ! ! void toXml(PrintStream s) { ! ! s.print("\t\t\t<ds><value> "); ! s.print(value); ! s.print(" </value> <unknown_datapoints> "); ! s.print(unknownDatapoints); ! s.println(" </unknown_datapoints></ds>"); ! } ! ! /** ! * Returns a summary the contents of this CDP status block. ! * ! * @return a summary of the information contained in the CDP status block. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[CDPStatusBlock: OFFSET=0x"); ! ! sb.append(Long.toHexString(offset)); ! sb.append(", SIZE=0x"); ! sb.append(Long.toHexString(size)); ! sb.append(", unknownDatapoints="); ! sb.append(unknownDatapoints); ! sb.append(", value="); ! sb.append(value); ! sb.append("]"); ! ! return sb.toString(); ! } ! } --- 1,86 ---- ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.IOException; ! import java.io.PrintStream; ! ! /** ! * Instances of this class model the consolidation data point status from an RRD file. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class CDPStatusBlock { ! ! long offset; ! long size; ! int unknownDatapoints; ! double value; ! ! CDPStatusBlock(RRDFile file) throws IOException { ! ! offset = file.getFilePointer(); ! value = file.readDouble(); ! unknownDatapoints = file.readInt(); ! ! // Skip rest of cdp_prep_t.scratch ! file.skipBytes(68); ! ! size = file.getFilePointer() - offset; ! } ! ! /** ! * Returns the number of unknown primary data points that were integrated. ! * ! * @return the number of unknown primary data points that were integrated. ! */ ! public int getUnknownDatapoints() { ! return unknownDatapoints; ! } ! ! /** ! * Returns the value of this consolidated data point. ! * ! * @return the value of this consolidated data point. ! */ ! public double getValue() { ! return value; ! } ! ! void toXml(PrintStream s) { ! ! s.print("\t\t\t<ds><value> "); ! s.print(value); ! s.print(" </value> <unknown_datapoints> "); ! s.print(unknownDatapoints); ! s.println(" </unknown_datapoints></ds>"); ! } ! ! /** ! * Returns a summary the contents of this CDP status block. ! * ! * @return a summary of the information contained in the CDP status block. ! */ ! public String toString() { ! ! StringBuffer sb = new StringBuffer("[CDPStatusBlock: OFFSET=0x"); ! ! sb.append(Long.toHexString(offset)); ! sb.append(", SIZE=0x"); ! sb.append(Long.toHexString(size)); ! sb.append(", unknownDatapoints="); ! sb.append(unknownDatapoints); ! sb.append(", value="); ! sb.append(value); ! sb.append("]"); ! ! return sb.toString(); ! } ! } Index: RRDatabase.java =================================================================== RCS file: /cvsroot/jrobin/src/org/jrobin/core/jrrd/RRDatabase.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RRDatabase.java 22 Jul 2004 09:36:33 -0000 1.2 --- RRDatabase.java 21 Dec 2006 18:02:42 -0000 1.3 *************** *** 1,484 **** ! /* ! * Copyright (C) 2001 Ciaran Treanor <ci...@co...> ! * ! * Distributable under GPL license. ! * See terms of license at gnu.org. ! * ! * $Id$ ! */ ! package org.jrobin.core.jrrd; ! ! import java.io.*; ! import java.util.*; ! import java.text.NumberFormat; ! import java.text.DecimalFormat; ! ! /** ! * Instances of this class model ! * <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/">Round Robin Database</a> ! * (RRD) files. ! * ! * @author <a href="mailto:ci...@co...">Ciaran Treanor</a> ! * @version $Revision$ ! */ ! public class RRDatabase { ! ! RRDFile rrdFile; ! ! // RRD file name ! private String name; ! Header header; ! ArrayList dataSources; ! ArrayList archives; ! Date lastUpdate; ! ! /** ! * Creates a database to read from. ! * ! * @param name the filename of the file to read from. ! * @throws IOException if an I/O error occurs. ! */ ! public RRDatabase(String name) throws IOException { ! this(new File(name)); ! } ! ! /** ! * Creates a database to read from. ! * ! * @param file the file to read from. ! * @throws IOException if an I/O error occurs. ! */ ! public RRDatabase(File file) throws IOException { ! ! name = file.getName(); ! rrdFile = new RRDFile(file); ! header = new Header(rrdFile); ! ! // Load the data sources ! dataSources = new ArrayList(); ! ! for (int i = 0; i < header.dsCount; i++) { ! DataSource ds = new DataSource(rrdFile); ! ! dataSources.add(ds); ! } ! ! // Load the archives ! archives = new ArrayList(); ! ! for (int i = 0; i < header.rraCount; i++) { ! Archive archive = new Archive(this); ! ! archives.add(archive); ! } ! ! rrdFile.align(); ! ! lastUpdate = new Date((long) (rrdFile.readInt()) * 1000); ! ! // Load PDPStatus(s) ! for (int i = 0; i < header.dsCount; i++) { ! DataSource ds = (DataSource) dataSources.get(i); ! ! ds.loadPDPStatusBlock(rrdFile); ! } ! ! // Load CDPStatus(s) ! for (int i = 0; i < header.rraCount; i++) { ! Archive archive = (Archive) archives.get(i); ! ! archive.loadCDPStatusBlocks(rrdFile, header.dsCount); ! } ! ! // Load current row information for each archive ! for (int i = 0; i < header.rraCount; i++) { ! Archive archive = (Archive) archives.get(i); ! ! archive.loadCurrentRow(rrdFile); ! } ! ! // Now load the data ! for (int i = 0; i < header.rraCount; i++) { ! Archive archive = (Archive) archives.get(i); ! ! archive.loadData(rrdFile, header.dsCount); ! } ! } ! ! /** ! * Returns the <code>Header</code> for this database. ! * ! * @return the <code>Header</code> for this database. ! */ ! public Header getHeader() { ! return header; ! } ! ! /** ! * Returns the date this database was last updated. To convert this date to ! * the form returned by <code>rrdtool last</code> call Date.getTime() and ! * divide the result by 1000. ! * ! * @return the date this database was last updated. ! */ ! public Date getLastUpdate() { ! return lastUpdate; ! } ! ! /** ! * Returns the <code>DataSource</code> at the specified position in this database. ! * ! * @param index index of <code>DataSource</code> to return. ! * @return the <code>DataSource</code> at the specified position in this database ! */ ! public DataSource getDataSource(int index) { ! return (DataSource) dataSources.get(index); ! } ! ! /** ! * Returns an iterator over the data sources in this database in proper sequence. ! * ! * @return an iterator over the data sources in this database in proper sequence. ! */ ! public Iterator getDataSources() { ! return dataSources.iterator(); ! } ! ! /** ! * Returns the <code>Archive</code> at the specified position in this database. ! * ! * @param index index of <code>Archive</code> to return. ! * @return the <code>Archive</code> at the specified position in this database. ! */ ! public Archive getArchi... [truncated message content] |