$Event::SlidingWindow::VERSION
=
'0.05'
;
sub
new {
my
$class
=
shift
;
my
$nb_buckets
=
int
(
shift
) ;
my
$bucket_size
=
int
(
shift
) || 1 ;
if
(
$nb_buckets
<= 0){
croak(
"nb_buckets must be an integer > 0"
) ;
}
my
$this
= {
nb_buckets
=>
$nb_buckets
,
bucket_size
=>
$bucket_size
,
loop
=> [],
} ;
bless
(
$this
,
$class
) ;
$this
->_init() ;
return
$this
;
}
sub
_init {
my
$this
=
shift
;
my
$now
=
shift
||
time
() ;
$this
->{cur_ts} =
$now
;
for
(
my
$i
= 0 ;
$i
<
$this
->{nb_buckets} ;
$i
++){
$this
->{loop}->[
$i
] = 0 ;
}
$this
->{cur_idx} = 0 ;
}
sub
record_event {
my
$this
=
shift
;
my
$now
=
shift
;
my
$incr
=
shift
|| 1 ;
$this
->_update(
$now
) ;
$this
->{loop}->[
$this
->{cur_idx}] +=
$incr
;
}
sub
count_events {
my
$this
=
shift
;
my
$now
=
shift
;
$this
->_update(
$now
) ;
my
$cnt
= 0 ;
foreach
my
$c
(@{
$this
->{loop}}){
$cnt
+=
$c
;
}
return
$cnt
;
}
sub
_update {
my
$this
=
shift
;
my
$now
=
shift
||
time
() ;
my
$interval
=
int
((
$now
-
$this
->{cur_ts}) /
$this
->{bucket_size}) ;
if
(!
$interval
){
return
;
}
if
(
$interval
>=
$this
->{nb_buckets}){
$this
->_init(
$now
) ;
return
;
}
for
(
my
$i
= 0 ;
$i
<
$interval
;
$i
++){
$this
->{loop}->[(
$this
->{cur_idx} +
$i
+ 1) %
$this
->{nb_buckets}] = 0 ;
}
$this
->{cur_idx} = (
$this
->{cur_idx} +
$interval
) %
$this
->{nb_buckets} ;
$this
->{cur_ts} =
$now
;
}
sub
_dump {
my
$this
=
shift
;
my
@ret
= () ;
for
(
my
$i
= 0 ;
$i
<
$this
->{nb_buckets} ;
$i
++){
push
@ret
,
$this
->{loop}->[(
$this
->{cur_idx} +
$i
+ 1) %
$this
->{nb_buckets}] ;
}
return
\
@ret
;
}
1 ;