File Coverage

blib/lib/Plucene/Index/FieldInfos.pm
Criterion Covered Total %
statement 52 53 98.1
branch 11 14 78.5
condition 3 3 100.0
subroutine 14 15 93.3
pod 8 8 100.0
total 88 93 94.6


line stmt bran cond sub pod time code
1             package Plucene::Index::FieldInfos;
2              
3             =head1 NAME
4              
5             Plucene::Index::FieldInfos - a collection of FieldInfo objects
6              
7             =head1 SYNOPSIS
8              
9             my $fis = Plucene::Index::FieldInfos->new($dir_name);
10             my $fis = Plucene::Index::FieldInfos->new($dir_name, $file);
11              
12             $fis->add(Plucene::Document $doc, $indexed);
13             $fis->add(Plucene::Index::FieldInfos $other_fis, $indexed);
14             $fis->add($name, $indexed);
15              
16             $fis->write($path);
17              
18             my @fields = $fis->fields;
19              
20             my $field_number = $fis->field_number($name);
21             my $field_info = $fis->field_info($name);
22             my $field_name = $fis->field_name($number);
23             my $num_fields = $fis->size;
24            
25              
26             =head1 DESCRIPTION
27              
28             This is a collection of field info objects, which happen to live in
29             the field infos file.
30              
31             =head1 METHODS
32              
33             =cut
34              
35 19     19   111400 use strict;
  19         38  
  19         684  
36 19     19   185 use warnings;
  19         175  
  19         617  
37              
38 19     19   100 use Carp qw(confess);
  19         34  
  19         1025  
39 19     19   4163 use File::Slurp;
  19         111115  
  19         1831  
40 19         155 use Class::Struct 'Plucene::Index::FieldInfo' =>
41 19     19   20749 [ name => '$', is_indexed => '$', number => '$' ];
  19         45450  
42              
43             =head2 new
44              
45             my $fis = Plucene::Index::FieldInfos->new($dir_name);
46             my $fis = Plucene::Index::FieldInfos->new($dir_name, $file);
47              
48             This will create a new Plucene::Index::FieldInfos object with the passed
49             directory and optional filename.
50            
51             =cut
52              
53             sub new {
54 841     841 1 4837 my ($class, $dir, $file) = @_;
55 841         3051 my $self = bless {}, $class;
56 841 100       5059 $file
57             ? $self->_read("$dir/$file")
58             : $self->_add_internal("", 0);
59 841         3757 return $self;
60             }
61              
62             =head2 add
63              
64             $fis->add(Plucene::Document $doc, $indexed);
65             $fis->add(Plucene::Index::FieldInfos $other_fis, $indexed);
66             $fis->add($name, $indexed);
67              
68             This will add the fields from a Plucene::Document or a
69             Plucene::Index::FieldsInfos to the field infos file.
70              
71             It is also possible to pass the name of a field and have it added
72             to the file.
73            
74             =cut
75              
76             sub add {
77 1574     1574 1 21758 my ($self, $obj, $indexed) = @_;
78 1574 100 100     13398 if ( UNIVERSAL::isa($obj, "Plucene::Document")
79             or UNIVERSAL::isa($obj, "Plucene::Index::FieldInfos")) {
80 531         1825 $self->add($_->name, $_->is_indexed) for $obj->fields;
81 531         3872 return;
82             }
83 1043 50       2343 confess "Don't yet know how to handle a $obj" if ref $obj;
84 1043         1556 my $name = $obj; # For clarity. :)
85 1043         2429 my $fi = $self->field_info($name);
86 1043 100       20872 $fi
87             ? $fi->is_indexed($indexed)
88             : $self->_add_internal($name, $indexed);
89             }
90              
91             sub _add_internal {
92 2167     2167   3816 my ($self, $name, $indexed) = @_;
93 2167         59904 my $fi = Plucene::Index::FieldInfo->new(
94             name => $name,
95             is_indexed => $indexed,
96 2167         3697 number => $#{ $self->{bynumber} } + 1,
97             );
98 2167         83848 push @{ $self->{bynumber} }, $fi;
  2167         5022  
99 2167         12680 $self->{byname}{$name} = $fi;
100             }
101              
102             =head2 field_number
103              
104             my $field_number = $fis->field_number($name);
105              
106             This will return the field number of the field with $name. If there is
107             no match, then -1 is returned.
108            
109             =cut
110              
111             sub field_number {
112 48263     48263 1 275578 my ($self, $name) = @_;
113 48263 50       104190 return -1 unless defined $name;
114 48263 50       138170 my $field = $self->{byname}{$name} or return -1;
115 48263         1125339 return $field->number;
116             }
117              
118             =head2 fields
119              
120             my @fields = $fis->fields;
121              
122             This will return all the fields.
123              
124             =cut
125              
126 1131     1131 1 6748 sub fields { return @{ $_[0]->{bynumber} } }
  1131         31379  
127              
128             =head2 field_info
129              
130             my $field_info = $fis->field_info($name);
131              
132             This will return the field info for the field called $name.
133              
134             =cut
135              
136             # Please ensure nothing in the code tries passing this a number. :(
137 1043     1043 1 2629 sub field_info { $_[0]->{byname}{ $_[1] } }
138              
139             =head2 field_name
140              
141             my $field_name = $fis->field_name($number);
142              
143             This will return the field name for the field whose number is $number.
144              
145             =cut
146              
147 69226     69226 1 1575877 sub field_name { $_[0]->{bynumber}[ $_[1] ]->name }
148              
149             =head2 size
150              
151             my $num_fields = $fis->size;
152              
153             This returns the number of field info objects.
154              
155             =cut
156              
157 0     0 1 0 sub size { scalar $_[0]->fields }
158              
159             =head2 write
160              
161             $fis->write($path);
162              
163             This will write the field info objects to $path.
164              
165             =cut
166              
167             # Called by DocumentWriter->add_document and
168             # SegmentMerger->merge_fields
169              
170             sub write {
171 296     296 1 700 my ($self, $file) = @_;
172 296         595 my @fi = @{ $self->{bynumber} };
  296         1009  
173 296         1097 my $template = "w" . ("w/a*C" x @fi);
174 730 100       22014 my $packed = pack $template, scalar(@fi),
175 296         686 map { $_->name => ($_->is_indexed ? 1 : 0) } @fi;
176 296         6382 write_file($file => $packed);
177             }
178              
179             sub _read {
180 544     544   1070 my ($self, $filename) = @_;
181 544         2234 my @fields = unpack "w/(w/aC)", read_file($filename);
182 544         56879 while (my ($field, $indexed) = splice @fields, 0, 2) {
183 1435         4261 $self->_add_internal($field => $indexed);
184             }
185             }
186              
187             1;