Exemplo n.º 1
0
static int32_t
S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) {
    RangeQuery *parent     = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
    Obj        *upper_term = RangeQuery_IVARS(parent)->upper_term;
    int32_t     retval     = INT32_MAX;

    if (upper_term) {
        int32_t hi_ord = SortCache_Find(sort_cache, upper_term);
        if (hi_ord < 0) {
            // The supplied term is lower than all terms in the field.
            retval = -1;
        }
        else {
            Obj *hi_found = SortCache_Value(sort_cache, hi_ord);
            bool exact_match = hi_found == NULL
                                 ? false
                                 : Obj_Equals(upper_term, (Obj*)hi_found);

            retval = hi_ord;
            if (exact_match && !RangeQuery_IVARS(parent)->include_upper) {
                retval--;
            }
            DECREF(hi_found);
        }
    }

    return retval;
}
Exemplo n.º 2
0
static int32_t
S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
    RangeQuery *parent      = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
    Obj        *lower_term  = RangeQuery_IVARS(parent)->lower_term;
    int32_t     lower_bound = 0;

    if (lower_term) {
        int32_t low_ord = SortCache_Find(sort_cache, lower_term);
        if (low_ord < 0) {
            // The supplied term is lower than all terms in the field.
            lower_bound = 0;
        }
        else {
            Obj *low_found = SortCache_Value(sort_cache, low_ord);
            bool exact_match = low_found == NULL
                                 ? false
                                 : Obj_Equals(lower_term, low_found);

            lower_bound = low_ord;
            if (!exact_match || !RangeQuery_IVARS(parent)->include_lower) {
                lower_bound++;
            }
            DECREF(low_found);
        }
    }

    return lower_bound;
}
uint32_t
SortFieldWriter_Refill_IMP(SortFieldWriter *self) {
    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
    if (!ivars->sort_cache) { return 0; }

    // Sanity check, then reset the buffer and prepare to start loading items.
    uint32_t buf_count = SortFieldWriter_Buffer_Count(self);
    if (buf_count) {
        THROW(ERR, "Refill called but buffer contains %u32 items",
              buf_count);
    }
    SortFieldWriter_Clear_Buffer(self);
    Counter_Reset(ivars->counter);
    S_lazy_init_sorted_ids(self);

    const int32_t    null_ord   = ivars->null_ord;
    I32Array *const  doc_map    = ivars->doc_map;
    SortCache *const sort_cache = ivars->sort_cache;

    uint32_t count = 0;
    while (ivars->run_tick <= ivars->run_max
           && Counter_Get_Value(ivars->counter) < ivars->mem_thresh
          ) {
        int32_t raw_doc_id = ivars->sorted_ids[ivars->run_tick];
        int32_t ord = SortCache_Ordinal(sort_cache, raw_doc_id);
        if (ord != null_ord) {
            int32_t remapped = doc_map
                               ? I32Arr_Get(doc_map, raw_doc_id)
                               : raw_doc_id;
            if (remapped) {
                Obj *val = SortCache_Value(sort_cache, ord);
                SortFieldWriter_Add(self, remapped, val);
                count++;
                DECREF(val);
            }
        }
        ivars->run_tick++;
    }

    if (ivars->run_tick > ivars->run_max) {
        DECREF(ivars->sort_cache);
        ivars->sort_cache = NULL;
        FREEMEM(ivars->sorted_ids);
        ivars->sorted_ids = NULL;
    }

    return count;
}
Exemplo n.º 4
0
i32_t
SortCache_find(SortCache *self, Obj *term)
{
    FieldType *const type = self->type;
    i32_t          lo     = 0;
    i32_t          hi     = self->num_uniq - 1;
    i32_t          result = -100;
    ZombieCharBuf  value  = ZCB_BLANK;

    if ( term != NULL && !OBJ_IS_A(term, CHARBUF)) {
        THROW("term is a %o, and not comparable to a %o",
            Obj_Get_Class_Name(term), CHARBUF.name);
    }

    /* Binary search. */
    while (hi >= lo) {
        const i32_t mid = lo + ((hi - lo) / 2);
        ViewCharBuf *val = SortCache_Value(self, mid, (ViewCharBuf*)&value);
        i64_t comparison = FType_Compare_Values(type, term, (Obj*)val);
        if (comparison < 0) {
            hi = mid - 1;
        }
        else if (comparison > 0) {
            lo = mid + 1;
        }
        else {
            result = mid;
            break;
        }
    }

    if (hi < 0) { 
        /* Target is "less than" the first cache entry. */
        return -1;
    }
    else if (result == -100) {
        /* If result is still -100, it wasn't set. */
        return hi;
    }
    else {
        return result;
    }
}
Exemplo n.º 5
0
int32_t
SortCache_Find_IMP(SortCache *self, Obj *term) {
    SortCacheIVARS *const ivars = SortCache_IVARS(self);
    FieldType *const type   = ivars->type;
    int32_t          lo     = 0;
    int32_t          hi     = ivars->cardinality - 1;
    int32_t          result = -100;

    // Binary search.
    while (hi >= lo) {
        const int32_t mid = lo + ((hi - lo) / 2);
        Obj *val = SortCache_Value(self, mid);
        int32_t comparison = FType_null_back_compare_values(type, term, val);
        DECREF(val);
        if (comparison < 0) {
            hi = mid - 1;
        }
        else if (comparison > 0) {
            lo = mid + 1;
        }
        else {
            result = mid;
            break;
        }
    }

    if (hi < 0) {
        // Target is "less than" the first cache entry.
        return -1;
    }
    else if (result == -100) {
        // If result is still -100, it wasn't set.
        return hi;
    }
    else {
        return result;
    }
}
Exemplo n.º 6
0
void
SortColl_collect(SortCollector *self, int32_t doc_id) {
    SortCollectorIVARS *const ivars = SortColl_IVARS(self);

    // Add to the total number of hits.
    ivars->total_hits++;

    // Collect this hit if it's competitive.
    if (SI_competitive(ivars, doc_id)) {
        MatchDoc *const match_doc = ivars->bumped;
        MatchDocIVARS *const match_doc_ivars = MatchDoc_IVARS(match_doc);
        match_doc_ivars->doc_id = doc_id + ivars->base;

        if (ivars->need_score && match_doc_ivars->score == F32_NEGINF) {
            match_doc_ivars->score = Matcher_Score(ivars->matcher);
        }

        // Fetch values so that cross-segment sorting can work.
        if (ivars->need_values) {
            VArray *values = match_doc_ivars->values;

            for (uint32_t i = 0, max = ivars->num_rules; i < max; i++) {
                SortCache *cache   = ivars->sort_caches[i];
                Obj       *old_val = (Obj*)VA_Delete(values, i);
                if (cache) {
                    int32_t ord = SortCache_Ordinal(cache, doc_id);
                    Obj *blank = old_val
                                 ? old_val
                                 : SortCache_Make_Blank(cache);
                    Obj *val = SortCache_Value(cache, ord, blank);
                    if (val) { VA_Store(values, i, (Obj*)val); }
                    else     { DECREF(blank); }
                }
            }
        }

        // Insert the new MatchDoc.
        ivars->bumped = (MatchDoc*)HitQ_Jostle(ivars->hit_q, (Obj*)match_doc);

        if (ivars->bumped) {
            if (ivars->bumped == match_doc) {
                /* The queue is full, and we have established a threshold for
                 * this segment as to what sort of document is definitely not
                 * acceptable.  Turn off AUTO_ACCEPT and start actually
                 * testing whether hits are competitive. */
                ivars->bubble_score  = match_doc_ivars->score;
                ivars->bubble_doc    = doc_id;
                ivars->actions       = ivars->derived_actions;
            }

            // Recycle.
            MatchDoc_IVARS(ivars->bumped)->score = ivars->need_score
                                                   ? F32_NEGINF
                                                   : F32_NAN;
        }
        else {
            // The queue isn't full yet, so create a fresh MatchDoc.
            VArray *values = ivars->need_values
                             ? VA_new(ivars->num_rules)
                             : NULL;
            float fake_score = ivars->need_score ? F32_NEGINF : F32_NAN;
            ivars->bumped = MatchDoc_new(INT32_MAX, fake_score, values);
            DECREF(values);
        }

    }
}