File Coverage

blib/lib/Plucene/Index/SegmentTermDocs.pm
Criterion Covered Total %
statement 53 58 91.3
branch 11 12 91.6
condition 3 8 37.5
subroutine 12 14 85.7
pod 6 6 100.0
total 85 98 86.7


line stmt bran cond sub pod time code
1             package Plucene::Index::SegmentTermDocs;
2              
3             =head1 NAME
4              
5             Plucene::Index::SegmentTermDocs - Segment term docs
6              
7             =head1 SYNOPSIS
8              
9             my $seg_term_docs = Plucene::Index::SegmentTermDocs
10             ->new(Plucene::Index::SegmentReader $seg_reader);
11            
12             $seg_term_docs->seek($term);
13             $seg_term_docs->next;
14             $seg_term_docs->read;
15             $seg_term_docs->skip_to($target);
16            
17             =head1 DESCRIPTION
18              
19             This is the segment term docs class.
20              
21             =head1 METHODS
22              
23             =cut
24              
25 18     18   163 use strict;
  18         35  
  18         625  
26 18     18   96 use warnings;
  18         36  
  18         804  
27              
28 18     18   15334 use IO::Handle;
  18         144021  
  18         1003  
29 18     18   144 use Carp qw/confess/;
  18         39  
  18         920  
30              
31 18     18   127 use Plucene::Bitvector;
  18         41  
  18         429  
32              
33 18     18   99 use base 'Class::Accessor::Fast';
  18         39  
  18         16388  
34              
35             __PACKAGE__->mk_accessors(
36             qw(parent freq_stream freq_count deleted_docs doc freq));
37              
38             =head2 new
39              
40             my $seg_term_docs = Plucene::Index::SegmentTermDocs
41             ->new(Plucene::Index::SegmentReader $seg_reader);
42              
43             This will create a new Plucene::Index::SegmentTermDocs object with the passed
44             segment reader.
45            
46             =head2 parent / freq_stream / freq_count / deleted_docs / doc / freq
47              
48             Get / set these attributes.
49            
50             =cut
51              
52             sub new {
53 597     597 1 1223 my $self = shift;
54 597         995 my $seg_reader = shift;
55 597         2121 return bless {
56             parent => $seg_reader,
57             freq_stream => $seg_reader->freq_stream, # listref
58             deleted_docs => $seg_reader->deleted_docs,
59             doc => 0,
60             } => $self;
61             }
62              
63             =head2 seek
64              
65             $seg_term_docs->seek($term);
66              
67             =cut
68              
69             sub seek {
70 33439     33439 1 49529 my ($self, $ti) = @_;
71              
72             # I object to this, but hey.
73 33439 100       198973 if ($ti->isa("Plucene::Index::Term")) {
74 321         1447 $self->_seek($self->parent->{tis}->get($ti));
75             } else {
76 33118         94930 $self->_seek($ti);
77             }
78             }
79              
80             sub _seek {
81 33439     33439   45494 my ($self, $ti) = @_;
82 33439 100       88015 if (!$ti) {
83 88         395 $self->freq_count(0);
84 88         769 return;
85             }
86 33351         92241 $self->freq_count($ti->doc_freq);
87 33351         317568 $self->doc(0);
88 33351         204374 $self->{ptr} = $ti->freq_pointer; # offset in our array
89             }
90              
91             =head2 skipping_doc
92              
93             By default this does nothing. You may wish to override it to do something.
94              
95             =cut
96              
97 0     0 1 0 sub skipping_doc { }
98              
99             sub _read_one {
100 33757     33757   41250 my $self = shift;
101 33757         85721 my $doc_code = $self->freq_stream->[ $self->{ptr}++ ];
102              
103             # A sequence that smacks of overoptimization
104 33757         181088 $self->{doc} += $doc_code >> 1;
105 33757 100       67479 if ($doc_code & 1) {
106 19412         47582 $self->freq(1);
107             } else {
108 14345         34242 $self->freq($self->freq_stream->[ $self->{ptr}++ ]);
109             }
110 33757         232313 $self->{freq_count}--;
111             }
112              
113             =head2 next
114              
115             $seg_term_docs->next;
116              
117             =cut
118              
119             sub next {
120 66552     66552 1 79812 my $self = shift;
121 66552         78805 while (1) {
122 66552 100       155348 return if $self->freq_count == 0;
123 33409         194991 $self->_read_one();
124             last
125 33409 50 33     105233 unless $self->{deleted_docs}
126             && $self->{deleted_docs}->get($self->{doc});
127 0         0 $self->skipping_doc;
128             }
129 33409         105249 return 1;
130             }
131              
132             =head2 read
133              
134             $seg_term_docs->read;
135              
136             =cut
137              
138             # Called by TermScorer and SegmentsTermDocs
139             sub read {
140 493     493 1 786 my $self = shift;
141 493         751 my (@docs, @freqs);
142 493         1677 while ($self->{freq_count} > 0) {
143 348         2048 $self->_read_one;
144             next
145 348 100 66     1462 if $self->{deleted_docs}
146             && $self->{deleted_docs}->get($self->{doc});
147 347         961 push @docs, $self->doc;
148 347         2058 push @freqs, $self->freq;
149             }
150 493         3009 return (\@docs, \@freqs);
151             }
152              
153             =head2 skip_to
154              
155             $seg_term_docs->skip_to($target);
156              
157             =cut
158              
159             sub skip_to {
160 0     0 1   my ($self, $target) = @_;
161 0   0       $self->next || return 0 while $target > $self->doc;
162 0           return 1;
163             }
164              
165             1;