From bf002a03d47f2a835cc4bddd666e8d65eea8c33a Mon Sep 17 00:00:00 2001 From: alisonjm Date: Wed, 8 Jun 2011 21:34:27 +0000 Subject: Added two Filters for RRA - one to average RRAs and increase their timestep, and one to timeshift for timezones. --- src/lib/rrdFilter.js | 157 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 149 insertions(+), 8 deletions(-) diff --git a/src/lib/rrdFilter.js b/src/lib/rrdFilter.js index e37038c..3406769 100644 --- a/src/lib/rrdFilter.js +++ b/src/lib/rrdFilter.js @@ -60,7 +60,6 @@ RRDRRAFilterDS.prototype.getElFast = function(row_idx,ds_idx) { } } - // -------------------------------------------------- function RRDFilterDS(rrd_file,ds_id_list) { this.rrd_file=rrd_file; @@ -75,7 +74,7 @@ function RRDFilterDS(rrd_file,ds_id_list) { this.ds_list.push(new_ds); } } -RRDFilterDS.prototype.getMinSteps = function() {return this.rrd_file.getMinSteps();} +RRDFilterDS.prototype.getMinStep = function() {return this.rrd_file.getMinStep();} RRDFilterDS.prototype.getLastUpdate = function() {return this.rrd_file.getLastUpdate();} RRDFilterDS.prototype.getNrDSs = function() {return this.ds_list.length;} @@ -126,12 +125,25 @@ RRDFilterDS.prototype.getRRA = function(idx) {return new RRDRRAFilterDS(this.rrd // computeResult(val_list) - val_list contains the values of the requested DSs (in the same order) // Example class that implements the interface: -// function sumDS(ds1,ds2) { -// this.getName = function() {return ds1+"+"+ds2;} -// this.getDSNames = function() {return [ds1,ds2];} +// function DoNothing(ds_name) { //Leaves the DS alone. +// this.getName = function() {return ds_name;} +// this.getDSNames = function() {return [ds1_name];} +// this.computeResult = function(val_list) {return val_list[0];} +// } +// function sumDS(ds1_name,ds2_name) { //Sums the two DSs. +// this.getName = function() {return ds1_name+"+"+ds2_name;} +// this.getDSNames = function() {return [ds1_name,ds2_name];} // this.computeResult = function(val_list) {return val_list[0]+val_list[1];} // } +// +// So to add a summed DS of your 1st and second DS: +// var ds0_name = rrd_data.getDS(0).getName(); +// var ds1_name = rrd_data.getDS(1).getName(); +// rrd_data = new RRDFilterOp(rrd_data, [new DoNothing(ds0_name), +// DoNothing(ds1_name), sumDS(ds0_name, ds1_name]); +//////////////////////////////////////////////////////////////////// +//Private function RRDDSFilterOp(rrd_file,op_obj,my_idx) { this.rrd_file=rrd_file; this.op_obj=op_obj; @@ -154,7 +166,8 @@ RRDDSFilterOp.prototype.getMax = function() {return undefined;} RRDDSFilterOp.prototype.getRealDSList = function() { return this.ds_idx_list;} RRDDSFilterOp.prototype.computeResult = function(val_list) {return this.op_obj.computeResult(val_list);} -// -------------------------------------------------- +// ------ -------------------------------------------- +//Private function RRDRRAFilterOp(rrd_rra,ds_list) { this.rrd_rra=rrd_rra; this.ds_list=ds_list; @@ -190,6 +203,7 @@ RRDRRAFilterOp.prototype.getElFast = function(row_idx,ds_idx) { } // -------------------------------------------------- +//Public function RRDFilterOp(rrd_file,op_obj_list) { this.rrd_file=rrd_file; this.ds_list=[]; @@ -197,9 +211,8 @@ function RRDFilterOp(rrd_file,op_obj_list) { this.ds_list.push(new RRDDSFilterOp(rrd_file,op_obj_list[i],i)); } } -RRDFilterOp.prototype.getMinSteps = function() {return this.rrd_file.getMinSteps();} +RRDFilterOp.prototype.getMinStep = function() {return this.rrd_file.getMinStep();} RRDFilterOp.prototype.getLastUpdate = function() {return this.rrd_file.getLastUpdate();} - RRDFilterOp.prototype.getNrDSs = function() {return this.ds_list.length;} RRDFilterOp.prototype.getDSNames = function() { var ds_names=[]; @@ -240,3 +253,131 @@ RRDFilterOp.prototype.getNrRRAs = function() {return this.rrd_file.getNrRRAs();} RRDFilterOp.prototype.getRRAInfo = function(idx) {return this.rrd_file.getRRAInfo(idx);} RRDFilterOp.prototype.getRRA = function(idx) {return new RRDRRAFilterOp(this.rrd_file.getRRA(idx),this.ds_list);} +// ================================================================ +// Shift RRAs in rra_list by the integer shift_int (in seconds). +// Only change is getLastUpdate - this takes care of everything. +// Example: To shift the first three 3 RRAs in the file by one hour, +// rrd_data = new RRAFilterShift(rra_data, 3600, [0,1,2]); + +function RRAFilterShift(rrd_file, shift_int, rra_list) { + this.rrd_file = rrd_file; + this.shift_int = shift_int; + this.rra_list = rra_list; + this.shift_in_seconds = this.shift_int*3600; //number of steps needed to move 1 hour +} +RRAFilterShift.prototype.getMinStep = function() {return this.rrd_file.getMinStep();} +RRAFilterShift.prototype.getLastUpdate = function() {return this.rrd_file.getLastUpdate()+this.shift_in_seconds;} +RRAFilterShift.prototype.getNrDSs = function() {return this.rrd_file.getNrDSs();} +RRAFilterShift.prototype.getDSNames = function() {return this.rrd_file.getDSNames();} +RRAFilterShift.prototype.getDS = function(id) {return this.rrd_file.getDS(id);} +RRAFilterShift.prototype.getNrRRAs = function() {return this.rra_list.length;} +RRAFilterShift.prototype.getRRAInfo = function(idx) {return this.rrd_file.getRRAInfo(idx);} +RRAFilterShift.prototype.getRRA = function(idx) {return this.rrd_file.getRRA(idx);} + +// ================================================================ +// Filter RRAs by using a user provided filter object +// The object must implement the following interface +// getIdx() - Index of RRA to use +// getStep() - new step size (return null to use step size of RRA specified by getIdx() + +/* Example classes that implements the interface: +* +* //This RRA Filter object leaves the original RRA unchanged. +* +* function RRADoNothing(rra_idx) { +* this.getIdx = function() {return rra_idx;} +* this.getStep = function() {return null;} +* } +* +* // This Filter creates a new RRA with a different step size +* // based on another RRA, whose data the new RRA averages. +* // rra_idx should be index of RRA with largest step size +* // that doesn't exceed new step size. +* +* function RRA_Avg(rra_idx,new_step_in_seconds) { +* this.getIdx = function() {return rra_idx;} +* this.getStep = function() {return new_step_in_seconds;} +* } +* //For example, if you have two RRAs, one with a 5 second step, +* //and another with a 60 second step, and you'd like a 30 second step, +* //rrd_data = new RRDRRAFilterShift(rrd_data,[new RRADoNothing(0), new RRDDoNothing(1),new RRA_Avg(1,30)];) +*/ + +//Private Function +function RRAInfoFilterAvg(rrd_file, rra, op_obj, idx) { + this.rrd_file = rrd_file; + this.op_obj = op_obj; + this.base_rra = rrd_file.getRRA(this.op_obj.getIdx()); + this.rra = rra; + this.idx = idx; + var scaler = 1; + if (this.op_obj.getStep()!=null) {scaler = this.op_obj.getStep()/this.base_rra.getStep();} + this.scaler = scaler; +} +RRAInfoFilterAvg.prototype.getIdx = function() {return this.idx;} +RRAInfoFilterAvg.prototype.getNrRows = function() {return this.rra.getNrRows();} //draw info from RRAFilterAvg +RRAInfoFilterAvg.prototype.getStep = function() {return this.rra.getStep();} +RRAInfoFilterAvg.prototype.getCFName = function() {return this.rra.getCFName();} +RRAInfoFilterAvg.prototype.getPdpPerRow = function() {return this.rrd_file.getRRAInfo(this.op_obj.getIdx()).getPdpPerRow()*this.scaler;} + +//--------------------------------------------------------------------------- +//Private Function +function RRAFilterAvg(rrd_file, op_obj) { + this.rrd_file = rrd_file; + this.op_obj = op_obj; + this.base_rra = rrd_file.getRRA(op_obj.getIdx()); + var scaler=1; + if (op_obj.getStep()!=null) {scaler = op_obj.getStep()/this.base_rra.getStep();} + this.scaler = Math.floor(scaler); + //document.write(this.scaler+","); +} +RRAFilterAvg.prototype.getIdx = function() {return this.op_obj.getIdx();} +RRAFilterAvg.prototype.getCFName = function() {return this.base_rra.getCFName();} +RRAFilterAvg.prototype.getNrRows = function() {return Math.floor(this.base_rra.getNrRows()/this.scaler);} +RRAFilterAvg.prototype.getNrDSs = function() {return this.base_rra.getNrDSs();} +RRAFilterAvg.prototype.getStep = function() { + if(this.op_obj.getStep()!=null) { + return this.op_obj.getStep(); + } else { return this.base_rra.getStep();} +} +RRAFilterAvg.prototype.getEl = function(row,ds) { + var sum=0; + for(var i=0;i=0) && (idx=0) && (idx