#!/usr/bin/perl # # avg-pkg-build-time: display average build times of packages # Copyright (C) 1998 Roman Hodek # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # $Id$ # ($main::HOME = $ENV{'HOME'}) or die "HOME not defined in environment!\n"; package conf; $HOME = $main::HOME; require "/etc/sbuild.conf" if -r "/etc/sbuild.conf"; require "$HOME/.sbuildrc" if -r "$HOME/.sbuildrc"; package main; die "No avg-time database defined\n" if !$conf::avg_time_db; use strict; use GDBM_File; use File::Basename; my $do_space = 0; my $delmode = 0; my $dumpmode = 0; my $addmode = 0; my $topmode = 0; my $open_mode = GDBM_READER; my $db_file = $conf::avg_time_db; if (basename($0) =~ /space$/) { $do_space = 1; $db_file = $conf::avg_space_db; } while( @ARGV && $ARGV[0] =~ /^-/ ) { $_ = shift @ARGV; if (/^(-s|--space)$/) { $do_space = 1; $db_file = $conf::avg_space_db; } elsif (/^--delete$/) { $delmode = 1; $open_mode = GDBM_WRCREAT; } elsif (/^--dump$/) { $dumpmode = 1; } elsif (/^(-a|--add)$/) { $addmode = 1; $open_mode = GDBM_WRCREAT; } elsif (/^(-t|--top)$/) { $topmode = 1; } elsif (/^(-f|--dbfile)$/) { die "-f need argument\n" if !@ARGV; $db_file = shift @ARGV; } } my %db; tie %db, 'GDBM_File', $db_file, $open_mode, 0664 or die "Can't open db\n"; die "No packages given for --delete.\n" if $delmode && !@ARGV; if ($addmode) { die "Args for --add must be package and a build time\n" if @ARGV != 2 || $ARGV[1] !~ /^[\d.:]+$/; my($pkg,$t) = @ARGV; if (!$do_space) { if ($t =~ /:/) { my @a = split( ':', $t ); my $x; for( $t = 0; $x = shift @a; ) { $t = ($t * 60) + $x; } } } if (exists $db{$pkg}) { if (!$do_space) { my @times = split( /\s+/, $db{$pkg} ); push( @times, $t ); my $sum = 0; foreach (@times[1..$#times]) { $sum += $_; } $times[0] = $sum / (@times-1); $db{$pkg} = join( ' ', @times ); } else { my $keepvals = 4; my @values = split( /\s+/, $db{$pkg} ); shift @values; unshift( @values, $t ); pop @values if @values > $keepvals; my ($sum, $n, $weight, $i) = (0, 0, scalar(@values)); for( $i = 0; $i < @values; ++$i) { $sum += $values[$i] * $weight; $n += $weight; } unshift( @values, $sum/$n ); $db{$pkg} = join( ' ', @values ); } } else { $db{$pkg} = "$t $t"; } } else { my $pkg; my @pkgs = sort sortfunc (@ARGV ? @ARGV : keys %db); foreach $pkg (@pkgs) { if (exists $db{$pkg}) { if ($delmode) { delete $db{$pkg}; print "$pkg: deleted\n"; } elsif ($dumpmode) { print "$pkg: $db{$pkg}\n"; } else { if (!$do_space) { my @times = split( /\s+/, $db{$pkg} ); my $t = $times[0]; my($sum, $sumq) = (0, 0); foreach (@times[1..$#times]) { $sum += $_; $sumq += $_*$_; } my $sigma; $sigma = (@times <= 2) ? 0 : sqrt( ($sumq - $sum*$sum/(@times-1))/(@times-2) ); printf "%s%02d:%02d:%02d (%d %s, sigma %02d:%02d:%02d)\n", align($pkg), int($t/3600), int(($t%3600)/60), int($t%60), @times-1, (@times == 2) ? "entry" : "entries", int($sigma/3600), int(($sigma%3600)/60), int($sigma%60); } else { my @values = split( /\s+/, $db{$pkg} ); printf "%s%6dk (%dk lastest)\n", align($pkg), $values[0], $values[1]; } } } else { print "$pkg: unknown\n"; } } } untie %db; exit 0; sub align { my $str = shift; $str .= ":"; my $l = length($str); $str .= "\t" if $l < 24; $str .= "\t" if $l < 16; $str .= "\t" if $l < 8; return $str; } sub sortfunc { if ($topmode) { my $tima = (split( /\s+/, $db{$a} ))[0]; my $timb = (split( /\s+/, $db{$b} ))[0]; return $timb <=> $tima; } else { return $a cmp $b; } }