Lucy
view release on metacpan or search on metacpan
cfcore/Lucy/Index/SegPostingList.c view on Meta::CPAN
uint32_t
SegPList_Get_Doc_Freq_IMP(SegPostingList *self) {
return SegPList_IVARS(self)->doc_freq;
}
int32_t
SegPList_Get_Doc_ID_IMP(SegPostingList *self) {
SegPostingListIVARS *const ivars = SegPList_IVARS(self);
return Post_IVARS(ivars->posting)->doc_id;
}
uint32_t
SegPList_Get_Count_IMP(SegPostingList *self) {
return SegPList_IVARS(self)->count;
}
InStream*
SegPList_Get_Post_Stream_IMP(SegPostingList *self) {
return SegPList_IVARS(self)->post_stream;
}
int32_t
SegPList_Next_IMP(SegPostingList *self) {
SegPostingListIVARS *const ivars = SegPList_IVARS(self);
InStream *const post_stream = ivars->post_stream;
Posting *const posting = ivars->posting;
// Bail if we're out of docs.
if (ivars->count >= ivars->doc_freq) {
Post_Reset(posting);
return 0;
}
ivars->count++;
Post_Read_Record(posting, post_stream);
return Post_IVARS(posting)->doc_id;
}
int32_t
SegPList_Advance_IMP(SegPostingList *self, int32_t target) {
SegPostingListIVARS *const ivars = SegPList_IVARS(self);
PostingIVARS *const posting_ivars = Post_IVARS(ivars->posting);
const int32_t skip_interval = ivars->skip_interval;
if ((int32_t)ivars->doc_freq >= skip_interval) {
InStream *post_stream = ivars->post_stream;
InStream *skip_stream = ivars->skip_stream;
SkipStepper *const skip_stepper = ivars->skip_stepper;
SkipStepperIVARS *const skip_stepper_ivars
= SkipStepper_IVARS(skip_stepper);
int32_t new_doc_id = skip_stepper_ivars->doc_id;
int64_t new_filepos = InStream_Tell(post_stream);
/* Assuming the default skip_interval of 16...
*
* Say we're currently on the 5th doc matching this term, and we get a
* request to skip to the 18th doc matching it. We won't have skipped
* yet, but we'll have already gone past 5 of the 16 skip docs --
* ergo, the modulus in the following formula.
*/
int32_t num_skipped = 0 - ((int32_t)ivars->count % skip_interval);
if (num_skipped == 0 && ivars->count != 0) {
num_skipped = 0 - skip_interval;
}
// See if there's anything to skip.
while (target > skip_stepper_ivars->doc_id) {
new_doc_id = skip_stepper_ivars->doc_id;
new_filepos = skip_stepper_ivars->filepos;
if (skip_stepper_ivars->doc_id != 0
&& skip_stepper_ivars->doc_id >= posting_ivars->doc_id
) {
num_skipped += skip_interval;
}
if (ivars->skip_count >= ivars->num_skips) {
break;
}
SkipStepper_Read_Record(skip_stepper, skip_stream);
ivars->skip_count++;
}
// If we found something to skip, skip it.
if (new_filepos > InStream_Tell(post_stream)) {
// Move the postings filepointer up.
InStream_Seek(post_stream, new_filepos);
// Jump to the new doc id.
posting_ivars->doc_id = new_doc_id;
// Increase count by the number of docs we skipped over.
ivars->count += (uint32_t)num_skipped;
}
}
// Done skipping, so scan.
while (1) {
int32_t doc_id = SegPList_Next(self);
if (doc_id == 0 || doc_id >= target) {
return doc_id;
}
}
}
void
SegPList_Seek_IMP(SegPostingList *self, Obj *target) {
SegPostingListIVARS *const ivars = SegPList_IVARS(self);
LexiconReader *lex_reader = PListReader_Get_Lex_Reader(ivars->plist_reader);
TermInfo *tinfo = LexReader_Fetch_Term_Info(lex_reader,
ivars->field, target);
S_seek_tinfo(self, tinfo);
DECREF(tinfo);
}
void
SegPList_Seek_Lex_IMP(SegPostingList *self, Lexicon *lexicon) {
( run in 0.656 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )