File Coverage

blib/lib/Algorithm/BinarySearch/Vec.pm
Criterion Covered Total %
statement 79 81 97.5
branch 24 32 75.0
condition 10 12 83.3
subroutine 17 19 89.4
pod 1 1 100.0
total 131 145 90.3


line stmt bran cond sub pod time code
1             package Algorithm::BinarySearch::Vec;
2              
3 2     2   12612 use Exporter;
  2         5  
  2         86  
4 2     2   11 use Carp;
  2         3  
  2         150  
5 2     2   2551 use AutoLoader;
  2         3981  
  2         15  
6 2     2   76 use strict;
  2         5  
  2         65  
7 2     2   1199 use bytes;
  2         12  
  2         14  
8              
9             our @ISA = qw(Exporter);
10             our $VERSION = '0.05';
11              
12             our ($HAVE_XS);
13             eval {
14             require XSLoader;
15             $HAVE_XS = XSLoader::load('Algorithm::BinarySearch::Vec', $VERSION);
16             } or do {
17             $HAVE_XS = 0;
18             };
19              
20             # Preloaded methods go here.
21             #require Algorithm::BinarySearch::Vec::XS::Whatever;
22              
23             # Autoload methods go after =cut, and are processed by the autosplit program.
24              
25             ##======================================================================
26             ## Exports
27             ##======================================================================
28              
29             our $KEY_NOT_FOUND = 0xffffffff;
30              
31             our (%EXPORT_TAGS, @EXPORT_OK, @EXPORT);
32             BEGIN {
33 2     2   825 %EXPORT_TAGS =
34             (
35             api => [qw( vbsearch vbsearch_lb vbsearch_ub),
36             qw(vabsearch vabsearch_lb vabsearch_ub),
37             qw(vvbsearch vvbsearch_lb vvbsearch_ub),
38             ],
39             const => [qw($KEY_NOT_FOUND)],
40             debug => [qw(vget vset vec2array)],
41             );
42 2         8 $EXPORT_TAGS{all} = [map {@$_} @EXPORT_TAGS{qw(api const debug)}];
  6         21  
43 2         7 $EXPORT_TAGS{default} = [map {@$_} @EXPORT_TAGS{qw(api const)}];
  4         13  
44 2         4 @EXPORT_OK = @{$EXPORT_TAGS{all}};
  2         10  
45 2         3 @EXPORT = @{$EXPORT_TAGS{default}};
  2         2436  
46             }
47              
48             ##======================================================================
49             ## Debug wrappers
50              
51             ##--------------------------------------------------------------
52             ## $val = vget($vec,$i,$nbits)
53             sub _vget {
54 0     0   0 return vec($_[0],$_[1],$_[2]);
55             }
56              
57             ##--------------------------------------------------------------
58             ## undef = vset($vec,$i,$nbits,$val)
59             sub _vset {
60 0     0   0 return vec($_[0],$_[1],$_[2])=$_[3];
61             }
62              
63              
64             ##======================================================================
65             ## API: Search: element-wise
66              
67             ##--------------------------------------------------------------
68             ## $index = vbsearch($v,$key,$nbits)
69             ## $index = vbsearch($v,$key,$nbits,$ilo,$ihi)
70             sub _vbsearch {
71 5     5   8924 my ($vr,$key,$nbits,$ilo,$ihi) = (\$_[0],@_[1..$#_]);
72 5 50       19 $ilo = 0 if (!defined($ilo));
73 5 50       16 $ihi = 8*length($$vr)/$nbits if (!defined($ihi));
74 5         6 my ($imid);
75 5         13 while ($ilo < $ihi) {
76 16         17 $imid = ($ihi+$ilo) >> 1;
77 16 100       33 if (vec($$vr,$imid,$nbits) < $key) {
78 6         12 $ilo = $imid + 1;
79             } else {
80 10         17 $ihi = $imid;
81             }
82             }
83 5 100 66     30 return ($ilo==$ihi) && vec($$vr,$ilo,$nbits)==$key ? $ilo : $KEY_NOT_FOUND;
84             }
85              
86             ##--------------------------------------------------------------
87             ## $index = vbsearch_lb($v,$key,$nbits)
88             ## $index = vbsearch_lb($v,$key,$nbits,$ilo,$ihi)
89             sub _vbsearch_lb {
90 6     6   1553 my ($vr,$key,$nbits,$ilo,$ihi) = (\$_[0],@_[1..$#_]);
91 6 50       41 $ilo = 0 if (!defined($ilo));
92 6 50       19 $ihi = 8*length($$vr)/$nbits if (!defined($ihi));
93 6         9 my ($imin,$imax,$imid) = ($ilo,$ihi);
94 6         15 while ($ihi-$ilo > 1) {
95 17         18 $imid = ($ihi+$ilo) >> 1;
96 17 100       33 if (vec($$vr,$imid,$nbits) < $key) {
97 6         10 $ilo = $imid;
98             } else {
99 11         25 $ihi = $imid;
100             }
101             }
102 6 50       14 return $ilo if ( vec($$vr,$ilo,$nbits)==$key);
103 6 100 100     30 return $ihi if ($ihi < $imax && vec($$vr,$ihi,$nbits)==$key);
104 4 100 100     20 return $ilo if ($ilo > $imin || vec($$vr,$ilo,$nbits) <$key);
105 1         3 return $KEY_NOT_FOUND;
106             }
107              
108             ##--------------------------------------------------------------
109             ## $index = vbsearch_ub($v,$key,$nbits)
110             ## $index = vbsearch_ub($v,$key,$nbits,$ilo,$ihi)
111             sub _vbsearch_ub {
112 6     6   1601 my ($vr,$key,$nbits,$ilo,$ihi) = (\$_[0],@_[1..$#_]);
113 6 50       19 $ilo = 0 if (!defined($ilo));
114 6 50       16 $ihi = 8*length($$vr)/$nbits if (!defined($ihi));
115 6         8 my ($imin,$imax,$imid) = ($ilo,$ihi);
116 6         15 while ($ihi-$ilo > 1) {
117 18         20 $imid = ($ihi+$ilo) >> 1;
118 18 100       27 if (vec($$vr,$imid,$nbits) > $key) {
119 9         20 $ihi = $imid;
120             } else {
121 9         20 $ilo = $imid;
122             }
123             }
124 6 50 66     44 return $ihi if ($ihi < $imax && vec($$vr,$ihi,$nbits)==$key);
125 6 100       19 return $ilo if ( vec($$vr,$ilo,$nbits)>=$key);
126 3 100       47 return $ihi>=$imax ? $KEY_NOT_FOUND : $ihi;
127             }
128              
129             ##======================================================================
130             ## API: Search: array-wise
131              
132             ##--------------------------------------------------------------
133             ## \@indices = vabsearch($v,\@keys,$nbits)
134             ## \@indices = vabsearch($v,\@keys,$nbits,$ilo,$ihi)
135             sub _vabsearch {
136 1     1   998 return [map {vbsearch($_[0],$_,@_[2..$#_])} @{$_[1]}];
  7         23  
  1         4  
137             }
138              
139              
140             ##--------------------------------------------------------------
141             ## \@indices = vabsearch_lb($v,\@keys,$nbits)
142             ## \@indices = vabsearch_lb($v,\@keys,$nbits,$ilo,$ihi)
143             sub _vabsearch_lb {
144 1     1   324 return [map {vbsearch_lb($_[0],$_,@_[2..$#_])} @{$_[1]}];
  7         23  
  1         3  
145             }
146              
147             ##--------------------------------------------------------------
148             ## \@indices = vabsearch_ub($v,\@keys,$nbits)
149             ## \@indices = vabsearch_ub($v,\@keys,$nbits,$ilo,$ihi)
150             sub _vabsearch_ub {
151 1     1   407 return [map {vbsearch_ub($_[0],$_,@_[2..$#_])} @{$_[1]}];
  7         23  
  1         3  
152             }
153              
154             ##======================================================================
155             ## API: Search: vec-wise
156              
157             ## \@a = vec2array($vec,$nbits)
158             sub vec2array {
159 3     3 1 13 return [map {vec($_[0],$_,$_[1])} (0..(length($_[0])*8/$_[1]-1))];
  21         106  
160             }
161              
162             ##--------------------------------------------------------------
163             ## $indices = vvbsearch($v,$keys,$nbits)
164             ## $indices = vvbsearch($v,$keys,$nbits,$ilo,$ihi)
165             sub _vvbsearch {
166 1     1   1447 return pack('N*', @{vabsearch($_[0],vec2array(@_[1,2]),@_[2..$#_])});
  1         7  
167             }
168              
169             ##--------------------------------------------------------------
170             ## $indices = vvbsearch_lb($v,$keys,$nbits)
171             ## $indices = vvbsearch_lb($v,$keys,$nbits,$ilo,$ihi)
172             sub _vvbsearch_lb {
173 1     1   394 return pack('N*', @{vabsearch_lb($_[0],vec2array(@_[1,2]),@_[2..$#_])});
  1         5  
174             }
175              
176             ##--------------------------------------------------------------
177             ## $indices = vvbsearch_ub($v,$keys,$nbits)
178             ## $indices = vvbsearch_ub($v,$keys,$nbits,$ilo,$ihi)
179             sub _vvbsearch_ub {
180 1     1   445 return pack('N*', @{vabsearch_ub($_[0],vec2array(@_[1,2]),@_[2..$#_])});
  1         4  
181             }
182              
183              
184             ##======================================================================
185             ## delegate: attempt to delegate to XS module
186             foreach my $func (map {@$_} @EXPORT_TAGS{qw(api debug)}) {
187 2     2   14 no warnings 'redefine';
  2         5  
  2         323  
188             if ($HAVE_XS && Algorithm::BinarySearch::Vec::XS->can($func)) {
189             eval "\*$func = \\&Algorithm::BinarySearch::Vec::XS::$func;";
190             } elsif (__PACKAGE__->can("_$func")) {
191             eval "\*$func = \\&_$func;";
192             }
193             }
194              
195              
196             1; ##-- be happy
197              
198             __END__