mirror of https://gitee.com/bigwinds/arangodb
improve binary search a bit, improve string comparisons (#10069)
This commit is contained in:
parent
a2e0fc643b
commit
ca3c742652
|
@ -114,7 +114,7 @@ int64_t Slice::getSmallIntUnchecked() const noexcept {
|
||||||
// translates an integer key into a string, without checks
|
// translates an integer key into a string, without checks
|
||||||
Slice Slice::translateUnchecked() const {
|
Slice Slice::translateUnchecked() const {
|
||||||
uint8_t const* result = Options::Defaults.attributeTranslator->translate(getUIntUnchecked());
|
uint8_t const* result = Options::Defaults.attributeTranslator->translate(getUIntUnchecked());
|
||||||
if (result != nullptr) {
|
if (VELOCYPACK_LIKELY(result != nullptr)) {
|
||||||
return Slice(result);
|
return Slice(result);
|
||||||
}
|
}
|
||||||
return Slice();
|
return Slice();
|
||||||
|
@ -384,9 +384,7 @@ int Slice::compareString(StringRef const& value) const {
|
||||||
int res = memcmp(k, value.data(), compareLength);
|
int res = memcmp(k, value.data(), compareLength);
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (keyLength != length) {
|
return static_cast<int>(keyLength - length);
|
||||||
return (keyLength > length) ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -400,9 +398,7 @@ int Slice::compareStringUnchecked(StringRef const& value) const noexcept {
|
||||||
int res = memcmp(k, value.data(), compareLength);
|
int res = memcmp(k, value.data(), compareLength);
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (keyLength != length) {
|
return static_cast<int>(keyLength - length);
|
||||||
return (keyLength > length) ? 1 : -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -598,49 +594,42 @@ Slice Slice::searchObjectKeyBinary(StringRef const& attribute,
|
||||||
bool const useTranslator = (Options::Defaults.attributeTranslator != nullptr);
|
bool const useTranslator = (Options::Defaults.attributeTranslator != nullptr);
|
||||||
VELOCYPACK_ASSERT(n > 0);
|
VELOCYPACK_ASSERT(n > 0);
|
||||||
|
|
||||||
ValueLength l = 0;
|
int64_t l = 0;
|
||||||
ValueLength r = n - 1;
|
int64_t r = static_cast<int64_t>(n) - 1;
|
||||||
ValueLength index = r / 2;
|
int64_t index = r / 2;
|
||||||
|
|
||||||
while (true) {
|
do {
|
||||||
ValueLength offset = ieBase + index * offsetSize;
|
ValueLength offset = ieBase + index * offsetSize;
|
||||||
Slice key(_start + readIntegerFixed<ValueLength, offsetSize>(_start + offset));
|
Slice key(_start + readIntegerFixed<ValueLength, offsetSize>(_start + offset));
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
if (key.isString()) {
|
if (key.isString()) {
|
||||||
res = key.compareStringUnchecked(attribute.data(), attribute.size());
|
res = key.compareStringUnchecked(attribute.data(), attribute.size());
|
||||||
} else if (key.isSmallInt() || key.isUInt()) {
|
} else {
|
||||||
|
VELOCYPACK_ASSERT(key.isSmallInt() || key.isUInt());
|
||||||
// translate key
|
// translate key
|
||||||
if (VELOCYPACK_UNLIKELY(!useTranslator)) {
|
if (VELOCYPACK_UNLIKELY(!useTranslator)) {
|
||||||
// no attribute translator
|
// no attribute translator
|
||||||
throw Exception(Exception::NeedAttributeTranslator);
|
throw Exception(Exception::NeedAttributeTranslator);
|
||||||
}
|
}
|
||||||
res = key.translateUnchecked().compareString(attribute);
|
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 (res > 0) {
|
||||||
if (index == 0) {
|
|
||||||
return Slice();
|
|
||||||
}
|
|
||||||
r = index - 1;
|
r = index - 1;
|
||||||
|
} else if (res == 0) {
|
||||||
|
// found. now return a Slice pointing at the value
|
||||||
|
return Slice(key.start() + key.byteSize());
|
||||||
} else {
|
} else {
|
||||||
l = index + 1;
|
l = index + 1;
|
||||||
}
|
}
|
||||||
if (r < l) {
|
|
||||||
return Slice();
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine new midpoint
|
// determine new midpoint
|
||||||
index = l + ((r - l) / 2);
|
index = l + ((r - l) / 2);
|
||||||
}
|
} while (r >= l);
|
||||||
|
|
||||||
|
// not found
|
||||||
|
return Slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
// template instanciations for searchObjectKeyBinary
|
// template instanciations for searchObjectKeyBinary
|
||||||
|
|
Loading…
Reference in New Issue