File Coverage

blib/lib/Plucene/Search/PhraseScorer.pm
Criterion Covered Total %
statement 51 52 98.0
branch 6 6 100.0
condition n/a
subroutine 10 11 90.9
pod 2 2 100.0
total 69 71 97.1


line stmt bran cond sub pod time code
1             package Plucene::Search::PhraseScorer;
2              
3             =head1 NAME
4              
5             Plucene::Search::PhraseScorer - a phrase scorer
6              
7             =head1 SYNOPSIS
8              
9             # isa Plucene::Search::Scorer
10              
11             $scorer->score($results, $end);
12            
13             =head1 DESCRIPTION
14              
15             This is the phrase scorer.
16              
17             =head1 METHODS
18              
19             =cut
20              
21 4     4   25 use strict;
  4         41  
  4         137  
22 4     4   23 use warnings;
  4         7  
  4         109  
23              
24 4     4   23 use Tie::Array::Sorted;
  4         8  
  4         97  
25              
26 4     4   2084 use Plucene::Search::PhrasePositions;
  4         12  
  4         32  
27              
28 4     4   125 use base qw(Plucene::Search::Scorer Class::Accessor::Fast);
  4         8  
  4         2715  
29              
30 0     0   0 sub _phrase_freq { die "Abstract method" }
31              
32             __PACKAGE__->mk_accessors(qw/ norms weight pq first last /);
33              
34             sub new {
35 6     6 1 248 my $self = shift->SUPER::new(@_);
36 6         97 my @pq;
37             tie @pq, "Tie::Array::Sorted", sub {
38 109 100   109   1758 $_[0]->doc <=> $_[1]->doc
39             || $_[0]->position <=> $_[1]->position;
40 6         119 };
41              
42 6         81 for my $i (0 .. $#{ $self->{tps} }) {
  6         76  
43 13         280 push @pq,
44             Plucene::Search::PhrasePositions->new({
45             tp => $self->{tps}->[$i],
46             offset => $i
47             });
48             }
49              
50 6         197 $self->{pq} = \@pq;
51              
52 6         85 $self->_pq_to_list();
53 6         73 return $self;
54             }
55              
56             # Thread the array elements together into a linked list
57             sub _pq_to_list {
58 57     57   112 my $self = shift;
59 57         145 $self->{first} = $self->{last} = undef;
60 57         107 while (@{ $self->{pq} }) {
  179         1456  
61 122         794 my $pp = shift @{ $self->{pq} };
  122         425  
62              
63             # If there's an entry already, put this after it
64 122 100       737 if ($self->{last}) { $self->last->next_in_list($pp); }
  65         203  
65              
66             # Else, this is the first one
67 57         200 else { $self->first($pp); }
68              
69             # But it's definitely the last one
70 122         1014 $self->last($pp);
71              
72             # And there's nothing after it, yet.
73 122         743 $pp->next_in_list(undef);
74             }
75             }
76              
77             =head2 score
78              
79             $scorer->score($results, $end);
80            
81             =cut
82              
83             sub score {
84 6     6 1 792 my ($self, $results, $end) = @_;
85 6         26 while ($self->last->doc < $end) {
86 63         912 while ($self->first->doc < $self->last->doc) {
87 67         873 do {
88 73         314 $self->first->next;
89             } while $self->first->doc < $self->last->doc;
90 67         1213 $self->_first_to_last;
91 67 100       702 return if $self->last->doc >= $end;
92             }
93 61         1295 my $freq = $self->_phrase_freq;
94 61         216 $self->_score_it($freq, $self->first->doc, $results);
95 61         449 $self->last->next;
96             }
97             }
98              
99             sub _first_to_last {
100 194     194   310 my $self = shift;
101 194         481 $self->last->next_in_list($self->first);
102 194         2264 $self->last($self->first);
103 194         1670 $self->first($self->first->next_in_list);
104 194         2160 $self->last->next_in_list(undef);
105             }
106              
107             1;