File Coverage

blib/lib/Algorithm/LCS/XS.pm
Criterion Covered Total %
statement 49 49 100.0
branch 4 8 50.0
condition 9 18 50.0
subroutine 11 11 100.0
pod 3 5 60.0
total 76 91 83.5


line stmt bran cond sub pod time code
1             package Algorithm::LCS::XS;
2              
3 1     1   64514 use 5.008;
  1         3  
4 1     1   4 use strict;
  1         2  
  1         17  
5 1     1   21 use warnings;
  1         1  
  1         21  
6 1     1   423 use version;
  1         1632  
  1         4  
7             our $VERSION = qv(2.0.1);
8 1     1   84 use base 'Exporter';
  1         1  
  1         589  
9             our @EXPORT_OK = qw/&ADLCS &LCSidx/;
10             require XSLoader;
11             XSLoader::load('Algorithm::LCS::XS', $VERSION);
12              
13             ##############################
14             # code adapted from Algorithm::Diff
15              
16             sub line_map {
17 200003     200003 1 244692 my $ctx = shift;
18 200003         210916 my %lines;
19 200003         368521 push @{ $lines{$_[$_]} }, $_ for 0..$#_; # values MUST be SvIOK
  11400174         15475138  
20 200003         297425 \%lines;
21             }
22              
23             sub callback {
24 1     1 1 9048 my ($ctx, @b) = @_;
25 1         3 my $h = $ctx->line_map(@b);
26 100001 50   100001   1680970 sub { @_ ? _core_loop($ctx, $_[0], 0, $#{$_[0]}, $h) : @b }
  100001         5257636  
27 1         4 }
28              
29             sub LCS {
30 200002     200002 1 278866 my ($ctx, $a, $b) = @_;
31 200002         329376 my ($amin, $amax, $bmin, $bmax) = (0, $#$a, 0, $#$b);
32              
33 200002   33     774237 while ($amin <= $amax and $bmin <= $bmax and $a->[$amin] eq $b->[$bmin]) {
      66        
34 200002         228759 $amin++;
35 200002         598687 $bmin++;
36             }
37 200002   33     613318 while ($amin <= $amax and $bmin <= $bmax and $a->[$amax] eq $b->[$bmax]) {
      66        
38 400004         401320 $amax--;
39 400004         1113426 $bmax--;
40             }
41              
42 200002         589392 my $h = $ctx->line_map(@$b[$bmin..$bmax]); # line numbers are off by $bmin
43              
44 200002 50       472697 return $amin + _core_loop($ctx, $a, $amin, $amax, $h) + ($#$a - $amax)
45             unless wantarray;
46              
47 200002         9081594 my @lcs = _core_loop($ctx,$a,$amin,$amax,$h);
48 200002 50       373658 if ($bmin > 0) {
49 200002         1190716 $_->[1] += $bmin for @lcs; # correct line numbers
50             }
51              
52 200002         1567346 map([$_ => $_], 0 .. ($amin-1)),
53             @lcs,
54             map([$_ => ++$bmax], ($amax+1) .. $#$a);
55             }
56              
57              
58             my $alg;
59              
60             sub LCSidx {
61 100001   66 100001 0 1727354 $alg //= Algorithm::LCS::XS->new;
62 100001         113785 my (@l, @r);
63 100001         169561 for my $arr ($alg->LCS(@_)) {
64 4000040         4298907 push @l, $$arr[0];
65 4000040         4474447 push @r, $$arr[1];
66             }
67 100001         1864591 return \@l, \@r;
68             }
69              
70             sub ADLCS {
71 100000   33 100000 0 2667023568 $alg //= Algorithm::LCS::XS->new;
72 100000         107481 my @rv;
73 100000         168188 for my $arr ($alg->LCS(@_)) {
74 4000000         5084974 $rv[$$arr[0]] = $_[0][$$arr[0]];
75             }
76 100000 50       1861444 return wantarray ? @rv : \@rv;
77             }
78              
79             1;
80              
81             __END__