/**
* @class ScorerDocQueue ScorerDocQueue.r
* @brief PriorityQueue for ordering Scorers by doc.
*
* ScorerDocQueue is designed to sort multiple scorers by document number and
* aggregate scores based on which items in the queue share the current doc
* number. It is derived from PriorityQueue, but is not a subclass -- the
* code has been unrolled for performance.
*/
#ifndef H_KINO_SCORERDOCQUEUE
#define H_KINO_SCORERDOCQUEUE 1
#include "KinoSearch/Util/Obj.r"
#include "KinoSearch/Search/Scorer.r"
/* A wrapper for a Scorer which caches the result of Scorer_Doc().
*/
typedef struct kino_HeapedScorerDoc {
struct kino_Scorer *scorer;
chy_u32_t doc;
} kino_HeapedScorerDoc;
typedef struct kino_ScorerDocQueue kino_ScorerDocQueue;
typedef struct KINO_SCORERDOCQUEUE_VTABLE KINO_SCORERDOCQUEUE_VTABLE;
KINO_FINAL_CLASS("KinoSearch::Search::ScorerDocQueue", "ScorerDocQ",
"KinoSearch::Util::Obj");
struct kino_ScorerDocQueue {
KINO_SCORERDOCQUEUE_VTABLE *_;
KINO_OBJ_MEMBER_VARS;
kino_HeapedScorerDoc **heap;
kino_HeapedScorerDoc **pool; /**< Pool of HSDs to minimize mallocs */
char *blob; /**< single allocation for all HSDs */
kino_HeapedScorerDoc *top_hsd; /**< cached top elem */
chy_u32_t size;
chy_u32_t max_size;
};
/* Constructor.
*
* @arg max_size The maximum number of Scorers the queue can hold.
*/
kino_ScorerDocQueue*
kino_ScorerDocQ_new(chy_u32_t max_size);
void
kino_ScorerDocQ_destroy(kino_ScorerDocQueue *self);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Destroy");
void
kino_ScorerDocQ_put(kino_ScorerDocQueue *self, struct kino_Scorer *scorer);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Put");
chy_bool_t
kino_ScorerDocQ_insert(kino_ScorerDocQueue *self, struct kino_Scorer *scorer);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Insert");
/* Call Scorer_Next() on the top score and adjust the queue, removing the
* Scorer if Scorer_Next() returns false.
*/
chy_bool_t
kino_ScorerDocQ_top_next(kino_ScorerDocQueue *self);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Top_Next");
/* Call Scorer_Skip_To() on the top scorer and adjust the queue, removing the
* Scorer if Scorer_Skip_To() returns false.
*/
chy_bool_t
kino_ScorerDocQ_top_skip_to(kino_ScorerDocQueue *self, chy_u32_t target);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Top_Skip_To");
/* Pop the scorer with the lowest doc off the top of the queue.
*/
struct kino_Scorer*
kino_ScorerDocQ_pop(kino_ScorerDocQueue *self);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Pop");
/* Reorder the queue after the value of Scorer_Doc() for the least Scorer has
* changed.
*/
void
kino_ScorerDocQ_adjust_top(kino_ScorerDocQueue *self);
KINO_FINAL_METHOD("Kino_ScorerDocQ_Adjust_Top");
KINO_END_CLASS
/* Get the Scorer at the top of the queue -- with the least document number.
* Don't call this (or any of the other peeks) when Queue is empty.
*/
#define KINO_SCORERDOCQ_PEEK(self) (self)->top_hsd->scorer
/* Get the document number of the Scorer at the front of the queue.
*/
#define KINO_SCORERDOCQ_PEEK_DOC(self) (self)->top_hsd->doc
/* Get the Tally from the Scorer at the front of the queue. Note that this is
* not the same as the aggregate Tally for the doc.
*/
#define KINO_SCORERDOCQ_PEEK_TALLY(self) \
Kino_Scorer_Tally((self)->top_hsd->scorer)
/* Return the number of Scorers in the queue.
*/
#define KINO_SCORERDOCQ_SIZE(self) (self)->size
#ifdef KINO_USE_SHORT_NAMES
#define HeapedScorerDoc kino_HeapedScorerDoc
#define SCORERDOCQ_PEEK(self) KINO_SCORERDOCQ_PEEK(self)
#define SCORERDOCQ_PEEK_DOC(self) KINO_SCORERDOCQ_PEEK_DOC(self)
#define SCORERDOCQ_PEEK_TALLY(self) KINO_SCORERDOCQ_PEEK_TALLY(self)
#define SCORERDOCQ_SIZE(self) KINO_SCORERDOCQ_SIZE(self)
#endif
#endif /* H_KINO_SCORERDOCQUEUE */
/* Copyright 2007 Marvin Humphrey
*
* This program is free software; you can redistribute it and/or modify
* under the same terms as Perl itself.
*/