static const char *
_upper_bound(_pd_cmp cmp, const char *prefix, const char *start, const char *end)
{
    if (start == end)
        return start;

    const char *middle = start + (end - start)/2;
    while (middle > start && middle[-1] != '\n') middle--;

    const char *next = _nextline(middle);

    int c = (*cmp)(prefix, middle);
    if (c == 0)
        return _upper_bound(cmp, prefix, next, end);

    /*
     * Check that middle is not a last line. Without this check we'd go into
     * infinite loop. To avoid this situation either terminate search or call
     * itself without last line.
     */
    if (next == end) {
        const char* prevline = middle - 1; /* skip \n on previous line */
        while (prevline > start && prevline[-1] != '\n') prevline--;

        int c = (*cmp)(prefix, prevline);
        if (c == 0)
            return middle;

        return _upper_bound(cmp, prefix, start, middle);
    }

    return _upper_bound(cmp, prefix, start, next);
}
static _pd_interval
_find_entry(_pd_cmp cmp, const char *prefix, const char *start, const char *end)
{
    _pd_interval res = {};

    while (start < end) {
        const char *middle = start + (end - start)/2;

        /* looking for the start of line */
        while (middle > start && middle[-1] != '\n') middle--;

        const char *next = _nextline(middle);

        int c = (*cmp)(prefix, middle);
        if (c == 0) {
            res.lower = _lower_bound(cmp, prefix, start, next);
            res.upper = _upper_bound(cmp, prefix, next, end);
            break;
        }

        if (c > 0) {
            start = next;
        } else {
            end = middle;
        }
    }

    return res;
}
Esempio n. 3
0
BaseIndex::Iterator BaseIndex::upper_bound(const std::vector<AllTypeVariant>& values) const {
  DebugAssert((_get_indexed_segments().size() >= values.size()),
              "BaseIndex: The number of queried segments has to be less or equal to the number of indexed segments.");

  return _upper_bound(values);
}