bool SegLexQ_Less_Than_IMP(SegLexQueue *self, Obj *a, Obj *b) { SegLexicon *const lex_a = (SegLexicon*)a; SegLexicon *const lex_b = (SegLexicon*)b; Obj *const term_a = SegLex_Get_Term(lex_a); Obj *const term_b = SegLex_Get_Term(lex_b); UNUSED_VAR(self); return Str_less_than(&term_a, &term_b); }
void PolyLex_Seek_IMP(PolyLexicon *self, Obj *target) { PolyLexiconIVARS *const ivars = PolyLex_IVARS(self); Vector *seg_lexicons = ivars->seg_lexicons; SegLexQueue *lex_q = ivars->lex_q; if (target == NULL) { PolyLex_Reset(self); return; } // Refresh the queue, set vars. S_refresh_lex_q(lex_q, seg_lexicons, target); SegLexicon *least = (SegLexicon*)SegLexQ_Peek(lex_q); DECREF(ivars->term); ivars->term = NULL; if (least) { Obj *least_term = SegLex_Get_Term(least); ivars->term = least_term ? Obj_Clone(least_term) : NULL; } // Scan up to the real target. do { if (ivars->term) { const int32_t comparison = Obj_Compare_To(ivars->term, target); if (comparison >= 0) { break; } } } while (PolyLex_Next(self)); }
bool PolyLex_Next_IMP(PolyLexicon *self) { PolyLexiconIVARS *const ivars = PolyLex_IVARS(self); SegLexQueue *lex_q = ivars->lex_q; SegLexicon *top_seg_lexicon = (SegLexicon*)SegLexQ_Peek(lex_q); // Churn through queue items with equal terms. while (top_seg_lexicon != NULL) { Obj *const candidate = SegLex_Get_Term(top_seg_lexicon); if ((candidate && !ivars->term) || Obj_Compare_To(ivars->term, candidate) != 0 ) { // Succeed if the next item in the queue has a different term. DECREF(ivars->term); ivars->term = Obj_Clone(candidate); return true; } else { SegLexicon *seg_lex = (SegLexicon*)SegLexQ_Pop(lex_q); DECREF(seg_lex); if (SegLex_Next(top_seg_lexicon)) { SegLexQ_Insert(lex_q, INCREF(top_seg_lexicon)); } top_seg_lexicon = (SegLexicon*)SegLexQ_Peek(lex_q); } } // If queue is empty, iterator is finished. DECREF(ivars->term); ivars->term = NULL; return false; }
static void S_refresh_lex_q(SegLexQueue *lex_q, Vector *seg_lexicons, Obj *target) { // Empty out the queue. while (1) { SegLexicon *seg_lex = (SegLexicon*)SegLexQ_Pop(lex_q); if (seg_lex == NULL) { break; } DECREF(seg_lex); } // Refill the queue. for (uint32_t i = 0, max = Vec_Get_Size(seg_lexicons); i < max; i++) { SegLexicon *const seg_lexicon = (SegLexicon*)Vec_Fetch(seg_lexicons, i); SegLex_Seek(seg_lexicon, target); if (SegLex_Get_Term(seg_lexicon) != NULL) { SegLexQ_Insert(lex_q, INCREF(seg_lexicon)); } } }
static TermInfo* S_find_tinfo(DefaultLexiconReader *self, String *field, Obj *target) { DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self); if (field != NULL && target != NULL) { int32_t field_num = Seg_Field_Num(ivars->segment, field); SegLexicon *lexicon = (SegLexicon*)VA_Fetch(ivars->lexicons, field_num); if (lexicon) { // Iterate until the result is ge the term. SegLex_Seek(lexicon, target); //if found matches target, return info; otherwise NULL Obj *found = SegLex_Get_Term(lexicon); if (found && Obj_Equals(target, found)) { return SegLex_Get_Term_Info(lexicon); } } } return NULL; }
TermInfo* DefLexReader_fetch_term_info(DefaultLexiconReader *self, const CharBuf *field, Obj *target) { if (field != NULL && target != NULL) { i32_t field_num = Seg_Field_Num(self->segment, field); SegLexicon *lexicon = (SegLexicon*)VA_Fetch(self->lexicons, field_num); if (lexicon) { /* Iterate until the result is ge the term. */ SegLex_Seek(lexicon, target); /*if found matches target, return info; otherwise NULL */ { Obj *found = SegLex_Get_Term(lexicon); if (found && Obj_Equals(target, found)) { return SegLex_Get_Term_Info(lexicon); } } } } return NULL; }