File Coverage

lib/Acme/Selection/RarestFirst.pm
Criterion Covered Total %
statement 11 11 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 15 15 100.0


line stmt bran cond sub pod time code
1 1     1   242998 use v5.42;
  1         4  
2 1     1   7 use feature 'class';
  1         2  
  1         221  
3 1     1   12 no warnings 'experimental::class';
  1         2  
  1         163  
4             #
5             class Acme::Selection::RarestFirst v1.0.0 {
6 1     1   9 use List::Util qw[shuffle];
  1         3  
  1         827  
7             field $size : param;
8             field @availability = (0) x $size; # index => count
9              
10             #
11             method update ( $bitfield, $delta ) {
12             for ( my $i = 0; $i < $size; $i++ ) {
13             if ( $bitfield->get($i) ) {
14             $availability[$i] += $delta;
15             }
16             }
17             }
18              
19             method pick ( $my_bitfield, $priorities //= () ) {
20             my @candidates;
21             for ( my $i = 0; $i < $size; $i++ ) {
22             next if $my_bitfield->get($i);
23             next if defined $priorities && ( $priorities->[$i] // 1 ) <= 0;
24             push @candidates, $i;
25             }
26             return undef unless @candidates;
27              
28             # Sort by:
29             # 1. User priority (higher first)
30             # 2. Availability (lowest first)
31             # 3. Random tie-break (achieved by shuffling before sort)
32             @candidates = shuffle @candidates;
33             @candidates = sort {
34             my $p_a = $priorities ? ( $priorities->[$a] // 1 ) : 1;
35             my $p_b = $priorities ? ( $priorities->[$b] // 1 ) : 1;
36             my $avail_a = $availability[$a] // 0;
37             my $avail_b = $availability[$b] // 0;
38             ( $p_b <=> $p_a ) || ( $avail_a <=> $avail_b )
39             } @candidates;
40             return $candidates[0];
41             }
42              
43             method get_availability ($index) {
44             return $availability[$index] // 0;
45             }
46             };
47             #
48             1;