static void S_add_last_term_to_ix(LexiconWriter *self) { // Write file pointer to index record. OutStream_Write_I64(self->ixix_out, OutStream_Tell(self->ix_out)); // Write term and file pointer to main record. Track count of terms added // to ix. TermStepper_Write_Key_Frame(self->term_stepper, self->ix_out, TermStepper_Get_Value(self->term_stepper)); TermStepper_Write_Key_Frame(self->tinfo_stepper, self->ix_out, TermStepper_Get_Value(self->tinfo_stepper)); OutStream_Write_C64(self->ix_out, OutStream_Tell(self->dat_out)); self->ix_count++; }
void LexIndex_Seek_IMP(LexIndex *self, Obj *target) { LexIndexIVARS *const ivars = LexIndex_IVARS(self); TermStepper *term_stepper = ivars->term_stepper; InStream *ix_in = ivars->ix_in; FieldType *type = ivars->field_type; int32_t lo = 0; int32_t hi = ivars->size - 1; int32_t result = -100; if (target == NULL || ivars->size == 0) { ivars->tick = 0; return; } else { if (!Obj_is_a(target, STRING)) { THROW(ERR, "Target is a %o, and not comparable to a %o", Obj_get_class_name(target), Class_Get_Name(STRING)); } /* TODO: Obj *first_obj = Vec_Fetch(terms, 0); if (!Obj_is_a(target, Obj_get_class(first_obj))) { THROW(ERR, "Target is a %o, and not comparable to a %o", Obj_get_class_name(target), Obj_get_class_name(first_obj)); } */ } // Divide and conquer. while (hi >= lo) { const int32_t mid = lo + ((hi - lo) / 2); const int64_t offset = (int64_t)NumUtil_decode_bigend_u64(ivars->offsets + mid); InStream_Seek(ix_in, offset); TermStepper_Read_Key_Frame(term_stepper, ix_in); // Compare values. There is no need for a NULL-check because the term // number is alway between 0 and ivars->size - 1. Obj *value = TermStepper_Get_Value(term_stepper); int32_t comparison = FType_Compare_Values(type, target, value); if (comparison < 0) { hi = mid - 1; } else if (comparison > 0) { lo = mid + 1; } else { result = mid; break; } } // Record the index of the entry we've seeked to, then read entry. ivars->tick = hi == -1 // indicating that target lt first entry ? 0 : result == -100 // if result is still -100, it wasn't set ? hi : result; S_read_entry(self); }
Obj* LexIndex_Get_Term_IMP(LexIndex *self) { LexIndexIVARS *const ivars = LexIndex_IVARS(self); return TermStepper_Get_Value(ivars->term_stepper); }