#include "KinoSearch/Util/ToolSet.h"
#define KINO_WANT_TOPDOCCOLLECTOR_VTABLE
#include "KinoSearch/Search/TopDocCollector.r"
#include "KinoSearch/Search/HitQueue.r"
#include "KinoSearch/Search/ScoreDoc.r"
/* Keep highest scoring docs.
*/
static void
TDColl_collect(TopDocCollector *self, u32_t doc_num, float score);
TopDocCollector*
TDColl_new(u32_t num_hits)
{
CREATE(self, TopDocCollector, TOPDOCCOLLECTOR);
/* init */
self->collect = (HC_collect_t)TDColl_collect;
self->release = NULL;
self->min_score = 0.0;
self->total_hits = 0;
/* assign */
self->num_hits = num_hits;
/* derive */
self->hit_q = kino_HitQ_new(num_hits);
return self;
}
void
TDColl_destroy(TopDocCollector *self)
{
REFCOUNT_DEC(self->hit_q);
free(self);
}
static void
TDColl_collect(TopDocCollector *self, u32_t doc_num, float score)
{
/* add to the total number of hits */
self->total_hits++;
/* bail if the score doesn't exceed the minimum */
if ( self->total_hits > self->num_hits
&& score < self->min_score
) {
return;
}
else if (self->num_hits > 0) {
ScoreDoc *const score_doc = ScoreDoc_new(doc_num, score);
HitQueue *const hit_q = self->hit_q;
HitQ_Insert(hit_q, score_doc);
/* store the bubble score in a more accessible spot */
if (hit_q->size == hit_q->max_size) {
ScoreDoc *const least = (ScoreDoc*)HitQ_Peek(hit_q);
self->min_score = least->score;
}
}
}
/* Copyright 2006-2007 Marvin Humphrey
*
* This program is free software; you can redistribute it and/or modify
* under the same terms as Perl itself.
*/