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); }
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); }