float ReqOptMatcher_Score_IMP(RequiredOptionalMatcher *self) { RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self); int32_t const current_doc = Matcher_Get_Doc_ID(ivars->req_matcher); if (ivars->opt_matcher_first_time) { ivars->opt_matcher_first_time = false; if (ivars->opt_matcher != NULL && !Matcher_Advance(ivars->opt_matcher, current_doc)) { DECREF(ivars->opt_matcher); ivars->opt_matcher = NULL; } } if (ivars->opt_matcher == NULL) { return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1]; } else { int32_t opt_matcher_doc = Matcher_Get_Doc_ID(ivars->opt_matcher); if (opt_matcher_doc < current_doc) { opt_matcher_doc = Matcher_Advance(ivars->opt_matcher, current_doc); if (!opt_matcher_doc) { DECREF(ivars->opt_matcher); ivars->opt_matcher = NULL; float req_score = Matcher_Score(ivars->req_matcher); return req_score * ivars->coord_factors[1]; } } if (opt_matcher_doc == current_doc) { float score = Matcher_Score(ivars->req_matcher) + Matcher_Score(ivars->opt_matcher); score *= ivars->coord_factors[2]; return score; } else { return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1]; } } }
i32_t SeriesMatcher_advance(SeriesMatcher *self, i32_t target) { if (target >= self->next_offset) { /* Proceed to next matcher or bail. */ if (self->tick < self->num_matchers) { while (1) { u32_t next_offset = self->tick + 1 == self->num_matchers ? I32_MAX : I32Arr_Get(self->offsets, self->tick + 1); self->current_matcher = (Matcher*)VA_Fetch(self->matchers, self->tick); self->current_offset = self->next_offset; self->next_offset = next_offset; self->doc_id = next_offset - 1; self->tick++; if ( self->current_matcher != NULL || self->tick >= self->num_matchers ) { break; } } return SeriesMatcher_advance(self, target); /* Recurse. */ } else { /* We're done. */ self->doc_id = 0; return 0; } } else { i32_t target_minus_offset = target - self->current_offset; i32_t found = Matcher_Advance(self->current_matcher, target_minus_offset); if (found) { self->doc_id = found + self->current_offset; return self->doc_id; } else { return SeriesMatcher_advance(self, self->next_offset); /* Recurse. */ } } }
void Matcher_collect(Matcher *self, Collector *collector, Matcher *deletions) { int32_t doc_id = 0; int32_t next_deletion = deletions ? 0 : INT32_MAX; Coll_Set_Matcher(collector, self); // Execute scoring loop. while (1) { if (doc_id > next_deletion) { next_deletion = Matcher_Advance(deletions, doc_id); if (next_deletion == 0) { next_deletion = INT32_MAX; } continue; } else if (doc_id == next_deletion) { // Skip past deletions. while (doc_id == next_deletion) { // Artifically advance matcher. while (doc_id == next_deletion) { doc_id++; next_deletion = Matcher_Advance(deletions, doc_id); if (next_deletion == 0) { next_deletion = INT32_MAX; } } // Verify that the artificial advance actually worked. doc_id = Matcher_Advance(self, doc_id); if (doc_id > next_deletion) { next_deletion = Matcher_Advance(deletions, doc_id); } } } else { doc_id = Matcher_Advance(self, doc_id + 1); if (doc_id >= next_deletion) { next_deletion = Matcher_Advance(deletions, doc_id); if (doc_id == next_deletion) { continue; } } } if (doc_id) { Coll_Collect(collector, doc_id); } else { break; } } Coll_Set_Matcher(collector, NULL); }
static CFISH_INLINE int32_t SI_top_advance(ORMatcher *self, ORMatcherIVARS *ivars, int32_t target) { HeapedMatcherDoc *const top_hmd = ivars->top_hmd; top_hmd->doc = Matcher_Advance(top_hmd->matcher, target); return S_adjust_root(self, ivars); }
int32_t ReqOptMatcher_Advance_IMP(RequiredOptionalMatcher *self, int32_t target) { RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self); return Matcher_Advance(ivars->req_matcher, target); }
static INLINE int32_t SI_top_advance(ORMatcher *self, int32_t target) { HeapedMatcherDoc *const top_hmd = self->top_hmd; top_hmd->doc = Matcher_Advance(top_hmd->matcher, target); return S_adjust_root(self); }