File Coverage

blib/lib/Plucene/Index/Reader.pm
Criterion Covered Total %
statement 48 59 81.3
branch 5 6 83.3
condition n/a
subroutine 16 27 59.2
pod 18 18 100.0
total 87 110 79.0


line stmt bran cond sub pod time code
1             package Plucene::Index::Reader;
2              
3 18     18   94 use strict;
  18         35  
  18         611  
4 18     18   151 use warnings;
  18         57  
  18         476  
5              
6 18     18   94 use Carp;
  18         33  
  18         1576  
7 18     18   102 use Fcntl qw(O_EXCL O_CREAT O_WRONLY);
  18         31  
  18         1059  
8              
9 18     18   12087 use Plucene::Index::SegmentReader;
  18         61  
  18         360  
10 18     18   10981 use Plucene::Index::SegmentInfos;
  18         63  
  18         549  
11 18     18   10370 use Plucene::Index::SegmentsReader;
  18         107  
  18         190  
12              
13             =head1 NAME
14              
15             Plucene::Index::Reader - Abstract class for accessing an index
16              
17             =head1 DESCRIPTION
18              
19             IndexReader is an abstract class, providing an interface for accessing an
20             index. Search of an index is done entirely through this abstract interface, so
21             that any subclass which implements it is searchable.
22              
23             Concrete subclasses of IndexReader are usually constructed with a call to the
24             static method L.
25              
26             For efficiency, in this API documents are often referred to via document
27             numbers, non-negative integers which each name a unique document in the index.
28             These document numbers are ephemeral--they may change as documents are added to
29             and deleted from an index. Clients should thus not rely on a given document
30             having the same number between sessions.
31              
32             =head1 METHODS
33              
34             =head2 new
35              
36             my $reader = Plucene::Index::Reader->new($dir_name);
37              
38             This will create a new Plucene::Index::Reader with the passed in directory.
39              
40             =cut
41              
42             sub new {
43 585     585 1 4919 my ($class, $directory) = @_;
44 585         3779 bless { directory => $directory, writelock => undef }, $class;
45             }
46              
47             =head2 open
48              
49             # If there is only one segment
50             my Plucene::Index::SegmentReader $seg_read = $reader->open;
51              
52             # If there are many segments
53             my Plucene::Index::SegmentsReader $seg_read = $reader->open;
54            
55             Returns an IndexReader reading the index in the given Directory.
56              
57             =cut
58              
59             sub open {
60 180     180 1 491 my ($self, $directory) = @_;
61 180         1894 my $reader = Plucene::Index::SegmentInfos->new;
62 180         1147 $reader->read($directory);
63 180         1034 my @segments = $reader->segments;
64              
65 180 100       1299 return Plucene::Index::SegmentReader->new($reader->info(0), 1)
66             if @segments == 1;
67 40         464 return Plucene::Index::SegmentsReader->new(
68             $directory,
69             map Plucene::Index::SegmentReader->new($reader->info($_),
70             $_ == $#segments),
71             0 .. $#segments
72             );
73              
74             }
75              
76             =head2 last_modified
77              
78             my $last_modified = Plucene::Index::Reader->last_modified($directory);
79              
80             =cut
81              
82 1     1 1 442 sub last_modified { (stat "$_[1]/segments")[9] }
83              
84             =head2 index_exists
85              
86             if (Plucene::Index::Reader->index_exists($directory)){ ... }
87              
88             =cut
89              
90 1     1 1 568 sub index_exists { -e "$_[1]/segments" }
91              
92             =head2 is_locked
93              
94             if (Plucene::Index::Reader->is_locked($directory)){ ... }
95              
96             =cut
97              
98 1     1 1 417 sub is_locked { -e "$_[1]/write.lock" }
99              
100             =head2 delete
101              
102             $reader->delete($doc);
103              
104             =cut
105              
106             sub delete {
107 41     41 1 150 my ($self, $doc) = @_;
108 41         76 local *FH;
109 41 100       89 if (!$self->{writelock}) {
110 2         9 $self->{writelock} = "$self->{directory}/write.lock";
111 2 50       203 sysopen FH, $self->{writelock}, O_EXCL | O_CREAT | O_WRONLY
112             or croak "Couldn't get lock";
113 2         24 close *FH;
114             }
115 41         103 $self->_do_delete($doc);
116 41         726 unlink "$self->{directory}/write.lock";
117             }
118              
119             =head2 delete_term
120              
121             $reader->delete_term($term);
122              
123             This will delete all the documents which contain the passed term.
124            
125             =cut
126              
127             sub delete_term {
128 1     1 1 12 my ($self, $term) = @_;
129 1         6 my $enum = $self->term_docs($term);
130 1         5 $self->delete($enum->doc) while $enum->next;
131             }
132              
133             =head2 close
134              
135             $reader->close;
136              
137             =cut
138              
139             sub close {
140 18     18 1 41 my $self = shift;
141 18         68 $self->_do_close;
142 18         79 $self->unlock($self->{directory});
143             }
144              
145             =head2 unlock
146              
147             $reader->unlock($directory);
148              
149             =cut
150              
151             sub unlock {
152 18     18 1 334 unlink "$_[1]/write.lock";
153 18         309 unlink "$_[1]/commit.lock";
154             }
155              
156             =head2 num_docs / max_doc / document / is_deleted / norms / terms /
157             doc_freq / term_docs / term_positions / _do_delete / _do_close
158              
159             These must be defined in a subclass
160              
161             =cut
162              
163 0     0 1   sub num_docs { die "Please define num_docs in subclass" }
164 0     0 1   sub max_doc { die "Please define max_doc in subclass" }
165 0     0 1   sub document { die "Please define document in subclass" }
166 0     0 1   sub is_deleted { die "Please define is_deleted in subclass" }
167 0     0 1   sub norms { die "Please define norms in subclass" }
168 0     0 1   sub terms { die "Please define terms in subclass" }
169 0     0 1   sub doc_freq { die "Please define doc_freq in subclass" }
170 0     0 1   sub term_docs { die "Please define term_docs in subclass" }
171 0     0 1   sub term_positions { die "Please define term_positions in subclass" }
172 0     0     sub _do_delete { die "Please define _do_delete in subclass" }
173 0     0     sub _do_close { die "Please define _do_close in subclass" }
174              
175             1;