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;
}
static const char *
_lower_bound(_pd_cmp cmp, const char *prefix, const char *start, const char *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);

    /* If we've got a single line, then we've found it */
    if (middle == start && next == end)
        return middle;

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

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

         /*
          * Now check if prevline matches prefix. If it is, then drop last line,
          * else we've found lower bound
          */
         int c = (*cmp)(prefix, prevline);
         if (c > 0)
             return middle;

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

    return _lower_bound(cmp, prefix, start, next);
}
Esempio n. 3
0
BaseIndex::Iterator BaseIndex::lower_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 _lower_bound(values);
}