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