package KinoSearch::Search::HitQueue; use strict; use warnings; use KinoSearch::Util::ToolSet; use base qw( KinoSearch::Util::PriorityQueue ); BEGIN { __PACKAGE__->init_instance_vars() } use KinoSearch::Search::Hit; sub new { my $either = shift; my $self = $either->SUPER::new(@_); $self->define_less_than; return $self; } # Create an array of "empty" Hit objects -- they have scores and ids, # but the stored fields have yet to be retrieved. sub hits { my ( $self, $start_offset, $num_wanted, $searcher ) = @_; my @hits = @{ $self->pop_all }; if ( defined $start_offset and defined $num_wanted ) { @hits = splice( @hits, $start_offset, $num_wanted ); } @hits = map { KinoSearch::Search::Hit->new( id => unpack( 'N', "$_" ), score => 0 + $_, searcher => $searcher ) } @hits; return \@hits; } 1; __END__ __XS__ MODULE = KinoSearch PACKAGE = KinoSearch::Search::HitQueue void define_less_than(hitq) PriorityQueue *hitq; PPCODE: hitq->less_than = &Kino_HitQ_less_than; __H__ #ifndef H_KINOSEARCH_SEARCH_HIT_QUEUE #define H_KINOSEARCH_SEARCH_HIT_QUEUE 1 #include "EXTERN.h" #include "perl.h" #include "XSUB.h" bool Kino_HitQ_less_than(SV*, SV*); #endif /* include guard */ __C__ #include "KinoSearchSearchHitQueue.h" /* Compare the NV then the PV for two scalars. */ bool Kino_HitQ_less_than(SV* a, SV* b) { char *ptr_a, *ptr_b; if (SvNV(a) == SvNV(b)) { ptr_a = SvPVX(a); ptr_b = SvPVX(b); /* sort by doc_num second */ return (bool) (memcmp(ptr_b, ptr_a, 4) < 0); } /* sort by score first */ return SvNV(a) < SvNV(b); } __POD__ =begin devdocs =head1 NAME KinoSearch::Search::HitQueue - track highest scoring docs =head1 DESCRIPTION HitQueue, a subclass of KinoSearch::Util::PriorityQueue, keeps track of score/doc_num pairs. Each pair is stored in a single scalar, with the document number in the PV and the score in the NV. The encoding algorithm is functionally equivalent to this: my $encoded_doc_num = pack('N', $doc_num); my $doc_num_slash_score = dualvar( $score, $encoded_doc_num ); =head1 COPYRIGHT Copyright 2005-2006 Marvin Humphrey =head1 LICENSE, DISCLAIMER, BUGS, etc. See L version 0.15. =end devdocs =cut