@@ -180,34 +180,32 @@ sub _mark_for_retention {
180
180
my ($self , $reference_date , $rule , $list , $trace )= @_ ;
181
181
my ($interval , $duration , $reach_factor )= @{$rule }{' interval' ,' duration' ,' reach_factor' };
182
182
$reach_factor = $self -> reach_factor unless defined $reach_factor ;
183
- my $next_date = $reference_date -> clone;
183
+ my $next_date = $reference_date -> clone-> subtract( %$duration ) -> add( %$interval ) ;
184
184
my $epoch = $next_date -> epoch;
185
- my $search_idx = $# $list ; # high value, iterates downward
186
- my $final_epoch = $next_date -> clone-> subtract(%$duration )-> epoch;
187
- my $next_epoch = $next_date -> subtract(%$interval )-> epoch;
188
- my $radius = ($epoch - $next_epoch ) * $reach_factor ;
185
+ my $search_idx = 0;
186
+ my $next_epoch = $next_date -> add(%$interval )-> epoch;
187
+ my $radius = -($epoch - $next_epoch ) * $reach_factor ;
189
188
my $drift = 0; # only used for auto_sync
190
189
my $rule_key ;
191
190
192
- # Iterating backward accross date intervals and also input points, which is awkward.
193
191
# The epoch variables track the current date interval, and the _idx
194
192
# variables track our position in the list.
195
- while ($epoch > $final_epoch && $search_idx >= 0 ) {
193
+ while ($epoch -abs( $drift ) <= $reference_date -> epoch && $search_idx < @$list ) {
196
194
my $best ;
197
- for (my $i = $search_idx ; $i >= 0 and $list -> [$i ][0] > $epoch +$drift - $radius ; -- $i ) {
198
- if ($list -> [$i ][0] < = $epoch +$drift + $radius
195
+ for (my $i = $search_idx ; $i < @$list and $list -> [$i ][0] < $epoch +$drift + $radius ; ++ $i ) {
196
+ if ($list -> [$i ][0] > = $epoch +$drift - $radius
199
197
and (!defined $best or abs($list -> [$i ][0] - ($epoch +$drift )) < abs($list -> [$best ][0] - ($epoch +$drift )))
200
198
) {
201
199
$best = $i ;
202
200
}
203
201
# update the start_idx for next interval iteration
204
- $search_idx = $i - 1 if $list -> [$i ][0] > $next_epoch + $drift + $ radius ;
202
+ $search_idx = $i + 1 if $list -> [$i ][0] < $next_epoch - $ radius*2 ;
205
203
}
206
204
if (defined $best ) {
207
205
$list -> [$best ][2]= 1; # mark as a keeper
208
206
# If option enabled, drift toward the time we found, so that gap between next
209
207
# is closer to $interval
210
- $drift += ( $list -> [$best ][0] - ( $epoch + $drift ))/2
208
+ $drift = $list -> [$best ][0] - $epoch
211
209
if $self -> auto_sync;
212
210
}
213
211
if ($trace ) {
@@ -221,7 +219,7 @@ sub _mark_for_retention {
221
219
push @{$trace -> {$rule_key }{interval }}, { epoch => $epoch , best => $best , drift => $drift };
222
220
}
223
221
$epoch = $next_epoch ;
224
- $next_epoch = $next_date -> subtract (%$interval )-> epoch;
222
+ $next_epoch = $next_date -> add (%$interval )-> epoch;
225
223
226
224
# if auto_sync enabled, cause drift to decay back toward 0
227
225
$drift = int ($drift * 7/8)
0 commit comments