KinoSearch::Search::HitCollector - process doc/score pairs |
void collect(hc, doc_num, score) HitCollector *hc; U32 doc_num; float score; PPCODE: hc->collect(hc, doc_num, score);
SV* _set_or_get(hc, ...) HitCollector *hc; ALIAS: _set_storage = 1 get_storage = 2 _set_i = 3 get_i = 4 _set_f = 5 _get_f = 6 _set_filter_bits = 7 _get_filter_bits = 8 CODE: { KINO_START_SET_OR_GET_SWITCH
case 1: SvREFCNT_dec(hc->storage_ref); hc->storage_ref = newSVsv( ST(1) ); Kino_extract_anon_struct(hc->storage_ref, hc->storage); /* fall through */ case 2: RETVAL = newSVsv(hc->storage_ref); break;
case 3: hc->i = SvUV( ST(1) ); /* fall through */ case 4: RETVAL = newSVuv(hc->i); break;
case 5: hc->f = SvNV( ST(1) ); /* fall through */ case 6: RETVAL = newSVnv(hc->f); break; case 7: SvREFCNT_dec(hc->filter_bits_ref); hc->filter_bits_ref = newSVsv( ST(1) ); Kino_extract_struct( hc->filter_bits_ref, hc->filter_bits, BitVector*, "KinoSearch::Util::BitVector" ); /* fall through */ case 8: RETVAL = newSVsv(hc->filter_bits_ref); break;
KINO_END_SET_OR_GET_SWITCH } OUTPUT: RETVAL
void
DESTROY(hc)
HitCollector *hc;
PPCODE:
Kino_HC_destroy(hc);
MODULE = KinoSearch PACKAGE = KinoSearch::Search::HitQueueCollector
void
_define_collect(hc)
HitCollector *hc;
PPCODE:
hc->collect = Kino_HC_collect_HitQueue;
MODULE = KinoSearch PACKAGE = KinoSearch::Search::BitCollector
void
_define_collect(hc)
HitCollector *hc;
PPCODE:
hc->collect = Kino_HC_collect_BitVec;
MODULE = KinoSearch PACKAGE = KinoSearch::Search::FilteredCollector
void _define_collect(hc); HitCollector *hc; PPCODE: hc->collect = Kino_HC_collect_filtered;
MODULE = KinoSearch PACKAGE = KinoSearch::Search::OffsetCollector
void _define_collect(hc); HitCollector *hc; PPCODE: hc->collect = Kino_HC_collect_offset;
__H__
#ifndef H_KINO_HIT_COLLECTOR #define H_KINO_HIT_COLLECTOR 1
#include ``EXTERN.h'' #include ``perl.h'' #include ``XSUB.h'' #include ``KinoSearchUtilCarp.h'' #include ``KinoSearchUtilMathUtils.h'' #include ``KinoSearchUtilBitVector.h'' #include ``KinoSearchUtilPriorityQueue.h'' #include ``KinoSearchUtilMemManager.h''
typedef struct hitcollector { void (*collect)(struct hitcollector*, U32, float); float f; U32 i; void *storage; SV *storage_ref; BitVector *filter_bits; SV *filter_bits_ref; } HitCollector;
HitCollector* Kino_HC_new(); void Kino_HC_collect_death(HitCollector*, U32, float); void Kino_HC_collect_HitQueue(HitCollector*, U32, float); void Kino_HC_collect_BitVec(HitCollector*, U32, float); void Kino_HC_collect_filtered(HitCollector*, U32, float); void Kino_HC_collect_offset(HitCollector*, U32, float); void Kino_HC_destroy(HitCollector*);
#endif /* include guard */
__C__
#include ``KinoSearchSearchHitCollector.h''
HitCollector*
Kino_HC_new()
{
HitCollector *hc;
/* allocate memory and init */ Kino_New(0, hc, 1, HitCollector); hc->f = 0; hc->i = 0; hc->storage = NULL; hc->storage_ref = &PL_sv_undef; hc->filter_bits = NULL; hc->filter_bits_ref = &PL_sv_undef;
/* force the subclass to spec a collect method */ hc->collect = Kino_HC_collect_death;
return hc; }
void Kino_HC_collect_death(HitCollector *hc, U32 doc_num, float score) { Kino_confess(``hit_collector->collect must be assigned in a subclass''); }
void Kino_HC_collect_HitQueue(HitCollector *hc, U32 doc_num, float score) { /* add to the total number of hits */ hc->i++;
/* bail if the score doesn't exceed the minimum */ if (score < hc->f) { return; } else { SV *element; char doc_num_buf[4]; PriorityQueue *hit_queue; hit_queue = (PriorityQueue*)hc->storage;
/* put a dualvar scalar -- encoded doc_num in PV, score in NV */ element = sv_newmortal(); (void)SvUPGRADE(element, SVt_PVNV); Kino_encode_bigend_U32(doc_num, &doc_num_buf); sv_setpvn(element, doc_num_buf, (STRLEN)4); SvNV_set(element, (double)score); SvNOK_on(element); (void)Kino_PriQ_insert(hit_queue, element);
/* store the bubble score in a more accessible spot */ if (hit_queue->size == hit_queue->max_size) { SV *least_sv; least_sv = Kino_PriQ_peek(hit_queue); hc->f = SvNV(least_sv); } } }
void Kino_HC_collect_BitVec(HitCollector *hc, U32 doc_num, float score) { BitVector *bit_vec; bit_vec = (BitVector*)hc->storage;
/* add to the total number of hits */ hc->i++;
/* add the doc_num to the BitVector */ Kino_BitVec_set(bit_vec, doc_num); }
void Kino_HC_collect_filtered(HitCollector *hc, U32 doc_num, float score) { if (hc->filter_bits == NULL) { Kino_confess(``filter_bits not set on FilteredCollector''); }
if (Kino_BitVec_get(hc->filter_bits, doc_num)) { HitCollector *inner_collector; inner_collector = (HitCollector*)hc->storage; inner_collector->collect(inner_collector, doc_num, score); } }
void Kino_HC_collect_offset(HitCollector *hc, U32 doc_num, float score) { HitCollector *inner_collector = (HitCollector*)hc->storage; U32 offset_doc_num = doc_num + hc->f; inner_collector->collect(inner_collector, offset_doc_num, score); }
void Kino_HC_destroy(HitCollector *hc) { SvREFCNT_dec(hc->storage_ref); SvREFCNT_dec(hc->filter_bits_ref); Kino_Safefree(hc); }
__POD__
KinoSearch::Search::HitCollector - process doc/score pairs |