File Coverage

blib/lib/Simple/Trie.pm
Criterion Covered Total %
statement 34 35 97.1
branch 5 6 83.3
condition 2 3 66.6
subroutine 9 9 100.0
pod 3 3 100.0
total 53 56 94.6


line stmt bran cond sub pod time code
1             package Simple::Trie;
2             BEGIN {
3 1     1   889 $Simple::Trie::AUTHORITY = 'cpan:LOGIE';
4             }
5             {
6             $Simple::Trie::VERSION = '0.01';
7             }
8 1     1   946 use Moo;
  1         23019  
  1         6  
9 1     1   2107 use constant '_END' => '';
  1         2  
  1         660  
10              
11             # ABSTRACT: Trie, it's simple
12              
13             has words => (
14             is => 'rw',
15             initializer => 'words',
16             trigger => sub { (shift)->_make_trie(shift) },
17             coerce => sub { ref $_[0] eq 'ARRAY' ? $_[0] : [split(/\s/,$_[0])] }
18             );
19              
20             has _trie => ( is => 'rw', default => sub {{}} );
21              
22 2     2 1 7 sub add { (shift)->_add_node(@_) }
23              
24             sub find {
25 4     4 1 1781 my ($self, $word) = @_;
26 4         17 my $node = $self->_trie;
27 4         26 $node = $node->{$_} for split "", $word;
28 4 100       25 return exists $node->{_END()} ? 1 : 0;
29             }
30              
31             sub smart_find {
32 1     1 1 2 my ($self, $prefix) = @_;
33 1         4 my @letters = split "", $prefix;
34 1         4 my $node = $self->_trie;
35              
36 1         4 $node = $node->{$_} for @letters;
37              
38 1 50       7 if ($node) {
39 1         2 my @found;
40 1         5 $self->_find_all($prefix, $node, \@found);
41 1         6 return @found;
42             }
43 0         0 return;
44             }
45              
46             sub _add_node {
47 10     10   16 my ($self, $word) = @_;
48 10         9 my $head;
49 10         25 my $node = $head = $self->_trie;
50              
51 10         31 my @letters = split "", $word;
52 10   66     55 while ( scalar @letters && exists($node->{$letters[0]}) ) {
53 7         37 $node = $node->{shift(@letters)};
54             }
55 10         19 for my $letter (@letters) {
56 27         58 $node = $node->{$letter} = {};
57             }
58 10         114 $node->{_END()} = undef;
59             }
60              
61             sub _find_all {
62 8     8   11 my ($self, $prefix, $node, $found) = @_;
63 8 100       18 push @$found, $prefix if exists $node->{_END()};
64 8         47 $self->_find_all($prefix . $_, $node->{$_}, $found) for keys %$node;
65             }
66              
67             sub _make_trie {
68 4     4   5 my ($self, $words) = @_;
69 4         13 $self->_add_node($_) for @$words;
70             }
71              
72              
73             1;
74              
75             __END__