#!/usr/local/bin/perl

#
# dbrowdiff
# Copyright (C) 1991-1998 by John Heidemann <johnh@isi.edu>
# $Id: dbrowdiff,v 1.17 2000/01/30 05:41:40 johnh Exp $
#
# This program is distributed under terms of the GNU general
# public license, version 2.  See the file COPYING
# in $dblibdir for details.
#
sub usage {
    print <<END;
usage: $0 [-c|-i] column

    Options:
    -c    cumulative mode (default)
    -i    incremental mode

    For a given column, comput the differences between each row
    of the table.  Differences are output to three columns:
    absdiff and pctdiff.

    In cumulative mode, differences are taken from the first row.
    In incremental mode each row is subtracted from the previous row.

Sample input:
#h      event   clock
_null_getpage+128       815812813.281756
_null_getpage+128       815812813.328709
_null_getpage+128       815812813.353830
_null_getpage+128       815812813.357169
_null_getpage+128       815812813.375844
_null_getpage+128       815812813.378358
#  | /home/johnh/BIN/DB/dbrow 
#  | /home/johnh/BIN/DB/dbcol event clock

Sample command:
cat DATA/kitrace.jdb | dbrowdiff clock

Sample output:
#h      event   clock   absdiff pctdiff
_null_getpage+128       815812813.281756        0       0
_null_getpage+128       815812813.328709        0.046953        5.7554e-09
_null_getpage+128       815812813.353830        0.072074        8.8346e-09
_null_getpage+128       815812813.357169        0.075413        9.2439e-09
_null_getpage+128       815812813.375844        0.094088        1.1533e-08
_null_getpage+128       815812813.378358        0.096602        1.1841e-08
#  | /home/johnh/BIN/DB/dbrow 
#  | /home/johnh/BIN/DB/dbcol event clock
#  | dbrowdiff clock
END
    exit 1;
}


BEGIN {
    $dblibdir = "/usr/local/lib/jdb";
    push(@INC, $dblibdir);
}
require "$dblibdir/dblib.pl";
use DbGetopt;

@orig_argv = @ARGV;
my($prog) = &progname;

# option processing
$format = "%.5g";
$incremental_mode = 0;
my($dbopts) = new DbGetopt("ci?", \@ARGV);
my($ch);
while ($dbopts->getopt) {
    $ch = $dbopts->opt;
    if ($ch eq 'c') {
	$incremental_mode = 0;
    } elsif ($ch eq 'i') {
	$incremental_mode = 1;
    } else {
	&usage;
    };
};

&usage if ($#ARGV != 0);


&readprocess_header;
$xf = $colnametonum{$ARGV[0]};
die ("$prog: unknown column name ``$ARGV[0]''.\n") if (!defined($xf));

#
# new columns
#
$absdiff_f = &col_create("absdiff");
$pctdiff_f = &col_create("pctdiff");
&write_header();

$base = undef;
while (<STDIN>) {
    &pass_comments && next;
    &split_cols;

    if ($base == undef) {
    	$base = $f[$xf];
    	$absdiff = $pctdiff = 0.0;
	$pctdiff = "n/a" if ($base == 0);
    } else {
    	$absdiff = $f[$xf] - $base;
	$pctdiff = ($absdiff / $base) * 100.0 if ($base != 0);
	$absdiff = sprintf("$format", $absdiff);
	$pctdiff = sprintf("$format", $pctdiff);
	$base = $f[$xf] if ($incremental_mode);
    };
    $f[$absdiff_f] = $absdiff;
    $f[$pctdiff_f] = $pctdiff;

    &write_cols;
};

print "#  | $prog ", join(" ", @orig_argv), "\n";
exit 0;
