1
0
Fork 0

improve binary search a bit, improve string comparisons (#10069)

This commit is contained in:
Jan 2019-09-24 18:20:34 +02:00 committed by GitHub
parent a2e0fc643b
commit ca3c742652
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 27 deletions

View File

@ -114,7 +114,7 @@ int64_t Slice::getSmallIntUnchecked() const noexcept {
// translates an integer key into a string, without checks
Slice Slice::translateUnchecked() const {
uint8_t const* result = Options::Defaults.attributeTranslator->translate(getUIntUnchecked());
if (result != nullptr) {
if (VELOCYPACK_LIKELY(result != nullptr)) {
return Slice(result);
}
return Slice();
@ -384,9 +384,7 @@ int Slice::compareString(StringRef const& value) const {
int res = memcmp(k, value.data(), compareLength);
if (res == 0) {
if (keyLength != length) {
return (keyLength > length) ? 1 : -1;
}
return static_cast<int>(keyLength - length);
}
return res;
}
@ -400,9 +398,7 @@ int Slice::compareStringUnchecked(StringRef const& value) const noexcept {
int res = memcmp(k, value.data(), compareLength);
if (res == 0) {
if (keyLength != length) {
return (keyLength > length) ? 1 : -1;
}
return static_cast<int>(keyLength - length);
}
return res;
}
@ -598,49 +594,42 @@ Slice Slice::searchObjectKeyBinary(StringRef const& attribute,
bool const useTranslator = (Options::Defaults.attributeTranslator != nullptr);
VELOCYPACK_ASSERT(n > 0);
ValueLength l = 0;
ValueLength r = n - 1;
ValueLength index = r / 2;
int64_t l = 0;
int64_t r = static_cast<int64_t>(n) - 1;
int64_t index = r / 2;
while (true) {
do {
ValueLength offset = ieBase + index * offsetSize;
Slice key(_start + readIntegerFixed<ValueLength, offsetSize>(_start + offset));
int res;
if (key.isString()) {
res = key.compareStringUnchecked(attribute.data(), attribute.size());
} else if (key.isSmallInt() || key.isUInt()) {
} else {
VELOCYPACK_ASSERT(key.isSmallInt() || key.isUInt());
// translate key
if (VELOCYPACK_UNLIKELY(!useTranslator)) {
// no attribute translator
throw Exception(Exception::NeedAttributeTranslator);
}
res = key.translateUnchecked().compareString(attribute);
} else {
// invalid key
return Slice();
}
if (res == 0) {
// found. now return a Slice pointing at the value
return Slice(key.start() + key.byteSize());
}
if (res > 0) {
if (index == 0) {
return Slice();
}
r = index - 1;
} else if (res == 0) {
// found. now return a Slice pointing at the value
return Slice(key.start() + key.byteSize());
} else {
l = index + 1;
}
if (r < l) {
return Slice();
}
// determine new midpoint
index = l + ((r - l) / 2);
}
} while (r >= l);
// not found
return Slice();
}
// template instanciations for searchObjectKeyBinary