File Coverage

lib/UR/BoolExpr/Template/PropertyComparison/In.pm
Criterion Covered Total %
statement 32 35 91.4
branch 6 8 75.0
condition 4 6 66.6
subroutine 7 7 100.0
pod n/a
total 49 56 87.5


line stmt bran cond sub pod time code
1              
2             package UR::BoolExpr::Template::PropertyComparison::In;
3              
4 266     266   981 use strict;
  266         341  
  266         6393  
5 266     266   853 use warnings;
  266         299  
  266         4887  
6 266     266   797 use UR;
  266         389  
  266         1038  
7             our $VERSION = "0.46"; # UR $VERSION;
8              
9             UR::Object::Type->define(
10             class_name => __PACKAGE__,
11             is => ['UR::BoolExpr::Template::PropertyComparison'],
12             doc => "Returns true if any of the property's values appears in the comparison value list",
13             );
14              
15             sub _compare {
16 118     118   178 my ($class,$comparison_values,@property_values) = @_;
17              
18 118 50 66     356 if (@property_values == 1 and ref($property_values[0]) eq 'ARRAY') {
19 0         0 @property_values = @{$property_values[0]};
  0         0  
20             }
21              
22             # undef should match missing values, which will be sorted at the end - the sorter in
23             # UR::BoolExpr::resolve() takes care of the sorting for us
24 118 50 66     275 if (! @property_values and !defined($comparison_values->[-1])) {
25 0         0 return 1;
26             }
27              
28 118         107 my($pv_idx, $cv_idx);
29 266     266   29262 no warnings;
  266         377  
  266         14935  
30 118     413   384 my $sorter = sub { return $property_values[$pv_idx] cmp $comparison_values->[$cv_idx] };
  413         380  
31 266     266   961 use warnings;
  266         318  
  266         29064  
32              
33             # Binary search within @$comparison_values
34 118         255 for ( $pv_idx = 0; $pv_idx < @property_values; $pv_idx++ ) {
35 220         164 my $cv_min = 0;
36 220         157 my $cv_max = $#$comparison_values;
37 220         165 do {
38 413         304 $cv_idx = ($cv_min + $cv_max) >> 1;
39 413         358 my $result = &$sorter;
40 413 100       590 if (!$result) {
    100          
41 82         493 return 1;
42             } elsif ($result > 0) {
43 187         285 $cv_min = $cv_idx + 1;
44             } else {
45 144         322 $cv_max = $cv_idx - 1;
46             }
47             } until ($cv_min > $cv_max);
48             }
49 36         173 return '';
50             }
51              
52             1;
53              
54             =pod
55              
56             =head1 NAME
57              
58             UR::BoolExpr::Template::PropertyComparison::In - perform an In test
59              
60             =head1 DESCRIPTION
61              
62             Returns true if any of the property's values appears in the comparison value list.
63             Think of 'in' as short for 'intersect', and not just SQL's 'IN' operator.
64              
65             =cut