File Coverage

blib/lib/Event/SlidingWindow.pm
Criterion Covered Total %
statement 41 51 80.3
branch 4 6 66.6
condition 5 10 50.0
subroutine 7 8 87.5
pod 0 3 0.0
total 57 78 73.0


line stmt bran cond sub pod time code
1             package Event::SlidingWindow ;
2              
3 1     1   5422 use strict ;
  1         2  
  1         30  
4 1     1   4 use Carp ;
  1         2  
  1         538  
5              
6              
7             $Event::SlidingWindow::VERSION = '0.05' ;
8              
9              
10             sub new {
11 1     1 0 561 my $class = shift ;
12 1         2 my $nb_buckets = int(shift) ; # Number of buckets, i.e. window size
13 1   50     4 my $bucket_size = int(shift) || 1 ; # Bucket size in seconds
14            
15             # Validate paramters...
16 1 50       3 if ($nb_buckets <= 0){
17 0         0 croak("nb_buckets must be an integer > 0") ;
18             }
19            
20 1         5 my $this = {
21             nb_buckets => $nb_buckets,
22             bucket_size => $bucket_size,
23             loop => [],
24             } ;
25              
26 1         2 bless($this, $class) ;
27 1         3 $this->_init() ;
28            
29 1         3 return $this ;
30             }
31              
32              
33             sub _init {
34 2     2   4 my $this = shift ;
35 2   66     12 my $now = shift || time() ;
36            
37 2         7 $this->{cur_ts} = $now ;
38 2         8 for (my $i = 0 ; $i < $this->{nb_buckets} ; $i++){
39 6         14 $this->{loop}->[$i] = 0 ;
40             }
41 2         6 $this->{cur_idx} = 0 ;
42             }
43              
44              
45             sub record_event {
46 5     5 0 12 my $this = shift ;
47 5         13 my $now = shift ;
48 5   50     18 my $incr = shift || 1 ;
49            
50 5         9 $this->_update($now) ;
51 5         10 $this->{loop}->[$this->{cur_idx}] += $incr ;
52             }
53              
54              
55             sub count_events {
56 2     2 0 8 my $this = shift ;
57 2         3 my $now = shift ;
58            
59 2         9 $this->_update($now) ;
60 2         3 my $cnt = 0 ;
61 2         3 foreach my $c (@{$this->{loop}}){
  2         5  
62 6         9 $cnt += $c ;
63             }
64            
65 2         12 return $cnt ;
66             }
67              
68              
69             # This method is responsible for keeping the loop in sync for
70             # from current time value.
71             sub _update {
72 7     7   7 my $this = shift ;
73 7   33     27 my $now = shift || time() ;
74              
75 7         16 my $interval = int(($now - $this->{cur_ts}) / $this->{bucket_size}) ;
76 7 100       12 if (! $interval){
77 6         7 return ;
78             }
79 1 50       10 if ($interval >= $this->{nb_buckets}){
80 1         5 $this->_init($now) ;
81 1         2 return ;
82             }
83            
84             # Now we really have some work to do.
85 0           for (my $i = 0 ; $i < $interval ; $i++){
86 0           $this->{loop}->[($this->{cur_idx} + $i + 1) % $this->{nb_buckets}] = 0 ;
87             }
88 0           $this->{cur_idx} = ($this->{cur_idx} + $interval) % $this->{nb_buckets} ;
89 0           $this->{cur_ts} = $now ;
90             }
91              
92              
93             sub _dump {
94 0     0     my $this = shift ;
95            
96 0           my @ret = () ;
97 0           for (my $i = 0 ; $i < $this->{nb_buckets} ; $i++){
98 0           push @ret, $this->{loop}->[($this->{cur_idx} + $i + 1) % $this->{nb_buckets}] ;
99             }
100            
101 0           return \@ret ;
102             }
103              
104              
105             1 ;
106              
107              
108             __END__