From 0163faefef02207ad0ea3330af688103633293ff Mon Sep 17 00:00:00 2001 From: Pim van den Berg Date: Fri, 10 May 2013 21:36:54 +0200 Subject: import js directory from jsrrdgraph for client side graph rendering Source: https://github.com/manuelluis/jsrrdgraph@276b880 --- js/rrdFile.js | 408 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 js/rrdFile.js (limited to 'js/rrdFile.js') diff --git a/js/rrdFile.js b/js/rrdFile.js new file mode 100644 index 0000000..870c88e --- /dev/null +++ b/js/rrdFile.js @@ -0,0 +1,408 @@ +/* + * Client library for access to RRD archive files + * Part of the javascriptRRD package + * Copyright (c) 2009-2010 Frank Wuerthwein, fkw@ucsd.edu + * Igor Sfiligoi, isfiligoi@ucsd.edu + * + * Original repository: http://javascriptrrd.sourceforge.net/ + * + * MIT License [http://www.opensource.org/licenses/mit-license.php] + * + */ + +/* + * + * RRDTool has been developed and is maintained by + * Tobias Oether [http://oss.oetiker.ch/rrdtool/] + * + * This software can be used to read files produced by the RRDTool + * but has been developed independently. + * + * Limitations: + * + * This version of the module assumes RRD files created on linux + * with intel architecture and supports both 32 and 64 bit CPUs. + * All integers in RRD files are suppoes to fit in 32bit values. + * + * Only versions 3 and 4 of the RRD archive are supported. + * + * Only AVERAGE,MAXIMUM,MINIMUM and LAST consolidation functions are + * supported. For all others, the behaviour is at the moment undefined. + * + */ + +/* + * Dependencies: + * + * The data provided to this module require an object of a class + * that implements the following methods: + * getByteAt(idx) - Return a 8 bit unsigned integer at offset idx + * getLongAt(idx) - Return a 32 bit unsigned integer at offset idx + * getDoubleAt(idx) - Return a double float at offset idx + * getFastDoubleAt(idx) - Similar to getDoubleAt but with less precision + * getCStringAt(idx,maxsize) - Return a string of at most maxsize characters + * that was 0-terminated in the source + * + * The BinaryFile from binaryXHR.js implements this interface. + * + */ + + +// ============================================================ +// Exception class +function InvalidRRD(msg) { + this.message=msg; + this.name="Invalid RRD"; +} + +// pretty print +InvalidRRD.prototype.toString = function() { + return this.name + ': "' + this.message + '"'; +} + + +// ============================================================ +// RRD DS Info class +function RRDDS(rrd_data,rrd_data_idx,my_idx) { + this.rrd_data=rrd_data; + this.rrd_data_idx=rrd_data_idx; + this.my_idx=my_idx; +} + +RRDDS.prototype.getIdx = function() { + return this.my_idx; +} +RRDDS.prototype.getName = function() { + return this.rrd_data.getCStringAt(this.rrd_data_idx,20); +} +RRDDS.prototype.getType = function() { + return this.rrd_data.getCStringAt(this.rrd_data_idx+20,20); +} +RRDDS.prototype.getMin = function() { + return this.rrd_data.getDoubleAt(this.rrd_data_idx+48); +} +RRDDS.prototype.getMax = function() { + return this.rrd_data.getDoubleAt(this.rrd_data_idx+56); +} + + +// ============================================================ +// RRD RRA Info class +function RRDRRAInfo(rrd_data,rra_def_idx, + rrd_align,row_cnt,pdp_step,my_idx) { + this.rrd_data=rrd_data; + this.rra_def_idx=rra_def_idx; + this.rrd_align=rrd_align; + this.row_cnt=row_cnt; + this.pdp_step=pdp_step; + this.my_idx=my_idx; +} + +RRDRRAInfo.prototype.getIdx = function() { + return this.my_idx; +} + +// Get number of rows +RRDRRAInfo.prototype.getNrRows = function() { + return this.row_cnt; +} + +// Get number of slots used for consolidation +// Mostly for internal use +RRDRRAInfo.prototype.getPdpPerRow = function() { + if (this.rrd_align==32) + return this.rrd_data.getLongAt(this.rra_def_idx+24,20); + else + return this.rrd_data.getLongAt(this.rra_def_idx+32,20); +} + +// Get RRA step (expressed in seconds) +RRDRRAInfo.prototype.getStep = function() { + return this.pdp_step*this.getPdpPerRow(); +} + +// Get consolidation function name +RRDRRAInfo.prototype.getCFName = function() { + return this.rrd_data.getCStringAt(this.rra_def_idx,20); +} + + +// ============================================================ +// RRD RRA handling class +function RRDRRA(rrd_data,rra_ptr_idx, + rra_info, + header_size,prev_row_cnts,ds_cnt) { + this.rrd_data=rrd_data; + this.rra_info=rra_info; + this.row_cnt=rra_info.row_cnt; + this.ds_cnt=ds_cnt; + + var row_size=ds_cnt*8; + + this.base_rrd_db_idx=header_size+prev_row_cnts*row_size; + + // get imediately, since it will be needed often + this.cur_row=rrd_data.getLongAt(rra_ptr_idx); + + // calculate idx relative to base_rrd_db_idx + // mostly used internally + this.calc_idx = function(row_idx,ds_idx) { + if ((row_idx>=0) && (row_idx=0) && (ds_idx=this.row_cnt) real_row_idx-=this.row_cnt; + return row_size*real_row_idx+ds_idx*8; + } else { + throw RangeError("DS idx ("+ row_idx +") out of range [0-" + ds_cnt +")."); + } + } else { + throw RangeError("Row idx ("+ row_idx +") out of range [0-" + this.row_cnt +")."); + } + } +} + +RRDRRA.prototype.getIdx = function() { + return this.rra_info.getIdx(); +} + +// Get number of rows/columns +RRDRRA.prototype.getNrRows = function() { + return this.row_cnt; +} +RRDRRA.prototype.getNrDSs = function() { + return this.ds_cnt; +} + +// Get RRA step (expressed in seconds) +RRDRRA.prototype.getStep = function() { + return this.rra_info.getStep(); +} + +// Get consolidation function name +RRDRRA.prototype.getCFName = function() { + return this.rra_info.getCFName(); +} + +RRDRRA.prototype.getEl = function(row_idx,ds_idx) { + return this.rrd_data.getDoubleAt(this.base_rrd_db_idx+this.calc_idx(row_idx,ds_idx)); +} + +// Low precision version of getEl +// Uses getFastDoubleAt +RRDRRA.prototype.getElFast = function(row_idx,ds_idx) { + return this.rrd_data.getFastDoubleAt(this.base_rrd_db_idx+this.calc_idx(row_idx,ds_idx)); +} + +// ============================================================ +// RRD Header handling class +function RRDHeader(rrd_data) { + this.rrd_data=rrd_data; + this.validate_rrd(); + this.load_header(); + this.calc_idxs(); +} + +// Internal, used for initialization +RRDHeader.prototype.validate_rrd = function() { + if (this.rrd_data.getCStringAt(0,4)!=="RRD") throw new InvalidRRD("Wrong magic id."); + + this.rrd_version=this.rrd_data.getCStringAt(4,5); + if ((this.rrd_version!=="0003")&&(this.rrd_version!=="0004")) { + throw new InvalidRRD("Unsupported RRD version "+this.rrd_version+"."); + } + + if (this.rrd_data.getDoubleAt(12)==8.642135e+130) { + this.rrd_align=32; + } else if (this.rrd_data.getDoubleAt(16)==8.642135e+130) { + this.rrd_align=64; + } else { + throw new InvalidRRD("Unsupported platform."); + } +} + +// Internal, used for initialization +RRDHeader.prototype.load_header = function() { + if (this.rrd_align==32) { + this.ds_cnt=this.rrd_data.getLongAt(20,false); + this.rra_cnt=this.rrd_data.getLongAt(24,false); + this.pdp_step=this.rrd_data.getLongAt(28,false); + // 8*10 unused values follow + this.top_header_size=112; + } else { + //get only the low 32 bits, the high 32 should always be 0 + this.ds_cnt=this.rrd_data.getLongAt(24,false); + this.rra_cnt=this.rrd_data.getLongAt(32,false); + this.pdp_step=this.rrd_data.getLongAt(40,false); + // 8*10 unused values follow + this.top_header_size=128; + } +} + +// Internal, used for initialization +RRDHeader.prototype.calc_idxs = function() { + this.ds_def_idx=this.top_header_size; + // char ds_nam[20], char dst[20], unival par[10] + this.ds_el_size=120; + + this.rra_def_idx=this.ds_def_idx+this.ds_el_size*this.ds_cnt; + // char cf_nam[20], uint row_cnt, uint pdp_cnt, unival par[10] + this.row_cnt_idx; + if (this.rrd_align==32) { + this.rra_def_el_size=108; + this.row_cnt_idx=20; + } else { + this.rra_def_el_size=120; + this.row_cnt_idx=24; + } + + this.live_head_idx=this.rra_def_idx+this.rra_def_el_size*this.rra_cnt; + // time_t last_up, int last_up_usec + if (this.rrd_align==32) { + this.live_head_size=8; + } else { + this.live_head_size=16; + } + + this.pdp_prep_idx=this.live_head_idx+this.live_head_size; + // char last_ds[30], unival scratch[10] + this.pdp_prep_el_size=112; + + this.cdp_prep_idx=this.pdp_prep_idx+this.pdp_prep_el_size*this.ds_cnt; + // unival scratch[10] + this.cdp_prep_el_size=80; + + this.rra_ptr_idx=this.cdp_prep_idx+this.cdp_prep_el_size*this.ds_cnt*this.rra_cnt; + // uint cur_row + if (this.rrd_align==32) { + this.rra_ptr_el_size=4; + } else { + this.rra_ptr_el_size=8; + } + + this.header_size=this.rra_ptr_idx+this.rra_ptr_el_size*this.rra_cnt; +} + +// Optional initialization +// Read and calculate row counts +RRDHeader.prototype.load_row_cnts = function() { + this.rra_def_row_cnts=[]; + this.rra_def_row_cnt_sums=[]; // how many rows before me + for (var i=0; i=0) && (idx=0) && (idx