view Lib/PerfCounter.pm @ 11:75980091813b

DOM и навигация
author Sergey
date Wed, 02 Sep 2009 17:47:44 +0400
parents 03e58a454b20
children 16ada169ca75
line wrap: on
line source

package PerfCounter;
use strict;
use Common;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(&GetTimeCounter &StartTimeCounter &StopTimeCounter &SetDBIPerfCounter);

our %Counters;

sub Reset() {
    $_->Reset foreach values %Counters;
}

sub GetTimeCounter {
    my $counter = $Counters{$_[0]};
    die new Exception("'$_[0]' already exists and isn't a time counter.") if ref $counter and ref $counter ne 'PerfInterval';
    if (not ref $counter) {
        $counter = new PerfInterval;
        $Counters{$_[0]} = $counter;
    }
    return $counter;
}

sub StartTimeCounter {
    my $counter = GetTimeCounter($_[0]);
    if (not $counter->IsOpened) {
        $counter->OpenInterval;
    }
}

sub StopTimeCounter {
    my $counter = GetTimeCounter($_[0]);
    if ($counter->IsOpened) {
        $counter->CloseInterval;
    }
}

sub SetDBIPerfCounter{
    my ($dbh,$name) = @_;
    $name ||= 'DBI';
    $Counters{$name} = DBIPerfomance->new(DBH => $dbh);
}

package PerfInterval;
use Common;
use Time::HiRes qw(gettimeofday tv_interval);

sub new {
    my $class = shift;
    my $self = bless { StartTime => scalar(gettimeofday()) }, $class;
    return $self;
}

sub CloseInterval {
    my $this = shift;
    
    if (not $this->{'EndTime'}) {    
        $this->{'EndTime'} = scalar(gettimeofday());    
        $this->{'Value'} += $this->{'EndTime'} - $this->{'StartTime'};
    }
    
    return $this->{'Value'};
}

sub Value {
    my $this = shift;
    
    if (not $this->{'EndTime'}) {
        return sprintf ( '%.3f+',scalar(gettimeofday()) - $this->{'StartTime'});
    } else {
        return sprintf ( '%.3f',$this->{'Value'});
    }
}

sub Add {
    my ($this,$interval) = @_;
    
    if(ref $interval eq 'PerfInterval') {
        $this->{'Value'} += $interval->{'Value'};
    } else {
        $this->{'Value'} += $interval;
    }
    
    return $this->{'Value'};
}

sub IsOpened {
    my $this = shift;
    return( not $this->{'EndTime'} );
}

sub OpenInterval {
    my $this = shift;
    
    $this->{'StartTime'} = gettimeofday();
    delete $this->{'EndTime'};
    
    return 1;
}

sub Reset {
    my ($this) = @_;
    
    $this->CloseInterval();
    $this->{'Value'} = 0;
}

package DBIPerfomance;
use Common;
our @ISA = qw(Object);

BEGIN {
    DeclareProperty DBH => ACCESS_READ;

}

sub CTOR {
    my $this=shift;
    $this->SUPER::CTOR(@_);

    
    $this->DBH->{Profile} = 6;
}

sub Reset {
    my $this = shift;
    $this->DBH->{Profile} = 6;
}

sub Value {
    my ($this,%opt) = @_;

    my $infoSelect = { count => 0, time => 0};
    my $infoUpdate = { count => 0, time => 0};
    my $infoTotal;

    foreach my $stmt (grep /^SELECT/i,keys %{$this->DBH->{Profile}->{Data} || {}}) {
        $infoSelect->{'count'} += $this->DBH->{Profile}{Data}{$stmt}{execute}[0] || 0;
        $infoSelect->{'time'} += $this->DBH->{Profile}{Data}{$stmt}{execute}[1] || 0;
    }

    foreach my $stmt (grep /^UPDATE/i,keys %{$this->DBH->{Profile}->{Data} || {}}) {
        $infoUpdate->{'count'} += $this->DBH->{Profile}{Data}{$stmt}{execute}[0] || 0;
        $infoUpdate->{'time'} += $this->DBH->{Profile}{Data}{$stmt}{execute}[1] || 0;
    }

    $infoTotal->{'count'} = $infoSelect->{'count'} + $infoUpdate->{'count'};
    $infoTotal->{'time'} = $infoSelect->{'time'} + $infoUpdate->{'time'};

    if ($opt{'extended'}) {
        return ($infoSelect,$infoUpdate,$infoTotal);
    } else {
        return sprintf( '%i (%.2f)', $infoTotal->{count},$infoTotal->{time} );
    }
}

sub Queries {
    my ($this) = @_;
    return [ map { "$this->{$DBH}{Profile}{Data}{$_}{execute}[0] x $_"} sort grep $_, keys %{$this->DBH->{Profile}->{Data}}];
}
1;