| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package KinoSearch1::Index::IndexReader; |
|
2
|
34
|
|
|
34
|
|
31298
|
use strict; |
|
|
34
|
|
|
|
|
67
|
|
|
|
34
|
|
|
|
|
1233
|
|
|
3
|
34
|
|
|
34
|
|
197
|
use warnings; |
|
|
34
|
|
|
|
|
59
|
|
|
|
34
|
|
|
|
|
922
|
|
|
4
|
34
|
|
|
34
|
|
712
|
use KinoSearch1::Util::ToolSet; |
|
|
34
|
|
|
|
|
65
|
|
|
|
34
|
|
|
|
|
5914
|
|
|
5
|
34
|
|
|
34
|
|
205
|
use base qw( KinoSearch1::Util::Class ); |
|
|
34
|
|
|
|
|
63
|
|
|
|
34
|
|
|
|
|
4581
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
BEGIN { |
|
8
|
34
|
|
|
34
|
|
379
|
__PACKAGE__->init_instance_vars( |
|
9
|
|
|
|
|
|
|
# constructor params / members |
|
10
|
|
|
|
|
|
|
invindex => undef, |
|
11
|
|
|
|
|
|
|
seg_infos => undef, |
|
12
|
|
|
|
|
|
|
close_invindex => 1, |
|
13
|
|
|
|
|
|
|
invindex_owner => 1, |
|
14
|
|
|
|
|
|
|
); |
|
15
|
34
|
|
|
|
|
291
|
__PACKAGE__->ready_get(qw( invindex )); |
|
16
|
|
|
|
|
|
|
} |
|
17
|
|
|
|
|
|
|
|
|
18
|
34
|
|
|
34
|
|
1801
|
use KinoSearch1::Store::FSInvIndex; |
|
|
34
|
|
|
|
|
84
|
|
|
|
34
|
|
|
|
|
811
|
|
|
19
|
34
|
|
|
34
|
|
22207
|
use KinoSearch1::Index::SegReader; |
|
|
34
|
|
|
|
|
116
|
|
|
|
34
|
|
|
|
|
1203
|
|
|
20
|
34
|
|
|
34
|
|
21232
|
use KinoSearch1::Index::MultiReader; |
|
|
34
|
|
|
|
|
115
|
|
|
|
34
|
|
|
|
|
1631
|
|
|
21
|
34
|
|
|
34
|
|
20944
|
use KinoSearch1::Index::SegInfos; |
|
|
34
|
|
|
|
|
311
|
|
|
|
34
|
|
|
|
|
1481
|
|
|
22
|
34
|
|
|
|
|
25153
|
use KinoSearch1::Index::IndexFileNames qw( |
|
23
|
|
|
|
|
|
|
WRITE_LOCK_NAME WRITE_LOCK_TIMEOUT |
|
24
|
|
|
|
|
|
|
COMMIT_LOCK_NAME COMMIT_LOCK_TIMEOUT |
|
25
|
34
|
|
|
34
|
|
308
|
); |
|
|
34
|
|
|
|
|
76
|
|
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub new { |
|
28
|
65
|
|
|
65
|
1
|
461
|
my $temp = shift->SUPER::new(@_); |
|
29
|
65
|
|
|
|
|
283
|
return $temp->_open_multi_or_segreader; |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# Returns a subclass of IndexReader: either a MultiReader or a SegReader, |
|
33
|
|
|
|
|
|
|
# depending on whether an invindex contains more than one segment. |
|
34
|
|
|
|
|
|
|
sub _open_multi_or_segreader { |
|
35
|
65
|
|
|
65
|
|
135
|
my $self = shift; |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# confirm an InvIndex object or make one using a supplied filepath. |
|
38
|
65
|
100
|
|
|
|
388
|
if ( !a_isa_b( $self->{invindex}, 'KinoSearch1::Store::InvIndex' ) ) { |
|
39
|
1
|
|
|
|
|
9
|
$self->{invindex} = KinoSearch1::Store::FSInvIndex->new( |
|
40
|
|
|
|
|
|
|
path => $self->{invindex} ); |
|
41
|
|
|
|
|
|
|
} |
|
42
|
65
|
|
|
|
|
164
|
my $invindex = $self->{invindex}; |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# read the segments file and decide what to do |
|
45
|
65
|
|
|
|
|
108
|
my $reader; |
|
46
|
|
|
|
|
|
|
$invindex->run_while_locked( |
|
47
|
|
|
|
|
|
|
lock_name => COMMIT_LOCK_NAME, |
|
48
|
|
|
|
|
|
|
timeout => COMMIT_LOCK_TIMEOUT, |
|
49
|
|
|
|
|
|
|
do_body => sub { |
|
50
|
65
|
|
|
65
|
|
471
|
my $seg_infos = KinoSearch1::Index::SegInfos->new; |
|
51
|
65
|
|
|
|
|
307
|
$seg_infos->read_infos($invindex); |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# create a SegReader for each segment in the invindex |
|
54
|
65
|
|
|
|
|
151
|
my @seg_readers; |
|
55
|
65
|
|
|
|
|
302
|
for my $sinfo ( $seg_infos->infos ) { |
|
56
|
94
|
|
|
|
|
457
|
push @seg_readers, |
|
57
|
|
|
|
|
|
|
KinoSearch1::Index::SegReader->new( |
|
58
|
|
|
|
|
|
|
seg_name => $sinfo->get_seg_name, |
|
59
|
|
|
|
|
|
|
invindex => $invindex, |
|
60
|
|
|
|
|
|
|
); |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
# if there's one SegReader use it; otherwise make a MultiReader |
|
63
|
|
|
|
|
|
|
$reader |
|
64
|
65
|
100
|
|
|
|
774
|
= @seg_readers == 1 |
|
65
|
|
|
|
|
|
|
? $seg_readers[0] |
|
66
|
|
|
|
|
|
|
: KinoSearch1::Index::MultiReader->new( |
|
67
|
|
|
|
|
|
|
invindex => $invindex, |
|
68
|
|
|
|
|
|
|
sub_readers => \@seg_readers, |
|
69
|
|
|
|
|
|
|
); |
|
70
|
|
|
|
|
|
|
}, |
|
71
|
65
|
|
|
|
|
602
|
); |
|
72
|
|
|
|
|
|
|
|
|
73
|
65
|
|
|
|
|
1078
|
return $reader; |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=begin comment |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
my $num = $reader->max_doc; |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Return the highest document number available to the reader. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=end comment |
|
83
|
|
|
|
|
|
|
=cut |
|
84
|
|
|
|
|
|
|
|
|
85
|
0
|
|
|
0
|
0
|
|
sub max_doc { shift->abstract_death } |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=begin comment |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my $num = $reader->num_docs; |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Return the number of (non-deleted) documents available to the reader. |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=end comment |
|
94
|
|
|
|
|
|
|
=cut |
|
95
|
|
|
|
|
|
|
|
|
96
|
0
|
|
|
0
|
0
|
|
sub num_docs { shift->abstract_death } |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=begin comment |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
my $term_docs = $reader->term_docs($term); |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Given a Term, return a TermDocs subclass. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=end comment |
|
105
|
|
|
|
|
|
|
=cut |
|
106
|
|
|
|
|
|
|
|
|
107
|
0
|
|
|
0
|
0
|
|
sub term_docs { shift->abstract_death } |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=begin comment |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
my $norms_reader = $reader->norms_reader($field_name); |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
Given a field name, return a NormsReader object. |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=end comment |
|
116
|
|
|
|
|
|
|
=cut |
|
117
|
|
|
|
|
|
|
|
|
118
|
0
|
|
|
0
|
0
|
|
sub norms_reader { shift->abstract_death } |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=begin comment |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
$reader->delete_docs_by_term( $term ); |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Delete all the documents available to the reader that index the given Term. |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=end comment |
|
127
|
|
|
|
|
|
|
=cut |
|
128
|
|
|
|
|
|
|
|
|
129
|
0
|
|
|
0
|
0
|
|
sub delete_docs_by_term { shift->abstract_death } |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=begin comment |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
$boolean = $reader->has_deletions |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Return true if any documents have been marked as deleted. |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=end comment |
|
138
|
|
|
|
|
|
|
=cut |
|
139
|
|
|
|
|
|
|
|
|
140
|
0
|
|
|
0
|
0
|
|
sub has_deletions { shift->abstract_death } |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=begin comment |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
my $enum = $reader->terms($term); |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Given a Term, return a TermEnum subclass. The Enum will be be pre-located via |
|
147
|
|
|
|
|
|
|
$enum->seek($term) to the right spot. |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=end comment |
|
150
|
|
|
|
|
|
|
=cut |
|
151
|
|
|
|
|
|
|
|
|
152
|
0
|
|
|
0
|
0
|
|
sub terms { shift->abstract_death } |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=begin comment |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
my $field_names = $reader->get_field_names( |
|
157
|
|
|
|
|
|
|
indexed => $indexed_fields_only, |
|
158
|
|
|
|
|
|
|
); |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Return a hashref which is a list of field names. If the parameter 'indexed' |
|
161
|
|
|
|
|
|
|
is true, return only the names of fields which are indexed. |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=end comment |
|
164
|
|
|
|
|
|
|
=cut |
|
165
|
|
|
|
|
|
|
|
|
166
|
0
|
|
|
0
|
0
|
|
sub get_field_names { shift->abstract_death } |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=begin comment |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
my $infos = $reader->generate_field_infos; |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
Return a new FieldInfos object, describing all the fields held by the reader. |
|
173
|
|
|
|
|
|
|
The FieldInfos object will be consolidated, and thus may not be representative |
|
174
|
|
|
|
|
|
|
of every field in every segment if there are conflicting definitions. |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=end comment |
|
177
|
|
|
|
|
|
|
=cut |
|
178
|
|
|
|
|
|
|
|
|
179
|
0
|
|
|
0
|
0
|
|
sub generate_field_infos { shift->abstract_death } |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=begin comment |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
my @sparse_segreaders = $reader->segreaders_to_merge; |
|
184
|
|
|
|
|
|
|
my @all_segreaders = $reader->segreaders_to_merge('all'); |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Find segments which are good candidates for merging, as they don't contain |
|
187
|
|
|
|
|
|
|
many valid documents. Returns an array of SegReaders. If passed an argument, |
|
188
|
|
|
|
|
|
|
return all SegReaders. |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=end comment |
|
191
|
|
|
|
|
|
|
=cut |
|
192
|
|
|
|
|
|
|
|
|
193
|
0
|
|
|
0
|
0
|
|
sub segreaders_to_merge { shift->abstract_death } |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=begin comment |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
$reader->close; |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Release all resources. |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=end comment |
|
202
|
|
|
|
|
|
|
=cut |
|
203
|
|
|
|
|
|
|
|
|
204
|
0
|
|
|
0
|
0
|
|
sub close { shift->abstract_death } |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
1; |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
__END__ |