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__

Back to Top

 KinoSearch::Search::HitCollector - process doc/score pairs