Sorry for visiting back on this Aaron Sir.
Actually I need to calculate AVERAGE and MAXIMUM within each group the same way we did for SUM earlier. I was able to draft AVERAGE logic and it works fine, but I am not able to derive MAXIMUM.
Could you please help me on this and guide me please if my approach for AVERAGE can be written in still more efficient way.
AVERAGE logic :- SUM($speed)/ DISTINCT($servers) * 60 for Hour
MAXIMUM logic :- MAX($speed) across all the $servers within each Hour
#!/usr/bin/env perl
use strict; use warnings;
my %h; my %m; my %db; my %sr;
sub round {
$_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5)
}
sub fnd_max (\%) {
my $hash = shift;
my ($key, @keys) = keys %$hash;
my ($big, @vals) = values %$hash;
for (0 .. $#keys) {
if ($vals[$_] > $big) {
$big = $vals[$_];
$key = $keys[$_];
}
}
$big
}
sub set_column_widths {
my $h = shift;
my $databases = shift;
my $names = shift;
for my $key (keys %$h){
for my $db (@$names){
my $l = length $h->{$key}{$db};
$databases->{$db} = $databases->{$db} > $l ? $databases->{
+$db} : $l;
}
}
for my $db (@$names){ # check the width of the database names the
+mselves too
my $l = length $db;
$databases->{$db} = $databases->{$db} > $l ? $databases->{$db}
+ : $l;
}
}
while(<DATA>){
next unless /\w/;
my($server,$datetime,$database,$speed) = (split)[0,1,2,3];
my $ddhhmm = substr $datetime,0,16;
my $ddhh = substr $datetime,0,13;
$h{$ddhh }{$database} += $speed;
$m{$ddhhmm}{$database} += $speed;
$db{$database} = 1;
$sr{$server } = 1;
}
my @db = sort keys %db; # sort and save database names as array since
+we'll be looping through them many times
my $count = keys %sr;
# HOUR SECTION START - AVG
for my $key (sort keys %h){
for (@db) { $h{$key}{$_} = round($h{$key}{$_} / ($count * 60))} ;
}
set_column_widths(\%h, \%db, \@db);
print "Frequency Hour:\ncollectionTime";
printf " %$db{$_}s", $_ for (@db);
print "\n";
for my $key (sort keys %h){
print "$key ";
printf " %$db{$_}s", $h{$key}{$_} for (@db);
print "\n";
}
# HOUR SECTION END - AVG
# MINUTE SECTION START - AVG
for my $key (sort keys %m){
for (@db) { $m{$key}{$_} = round($m{$key}{$_} / ($count))} ;
}
set_column_widths(\%m, \%db, \@db);
print "\nFrequency Minute:\n collectionTime";
printf " %$db{$_}s", $_ for (@db);
print "\n";
for my $key (sort keys %m){
print $key;
printf " %$db{$_}s", $m{$key}{$_} for (@db);
print "\n";
}
# MINUTE SECTION END - AVG
# HOUR SECTION START - MAX
set_column_widths(\%h, \%db, \@db);
print "Frequency Hour:\ncollectionTime";
printf " %$db{$_}s", $_ for (@db);
print "\n";
for my $key (sort keys %h){
print "$key ";
printf " %$db{$_}s", max (values $h{$key}{$_}) for (@db);
print "\n";
}
# HOUR SECTION END - MAX
# MINUTE SECTION START - MAX
print fnd_max %m ;
set_column_widths(\%m, \%db, \@db);
print "\nFrequency Minute:\n collectionTime";
printf " %$db{$_}s", $_ for (@db);
print "\n";
for my $key (sort keys %m){
print $key;
printf " %$db{$_}s", max (values $m{$key}{$_}) for (@db);
print "\n";
}
# MINUTE SECTION END - MAX