File Coverage

blib/lib/HTML/ListScraper/Vat.pm
Criterion Covered Total %
statement 85 86 98.8
branch 16 18 88.8
condition n/a
subroutine 12 12 100.0
pod 0 2 0.0
total 113 118 95.7


line stmt bran cond sub pod time code
1             package HTML::ListScraper::Vat;
2              
3 4     4   25 use warnings;
  4         9  
  4         148  
4 4     4   22 use strict;
  4         8  
  4         88  
5              
6 4     4   21 use Class::Generate;
  4         7  
  4         155  
7 4     4   2169 use HTML::ListScraper::Foam;
  4         11  
  4         133  
8 4     4   2167 use HTML::ListScraper::Occurence;
  4         8  
  4         3353  
9              
10             my $epsilon = 0.0001;
11              
12             sub new {
13 8     8 0 21 my ($class, $book, $min_count) = @_;
14 8         34 my $self = { book => $book, min_count => $min_count };
15 8         52 $self->{seq} = $book->get_internal_sequence;
16 8         20 bless $self, $class;
17              
18 8         31 return $self;
19             }
20              
21             sub create_sequence {
22 8     8 0 17 my $self = shift;
23              
24 8         58 my $count = scalar(@{$self->{seq}});
  8         40  
25 8 50       33 if ($count < $self->{min_count}) {
26 0         0 return undef; # if we had a verbose mode, we would warn here
27             }
28              
29 8         61 $self->{foam} = HTML::ListScraper::Foam->new($self->{book});
30              
31 8         18 $self->{map} = { };
32 8         28 $self->_fill_pair_map;
33 8         32 while ($self->_has_cand) {
34 809         2009 $self->_prune_map;
35 809         2101 $self->_skim_map;
36 809         6382 $self->_grow_map;
37             }
38              
39 8         46 return $self->{foam};
40             }
41              
42             sub _has_cand {
43 817     817   1255 my $self = shift;
44              
45 817         1059 return scalar(keys %{$self->{map}});
  817         6974  
46             }
47              
48             sub _fill_pair_map {
49 8     8   15 my $self = shift;
50              
51 8         18 $self->{max_spread} = 1;
52 8         21 $self->{length} = 2;
53              
54 8         10 my $count = scalar(@{$self->{seq}});
  8         22  
55              
56 8         56 my $first = $self->{seq}->[0];
57 8         51 my $i = 1;
58 8         31 while ($i < $count) {
59 4069         6674 my $second = $self->{seq}->[$i];
60 4069         6123 my $seq = $first . $second;
61 4069 100       9391 if (!exists($self->{map}->{$seq})) {
62 771         2362 $self->{map}->{$seq} =
63             HTML::ListScraper::Occurence->new(2, $i - 1);
64             } else {
65 3298         10828 my $spread = $self->{map}->{$seq}->append_pos($i - 1);
66 3298 100       9021 if ($spread > $self->{max_spread}) {
67 438         752 $self->{max_spread} = $spread;
68             }
69             }
70              
71 4069         5819 $first = $second;
72 4069         10319 ++$i;
73             }
74             }
75              
76             sub _prune_map {
77 809     809   1154 my $self = shift;
78              
79 809         1013 my @seq = keys %{$self->{map}};
  809         17691  
80 809         5970 foreach my $seq (@seq) {
81 77192         230880 my $n = $self->{map}->{$seq}->spread;
82 77192 100       225973 if ($n < $self->{min_count}) {
83 3376         10613 delete $self->{map}->{$seq};
84             }
85             }
86             }
87              
88             sub _skim_map {
89 809     809   1121 my $self = shift;
90              
91 809         1056 foreach my $seq (keys %{$self->{map}}) {
  809         9693  
92 16009         27781 my $occ = $self->{map}->{$seq};
93 16009 100       42527 if ($occ->spread == $self->{max_spread}) {
94 2542 100       7896 if (!$self->{foam}->store($seq, $occ)) {
95             # the best isn't good enough
96 571         1197 return;
97             }
98             }
99             }
100             }
101              
102             sub _grow_map {
103 809     809   1147 my $self = shift;
104              
105 809         1106 my $max_spread = 1;
106 809         1306 my $length = $self->{length} + 1;
107 809         1341 my $map = { };
108 809         1116 foreach my $seq (keys %{$self->{map}}) {
  809         9656  
109 73816         122935 my $occ = $self->{map}->{$seq};
110 73816         205913 foreach my $pos ($occ->positions) {
111 305412 50       729723 if ($pos > 0) {
112 305412         404466 my $npos = $pos - 1;
113 305412         599022 my $nseq = $self->{seq}->[$npos] . $seq;
114              
115 305412 100       894752 if (!exists($map->{$nseq})) {
116 76421         218089 $map->{$nseq} =
117             HTML::ListScraper::Occurence->new($length, $npos);
118             } else {
119 228991         840223 my $spread = $map->{$nseq}->append_pos($npos);
120 228991 100       793763 if ($spread > $max_spread) {
121 3809         9748 $max_spread = $spread;
122             }
123             }
124             }
125             }
126             }
127              
128 809         6177 $self->{map} = $map;
129 809         59088 $self->{length} = $length;
130 809         2867 $self->{max_spread} = $max_spread;
131             }
132              
133             1;