| Plucene documentation | Contained in the Plucene distribution. |
Plucene::Index::SegmentReader - the Segment reader
my $seg_reader =
Plucene::Index::SegmentReader->new( Plucene::Index::SegmentInfo $si);
my @files = $seg_reader->files;
my @terms = $seg_reader->terms;
my $doc = $seg_reader->document($id);
my $doc_freq = $seg_reader->doc_freq($term);
my $max_doc = $seg_reader->max_doc;
my $norms = $seg_reader->norms($field, $offset);
my Plucene::Index::SegmentTermDocs $docs
= $seg_reader->term_docs($term);
my Plucene::Index::SegmentTermPositions $pos
= $seg_reader->term_positions($term);
my Plucene::Store::InputStream $stream
= $seg_reader->norm_stream($field);
if ($seg_reader->is_deleted($id)) { .. }
if ($seg_reader->has_deletions(Plucene::Index::SegmentInfo $si))
{ ... }
The segment reader class.
my $seg_reader = Plucene::Index::SegmentReader->new( Plucene::Index::SegmentInfo $si);
This will create a new Plucene::Index::SegmentReader object.
if ($seg_reader->has_deletions(Plucene::Index::SegmentInfo $si))
{ ... }
my @files = $seg_reader->files;
my @terms = $seg_reader->terms;
my $doc = $seg_reader->document($id);
if ($seg_reader->is_deleted($id)) { .. }
my Plucene::Index::SegmentTermDocs $docs = $seg_reader->term_docs($term);
This will return the Plucene::Index::SegmentTermDocs object for the given term.
my Plucene::Index::SegmentTermPositions $pos = $seg_reader->term_positions($term);
This will return the Plucene::Index::SegmentTermPositions object for the given term.
my $doc_freq = $seg_reader->doc_freq($term);
This returns the number of documents containing the passed term.
my $num_docs = $seg_reader->num_docs;
This is the number of documents, excluding deleted ones.
my $max_doc = $seg_reader->max_doc;
my $norms = $seg_reader->norms($field, $offset);
This returns the byte-encoded normalisation factor for the passed field. This is used by the search code to score documents.
Note we are not using the 'offset' and 'bytes' arguments per the Java. Instead, callers should use substr to put the result of "norms" into the appropriate place in a string.
my Plucene::Store::InputStream $stream = $seg_reader->norm_stream($field);
This will return the Plucene::Store::InputStream for the passed field.
| Plucene documentation | Contained in the Plucene distribution. |
package Plucene::Index::SegmentReader;
use strict; use warnings; use File::Slurp; use Plucene::Bitvector; use Plucene::Index::FieldInfos; use Plucene::Index::FieldsReader; use Plucene::Index::SegmentTermDocs; use Plucene::Index::SegmentTermPositions; use Plucene::Index::TermInfosReader; use Plucene::Utils; use Plucene::Store::InputStream; use Plucene::Store::OutputStream; use base qw(Plucene::Index::Reader Class::Accessor::Fast); __PACKAGE__->mk_accessors( qw(field_infos fields_reader deleted_docs freq_stream prox_stream directory) );
sub new { my ($class, $si) = @_; my $self = $class->SUPER::new($si->dir); my $segment = $self->{segment} = $si->name; $self->field_infos( Plucene::Index::FieldInfos->new($self->{directory}, "$segment.fnm")); $self->fields_reader( Plucene::Index::FieldsReader->new( $self->{directory}, $segment, $self->{field_infos})); $self->{tis} = Plucene::Index::TermInfosReader->new($self->{directory}, $segment, $self->{field_infos}); if ($self->has_deletions($si)) { my $stream = Plucene::Store::InputStream->new("$self->{directory}/$segment.del"); $self->deleted_docs(Plucene::Bitvector->read($stream)); } $self->freq_stream( [ unpack "(w)*", read_file("$self->{directory}/$segment.frq") ]); $self->prox_stream( [ unpack "(w)*", read_file("$self->{directory}/$segment.prx") ]); $self->_open_norms; return $self; } sub _do_close { my $self = shift; if ($self->{deleted_docs_dirty}) { my $file = "$self->{directory}/$self->{segment}"; do_locked { my $stream = Plucene::Store::OutputStream->new($file . ".tmp"); $self->deleted_docs->write($stream); $stream->close; rename $file . ".tmp", $file . ".del"; } "$self->{directory}/commit.lock"; $self->{deleted_docs_dirty} = 0; } }
sub has_deletions { -e ($_[1]->dir . "/" . $_[1]->name . ".del"); } sub _do_delete { my ($self, $doc_num) = @_; $self->{deleted_docs} = Plucene::Bitvector->new(size => $self->max_doc) unless $self->deleted_docs; $self->deleted_docs->set($doc_num); $self->{deleted_docs_dirty} = 1; }
sub files { my $self = shift; my $segment = $self->{segment}; my @files = map "$segment.$_", qw( fnm fdx fdt tii tis frq prx); push @files, "$segment.del" if -e "$self->{directory}/$segment.del"; my @fi = $self->field_infos->fields; ($fi[$_]->is_indexed && push @files, "$segment.f$_") for 0 .. $#fi; return @files; }
sub terms { shift->{tis}->terms(@_) }
sub document { my ($self, $id) = @_; die "Attempt to access deleted document $id" if $self->is_deleted($id); return $self->{fields_reader}->doc($id); }
sub is_deleted { $_[0]->{deleted_docs} ? $_[0]->{deleted_docs}->get($_[1]) : 0; }
sub term_docs { my ($self, $term) = @_; my $docs = Plucene::Index::SegmentTermDocs->new($self); if ($term) { $docs->seek($term) } return $docs; }
sub term_positions { my ($self, $term) = @_; my $pos = Plucene::Index::SegmentTermPositions->new($self); $pos->seek($term) if $term; return $pos; }
sub doc_freq { my ($self, $term) = @_; my $ti = $self->{tis}->get($term) or return 0; return $ti->doc_freq; }
sub num_docs { my $self = shift; my $num = $self->max_doc; $num -= $self->deleted_docs->count if $self->deleted_docs; $num; }
sub max_doc { $_[0]->fields_reader->size; }
sub norms { my ($self, $field, $offset) = @_; my $norm = $self->{norms}->{$field} or return; return $norm->{bytes} ||= $self->_norm_read_from_stream($field); } sub _norm_read_from_stream { my ($self, $field) = @_; my $ns = $self->norm_stream($field) or return; $ns->read(my $output, $self->max_doc); return $output; }
sub norm_stream { my ($self, $field) = @_; my $norm = $self->{norms}->{$field} or return; # Clone the norm's filehandle my $clon = $norm->{in}->clone; $clon->seek(0, 0); return $clon; } sub _open_norms { my $self = shift; for my $fi (grep $_->is_indexed, $self->field_infos->fields) { my $file = "$self->{directory}/$self->{segment}.f" . $fi->number; my $fh = Plucene::Store::InputStream->new($file) or die $file . " :" . $!; $self->{norms}{ $fi->name } = Plucene::Index::Norm->new($fh); } } package Plucene::Index::Norm; sub new { bless { in => $_[1] }, $_[0] } # They have bytes, too, but we're not worrying about that. 1;