mirror of https://gitee.com/bigwinds/arangodb
Feature/velocypack update (#6678)
This commit is contained in:
parent
883a2baace
commit
c06f2d77da
|
@ -229,6 +229,8 @@ class Buffer {
|
|||
return append(value.data(), value.size());
|
||||
}
|
||||
|
||||
// reserves len *extra* bytes of storage space
|
||||
// this should probably be renamed to reserveExtra
|
||||
inline void reserve(ValueLength len) {
|
||||
VELOCYPACK_ASSERT(_size <= _capacity);
|
||||
|
||||
|
@ -255,8 +257,8 @@ class Buffer {
|
|||
|
||||
// need reallocation
|
||||
ValueLength newLen = _size + len;
|
||||
static constexpr double growthFactor = 1.25;
|
||||
if (_size > 0 && newLen < growthFactor * _size) {
|
||||
constexpr double growthFactor = 1.25;
|
||||
if (newLen < growthFactor * _size) {
|
||||
// ensure the buffer grows sensibly and not by 1 byte only
|
||||
newLen = static_cast<ValueLength>(growthFactor * _size);
|
||||
}
|
||||
|
|
|
@ -114,15 +114,6 @@ class Builder {
|
|||
bool _keyWritten; // indicates that in the current object the key
|
||||
// has been written but the value not yet
|
||||
|
||||
// Sort the indices by attribute name:
|
||||
static void doActualSort(std::vector<SortEntry>& entries);
|
||||
|
||||
// Find the actual bytes of the attribute name of the VPack value
|
||||
// at position base, also determine the length len of the attribute.
|
||||
// This takes into account the different possibilities for the format
|
||||
// of attribute names:
|
||||
static uint8_t const* findAttrName(uint8_t const* base, uint64_t& len);
|
||||
|
||||
void sortObjectIndexShort(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets) const;
|
||||
|
||||
|
@ -130,7 +121,13 @@ class Builder {
|
|||
std::vector<ValueLength>& offsets);
|
||||
|
||||
void sortObjectIndex(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets);
|
||||
std::vector<ValueLength>& offsets) {
|
||||
if (offsets.size() > 32) {
|
||||
sortObjectIndexLong(objBase, offsets);
|
||||
} else {
|
||||
sortObjectIndexShort(objBase, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Options const* options;
|
||||
|
@ -573,7 +570,7 @@ class Builder {
|
|||
private:
|
||||
inline void checkKeyIsString(bool isString) {
|
||||
if (!_stack.empty()) {
|
||||
ValueLength const tos = _stack.back();
|
||||
ValueLength const& tos = _stack.back();
|
||||
if (_start[tos] == 0x0b || _start[tos] == 0x14) {
|
||||
if (!_keyWritten && !isString) {
|
||||
throw Exception(Exception::BuilderKeyMustBeString);
|
||||
|
@ -615,7 +612,7 @@ class Builder {
|
|||
uint8_t* addInternal(std::string const& attrName, T const& sub) {
|
||||
bool haveReported = false;
|
||||
if (!_stack.empty()) {
|
||||
ValueLength& tos = _stack.back();
|
||||
ValueLength const& tos = _stack.back();
|
||||
if (_start[tos] != 0x0b && _start[tos] != 0x14) {
|
||||
throw Exception(Exception::BuilderNeedOpenObject);
|
||||
}
|
||||
|
|
|
@ -39,29 +39,10 @@
|
|||
#include "velocypack/velocypack-common.h"
|
||||
#include "velocypack/Exception.h"
|
||||
#include "velocypack/Options.h"
|
||||
#include "velocypack/StringRef.h"
|
||||
#include "velocypack/Value.h"
|
||||
#include "velocypack/ValueType.h"
|
||||
|
||||
#ifndef VELOCYPACK_XXHASH
|
||||
#ifndef VELOCYPACK_FASTHASH
|
||||
#define VELOCYPACK_XXHASH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VELOCYPACK_XXHASH
|
||||
// forward for XXH64 function declared elsewhere
|
||||
extern "C" unsigned long long XXH64(void const*, size_t, unsigned long long);
|
||||
|
||||
#define VELOCYPACK_HASH(mem, size, seed) XXH64(mem, size, seed)
|
||||
#endif
|
||||
|
||||
#ifdef VELOCYPACK_FASTHASH
|
||||
// forward for fasthash64 function declared elsewhere
|
||||
uint64_t fasthash64(void const*, size_t, uint64_t);
|
||||
|
||||
#define VELOCYPACK_HASH(mem, size, seed) fasthash64(mem, size, seed)
|
||||
#endif
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
|
||||
|
@ -185,6 +166,13 @@ class Slice {
|
|||
return VELOCYPACK_HASH(start(), size, seed);
|
||||
}
|
||||
|
||||
// hashes the binary representation of a value, not using precalculated hash values
|
||||
// this is mainly here for testing purposes
|
||||
inline uint64_t hashSlow(uint64_t seed = defaultSeed) const {
|
||||
size_t const size = checkOverflow(byteSize());
|
||||
return VELOCYPACK_HASH(start(), size, seed);
|
||||
}
|
||||
|
||||
// hashes the value, normalizing different representations of
|
||||
// arrays, objects and numbers. this function may produce different
|
||||
// hash values than the binary hash() function
|
||||
|
@ -447,7 +435,8 @@ class Slice {
|
|||
|
||||
// look for the specified attribute path inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(std::vector<std::string> const& attributes,
|
||||
template<typename T>
|
||||
Slice get(std::vector<T> const& attributes,
|
||||
bool resolveExternals = false) const {
|
||||
size_t const n = attributes.size();
|
||||
if (n == 0) {
|
||||
|
@ -476,48 +465,47 @@ class Slice {
|
|||
return last;
|
||||
}
|
||||
|
||||
// look for the specified attribute path inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(std::vector<char const*> const& attributes) const {
|
||||
size_t const n = attributes.size();
|
||||
if (n == 0) {
|
||||
throw Exception(Exception::InvalidAttributePath);
|
||||
}
|
||||
|
||||
// use ourselves as the starting point
|
||||
Slice last = Slice(start());
|
||||
for (size_t i = 0; i < attributes.size(); ++i) {
|
||||
// fetch subattribute
|
||||
last = last.get(attributes[i]);
|
||||
|
||||
// abort as early as possible
|
||||
if (last.isNone() || (i + 1 < n && !last.isObject())) {
|
||||
return Slice();
|
||||
}
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
// look for the specified attribute inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(std::string const& attribute) const;
|
||||
Slice get(StringRef const& attribute) const;
|
||||
|
||||
Slice get(std::string const& attribute) const {
|
||||
return get(StringRef(attribute.data(), attribute.size()));
|
||||
}
|
||||
|
||||
// look for the specified attribute inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice get(char const* attribute) const {
|
||||
return get(std::string(attribute));
|
||||
return get(StringRef(attribute));
|
||||
}
|
||||
|
||||
Slice operator[](std::string const& attribute) const {
|
||||
Slice get(char const* attribute, size_t length) const {
|
||||
return get(StringRef(attribute, length));
|
||||
}
|
||||
|
||||
Slice operator[](StringRef const& attribute) const {
|
||||
return get(attribute);
|
||||
}
|
||||
|
||||
Slice operator[](std::string const& attribute) const {
|
||||
return get(attribute.data(), attribute.size());
|
||||
}
|
||||
|
||||
// whether or not an Object has a specific key
|
||||
bool hasKey(std::string const& attribute) const {
|
||||
bool hasKey(StringRef const& attribute) const {
|
||||
return !get(attribute).isNone();
|
||||
}
|
||||
|
||||
bool hasKey(std::string const& attribute) const {
|
||||
return hasKey(StringRef(attribute));
|
||||
}
|
||||
|
||||
bool hasKey(char const* attribute) const {
|
||||
return hasKey(StringRef(attribute));
|
||||
}
|
||||
|
||||
bool hasKey(char const* attribute, size_t length) const {
|
||||
return hasKey(StringRef(attribute, length));
|
||||
}
|
||||
|
||||
// whether or not an Object has a specific sub-key
|
||||
bool hasKey(std::vector<std::string> const& attributes) const {
|
||||
return !get(attributes).isNone();
|
||||
|
@ -706,6 +694,25 @@ class Slice {
|
|||
throw Exception(Exception::InvalidValueType, "Expecting type String");
|
||||
}
|
||||
|
||||
// return a copy of the value for a String object
|
||||
StringRef stringRef() const {
|
||||
uint8_t h = head();
|
||||
if (h >= 0x40 && h <= 0xbe) {
|
||||
// short UTF-8 String
|
||||
ValueLength length = h - 0x40;
|
||||
return StringRef(reinterpret_cast<char const*>(_start + 1),
|
||||
static_cast<size_t>(length));
|
||||
}
|
||||
|
||||
if (h == 0xbf) {
|
||||
ValueLength length = readIntegerFixed<ValueLength, 8>(_start + 1);
|
||||
return StringRef(reinterpret_cast<char const*>(_start + 1 + 8),
|
||||
checkOverflow(length));
|
||||
}
|
||||
|
||||
throw Exception(Exception::InvalidValueType, "Expecting type String");
|
||||
}
|
||||
|
||||
// return the value for a Binary object
|
||||
uint8_t const* getBinary(ValueLength& length) const {
|
||||
if (!isBinary()) {
|
||||
|
@ -879,15 +886,37 @@ class Slice {
|
|||
|
||||
Slice makeKey() const;
|
||||
|
||||
int compareString(char const* value, size_t length) const;
|
||||
int compareStringUnchecked(char const* value, size_t length) const noexcept;
|
||||
int compareString(StringRef const& value) const;
|
||||
|
||||
inline int compareString(std::string const& attribute) const {
|
||||
return compareString(attribute.data(), attribute.size());
|
||||
inline int compareString(std::string const& value) const {
|
||||
return compareString(StringRef(value.data(), value.size()));
|
||||
}
|
||||
|
||||
bool isEqualString(std::string const& attribute) const;
|
||||
bool isEqualStringUnchecked(std::string const& attribute) const noexcept;
|
||||
int compareString(char const* value, size_t length) const {
|
||||
return compareString(StringRef(value, length));
|
||||
}
|
||||
|
||||
int compareStringUnchecked(StringRef const& value) const noexcept;
|
||||
|
||||
int compareStringUnchecked(std::string const& value) const noexcept {
|
||||
return compareStringUnchecked(StringRef(value.data(), value.size()));
|
||||
}
|
||||
|
||||
int compareStringUnchecked(char const* value, size_t length) const noexcept {
|
||||
return compareStringUnchecked(StringRef(value, length));
|
||||
}
|
||||
|
||||
bool isEqualString(StringRef const& attribute) const;
|
||||
|
||||
bool isEqualString(std::string const& attribute) const {
|
||||
return isEqualString(StringRef(attribute.data(), attribute.size()));
|
||||
}
|
||||
|
||||
bool isEqualStringUnchecked(StringRef const& attribute) const noexcept;
|
||||
|
||||
bool isEqualStringUnchecked(std::string const& attribute) const noexcept {
|
||||
return isEqualStringUnchecked(StringRef(attribute.data(), attribute.size()));
|
||||
}
|
||||
|
||||
// check if two Slices are equal on the binary level
|
||||
bool equals(Slice const& other) const {
|
||||
|
@ -944,7 +973,7 @@ class Slice {
|
|||
// translates an integer key into a string, without checks
|
||||
Slice translateUnchecked() const;
|
||||
|
||||
Slice getFromCompactObject(std::string const& attribute) const;
|
||||
Slice getFromCompactObject(StringRef const& attribute) const;
|
||||
|
||||
// extract the nth member from an Array
|
||||
Slice getNth(ValueLength index) const;
|
||||
|
@ -968,12 +997,12 @@ class Slice {
|
|||
}
|
||||
|
||||
// perform a linear search for the specified attribute inside an Object
|
||||
Slice searchObjectKeyLinear(std::string const& attribute, ValueLength ieBase,
|
||||
Slice searchObjectKeyLinear(StringRef const& attribute, ValueLength ieBase,
|
||||
ValueLength offsetSize, ValueLength n) const;
|
||||
|
||||
// perform a binary search for the specified attribute inside an Object
|
||||
template<ValueLength offsetSize>
|
||||
Slice searchObjectKeyBinary(std::string const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
Slice searchObjectKeyBinary(StringRef const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
|
||||
// assert that the slice is of a specific type
|
||||
// can be used for debugging and removed in production
|
||||
|
|
|
@ -29,12 +29,14 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "velocypack/velocypack-common.h"
|
||||
#include "velocypack/Slice.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
class Slice;
|
||||
|
||||
class StringRef {
|
||||
public:
|
||||
|
@ -44,19 +46,18 @@ class StringRef {
|
|||
/// @brief create a StringRef from an std::string
|
||||
explicit StringRef(std::string const& str) noexcept : StringRef(str.data(), str.size()) {}
|
||||
|
||||
/// @brief create a StringRef from a C string plus length
|
||||
constexpr StringRef(char const* data, size_t length) noexcept : _data(data), _length(length) {}
|
||||
|
||||
/// @brief create a StringRef from a null-terminated C string
|
||||
#if __cplusplus >= 201703
|
||||
constexpr explicit StringRef(char const* data) noexcept : StringRef(data, std::char_traits<char>::length(data)) {}
|
||||
#else
|
||||
explicit StringRef(char const* data) noexcept : StringRef(data, strlen(data)) {}
|
||||
#endif
|
||||
|
||||
/// @brief create a StringRef from a VPack slice (must be of type String)
|
||||
explicit StringRef(arangodb::velocypack::Slice const& slice) {
|
||||
VELOCYPACK_ASSERT(slice.isString());
|
||||
arangodb::velocypack::ValueLength l;
|
||||
_data = slice.getString(l);
|
||||
_length = l;
|
||||
}
|
||||
|
||||
/// @brief create a StringRef from a C string plus length
|
||||
StringRef(char const* data, size_t length) noexcept : _data(data), _length(length) {}
|
||||
explicit StringRef(arangodb::velocypack::Slice const& slice);
|
||||
|
||||
/// @brief create a StringRef from another StringRef
|
||||
StringRef(StringRef const& other) noexcept
|
||||
|
@ -95,12 +96,7 @@ class StringRef {
|
|||
}
|
||||
|
||||
/// @brief create a StringRef from a VPack slice of type String
|
||||
StringRef& operator=(arangodb::velocypack::Slice const& slice) {
|
||||
arangodb::velocypack::ValueLength l;
|
||||
_data = slice.getString(l);
|
||||
_length = l;
|
||||
return *this;
|
||||
}
|
||||
StringRef& operator=(arangodb::velocypack::Slice const& slice);
|
||||
|
||||
int compare(std::string const& other) const noexcept {
|
||||
int res = memcmp(_data, other.data(), (std::min)(_length, other.size()));
|
||||
|
@ -126,17 +122,17 @@ class StringRef {
|
|||
return (_length == 0);
|
||||
}
|
||||
|
||||
inline char const* begin() const {
|
||||
inline char const* begin() const noexcept {
|
||||
return _data;
|
||||
}
|
||||
|
||||
inline char const* end() const {
|
||||
inline char const* end() const noexcept {
|
||||
return _data + _length;
|
||||
}
|
||||
|
||||
inline char front() const { return _data[0]; }
|
||||
inline char front() const noexcept { return _data[0]; }
|
||||
|
||||
inline char back() const { return _data[_length - 1]; }
|
||||
inline char back() const noexcept { return _data[_length - 1]; }
|
||||
|
||||
inline char operator[](size_t index) const noexcept {
|
||||
return _data[index];
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <cstdint>
|
||||
// for size_t:
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(__GNUC__) || defined(__GNUG__)
|
||||
#define VELOCYPACK_LIKELY(v) __builtin_expect(!!(v), 1)
|
||||
|
@ -77,6 +78,26 @@
|
|||
#define VELOCYPACK_UNUSED /* unused */
|
||||
#endif
|
||||
|
||||
#ifndef VELOCYPACK_XXHASH
|
||||
#ifndef VELOCYPACK_FASTHASH
|
||||
#define VELOCYPACK_XXHASH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VELOCYPACK_XXHASH
|
||||
// forward for XXH64 function declared elsewhere
|
||||
extern "C" unsigned long long XXH64(void const*, size_t, unsigned long long);
|
||||
|
||||
#define VELOCYPACK_HASH(mem, size, seed) XXH64(mem, size, seed)
|
||||
#endif
|
||||
|
||||
#ifdef VELOCYPACK_FASTHASH
|
||||
// forward for fasthash64 function declared elsewhere
|
||||
uint64_t fasthash64(void const*, size_t, uint64_t);
|
||||
|
||||
#define VELOCYPACK_HASH(mem, size, seed) fasthash64(mem, size, seed)
|
||||
#endif
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
|
||||
|
@ -177,10 +198,12 @@ static inline int64_t toInt64(uint64_t v) noexcept {
|
|||
// specified length, starting at the specified byte offset
|
||||
template <typename T, ValueLength length>
|
||||
static inline T readIntegerFixed(uint8_t const* start) noexcept {
|
||||
static_assert(std::is_unsigned<T>::value, "result type must be unsigned");
|
||||
static_assert(length > 0, "length must be > 0");
|
||||
static_assert(length <= sizeof(T), "length must be <= sizeof(T)");
|
||||
uint64_t x = 8;
|
||||
uint8_t const* end = start + length;
|
||||
uint64_t value = static_cast<T>(*start++);
|
||||
T value = static_cast<T>(*start++);
|
||||
while (start < end) {
|
||||
value += static_cast<T>(*start++) << x;
|
||||
x += 8;
|
||||
|
@ -189,13 +212,15 @@ static inline T readIntegerFixed(uint8_t const* start) noexcept {
|
|||
}
|
||||
|
||||
// read an unsigned little endian integer value of the
|
||||
// specified length, starting at the specified byte offset
|
||||
// specified, non-0 length, starting at the specified byte offset
|
||||
template <typename T>
|
||||
static inline T readIntegerNonEmpty(uint8_t const* start, ValueLength length) noexcept {
|
||||
static_assert(std::is_unsigned<T>::value, "result type must be unsigned");
|
||||
VELOCYPACK_ASSERT(length > 0);
|
||||
VELOCYPACK_ASSERT(length <= sizeof(T));
|
||||
uint64_t x = 8;
|
||||
uint8_t const* end = start + length;
|
||||
uint64_t value = static_cast<T>(*start++);
|
||||
T value = static_cast<T>(*start++);
|
||||
while (start < end) {
|
||||
value += static_cast<T>(*start++) << x;
|
||||
x += 8;
|
||||
|
|
|
@ -35,40 +35,12 @@
|
|||
|
||||
using namespace arangodb::velocypack;
|
||||
|
||||
std::string Builder::toString() const {
|
||||
Options options;
|
||||
options.prettyPrint = true;
|
||||
|
||||
std::string buffer;
|
||||
StringSink sink(&buffer);
|
||||
Dumper::dump(slice(), &sink, &options);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string Builder::toJson() const {
|
||||
std::string buffer;
|
||||
StringSink sink(&buffer);
|
||||
Dumper::dump(slice(), &sink);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Builder::doActualSort(std::vector<SortEntry>& entries) {
|
||||
VELOCYPACK_ASSERT(entries.size() > 1);
|
||||
std::sort(entries.begin(), entries.end(),
|
||||
[](SortEntry const& a, SortEntry const& b) {
|
||||
// return true iff a < b:
|
||||
uint8_t const* pa = a.nameStart;
|
||||
uint64_t sizea = a.nameSize;
|
||||
uint8_t const* pb = b.nameStart;
|
||||
uint64_t sizeb = b.nameSize;
|
||||
size_t const compareLength = checkOverflow((std::min)(sizea, sizeb));
|
||||
int res = memcmp(pa, pb, compareLength);
|
||||
|
||||
return (res < 0 || (res == 0 && sizea < sizeb));
|
||||
});
|
||||
};
|
||||
|
||||
uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len) {
|
||||
namespace {
|
||||
// Find the actual bytes of the attribute name of the VPack value
|
||||
// at position base, also determine the length len of the attribute.
|
||||
// This takes into account the different possibilities for the format
|
||||
// of attribute names:
|
||||
static uint8_t const* findAttrName(uint8_t const* base, uint64_t& len) {
|
||||
uint8_t const b = *base;
|
||||
if (b >= 0x40 && b <= 0xbe) {
|
||||
// short UTF-8 string
|
||||
|
@ -86,18 +58,20 @@ uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len) {
|
|||
}
|
||||
|
||||
// translate attribute name
|
||||
return findAttrName(Slice(base).makeKey().start(), len);
|
||||
return findAttrName(arangodb::velocypack::Slice(base).makeKey().start(), len);
|
||||
}
|
||||
|
||||
void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets) const {
|
||||
std::sort(offsets.begin(), offsets.end(), [&objBase](ValueLength a, ValueLength b) -> bool {
|
||||
struct ObjectIndexSorterShort {
|
||||
explicit ObjectIndexSorterShort(uint8_t const* objBase) : objBase(objBase) {}
|
||||
|
||||
bool operator()(arangodb::velocypack::ValueLength const& a,
|
||||
arangodb::velocypack::ValueLength const& b) const noexcept {
|
||||
uint8_t const* aa = objBase + a;
|
||||
uint8_t const* bb = objBase + b;
|
||||
if (*aa >= 0x40 && *aa <= 0xbe && *bb >= 0x40 && *bb <= 0xbe) {
|
||||
// The fast path, short strings:
|
||||
uint8_t m = (std::min)(*aa - 0x40, *bb - 0x40);
|
||||
int c = memcmp(aa + 1, bb + 1, checkOverflow(m));
|
||||
int c = memcmp(aa + 1, bb + 1, arangodb::velocypack::checkOverflow(m));
|
||||
return (c < 0 || (c == 0 && *aa < *bb));
|
||||
} else {
|
||||
uint64_t lena;
|
||||
|
@ -105,10 +79,52 @@ void Builder::sortObjectIndexShort(uint8_t* objBase,
|
|||
aa = findAttrName(aa, lena);
|
||||
bb = findAttrName(bb, lenb);
|
||||
uint64_t m = (std::min)(lena, lenb);
|
||||
int c = memcmp(aa, bb, checkOverflow(m));
|
||||
int c = memcmp(aa, bb, arangodb::velocypack::checkOverflow(m));
|
||||
return (c < 0 || (c == 0 && lena < lenb));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uint8_t const* objBase;
|
||||
};
|
||||
|
||||
struct ObjectIndexSorterLong {
|
||||
bool operator()(arangodb::velocypack::Builder::SortEntry const& a,
|
||||
arangodb::velocypack::Builder::SortEntry const& b) const noexcept {
|
||||
// return true iff a < b:
|
||||
uint8_t const* pa = a.nameStart;
|
||||
uint64_t sizea = a.nameSize;
|
||||
uint8_t const* pb = b.nameStart;
|
||||
uint64_t sizeb = b.nameSize;
|
||||
size_t const compareLength = arangodb::velocypack::checkOverflow((std::min)(sizea, sizeb));
|
||||
int res = memcmp(pa, pb, compareLength);
|
||||
|
||||
return (res < 0 || (res == 0 && sizea < sizeb));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
std::string Builder::toString() const {
|
||||
Options options;
|
||||
options.prettyPrint = true;
|
||||
|
||||
std::string buffer;
|
||||
StringSink sink(&buffer);
|
||||
Dumper::dump(slice(), &sink, &options);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::string Builder::toJson() const {
|
||||
std::string buffer;
|
||||
StringSink sink(&buffer);
|
||||
Dumper::dump(slice(), &sink);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets) const {
|
||||
std::sort(offsets.begin(), offsets.end(), ::ObjectIndexSorterShort(objBase));
|
||||
}
|
||||
|
||||
void Builder::sortObjectIndexLong(uint8_t* objBase,
|
||||
|
@ -116,15 +132,16 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
|||
_sortEntries.clear();
|
||||
|
||||
size_t const n = offsets.size();
|
||||
VELOCYPACK_ASSERT(n > 1);
|
||||
_sortEntries.reserve(n);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
SortEntry e;
|
||||
e.offset = offsets[i];
|
||||
e.nameStart = findAttrName(objBase + e.offset, e.nameSize);
|
||||
e.nameStart = ::findAttrName(objBase + e.offset, e.nameSize);
|
||||
_sortEntries.push_back(e);
|
||||
}
|
||||
VELOCYPACK_ASSERT(_sortEntries.size() == n);
|
||||
doActualSort(_sortEntries);
|
||||
std::sort(_sortEntries.begin(), _sortEntries.end(), ::ObjectIndexSorterLong());
|
||||
|
||||
// copy back the sorted offsets
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
|
@ -133,15 +150,6 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
|||
_sortEntries.clear();
|
||||
}
|
||||
|
||||
void Builder::sortObjectIndex(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets) {
|
||||
if (offsets.size() > 32) {
|
||||
sortObjectIndexLong(objBase, offsets);
|
||||
} else {
|
||||
sortObjectIndexShort(objBase, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
void Builder::removeLast() {
|
||||
if (_stack.empty()) {
|
||||
throw Exception(Exception::BuilderNeedOpenCompound);
|
||||
|
|
|
@ -746,7 +746,7 @@ uint64_t Slice::normalizedHash(uint64_t seed) const {
|
|||
|
||||
// look for the specified attribute inside an Object
|
||||
// returns a Slice(ValueType::None) if not found
|
||||
Slice Slice::get(std::string const& attribute) const {
|
||||
Slice Slice::get(StringRef const& attribute) const {
|
||||
if (VELOCYPACK_UNLIKELY(!isObject())) {
|
||||
throw Exception(Exception::InvalidValueType, "Expecting Object");
|
||||
}
|
||||
|
@ -934,12 +934,13 @@ int64_t Slice::getSmallInt() const {
|
|||
throw Exception(Exception::InvalidValueType, "Expecting type SmallInt");
|
||||
}
|
||||
|
||||
int Slice::compareString(char const* value, size_t length) const {
|
||||
int Slice::compareString(StringRef const& value) const {
|
||||
size_t const length = value.size();
|
||||
ValueLength keyLength;
|
||||
char const* k = getString(keyLength);
|
||||
size_t const compareLength =
|
||||
(std::min)(static_cast<size_t>(keyLength), length);
|
||||
int res = memcmp(k, value, compareLength);
|
||||
int res = memcmp(k, value.data(), compareLength);
|
||||
|
||||
if (res == 0) {
|
||||
if (keyLength != length) {
|
||||
|
@ -949,12 +950,13 @@ int Slice::compareString(char const* value, size_t length) const {
|
|||
return res;
|
||||
}
|
||||
|
||||
int Slice::compareStringUnchecked(char const* value, size_t length) const noexcept {
|
||||
int Slice::compareStringUnchecked(StringRef const& value) const noexcept {
|
||||
size_t const length = value.size();
|
||||
ValueLength keyLength;
|
||||
char const* k = getStringUnchecked(keyLength);
|
||||
size_t const compareLength =
|
||||
(std::min)(static_cast<size_t>(keyLength), length);
|
||||
int res = memcmp(k, value, compareLength);
|
||||
int res = memcmp(k, value.data(), compareLength);
|
||||
|
||||
if (res == 0) {
|
||||
if (keyLength != length) {
|
||||
|
@ -964,7 +966,7 @@ int Slice::compareStringUnchecked(char const* value, size_t length) const noexce
|
|||
return res;
|
||||
}
|
||||
|
||||
bool Slice::isEqualString(std::string const& attribute) const {
|
||||
bool Slice::isEqualString(StringRef const& attribute) const {
|
||||
ValueLength keyLength;
|
||||
char const* k = getString(keyLength);
|
||||
if (static_cast<size_t>(keyLength) != attribute.size()) {
|
||||
|
@ -973,7 +975,7 @@ bool Slice::isEqualString(std::string const& attribute) const {
|
|||
return (memcmp(k, attribute.data(), attribute.size()) == 0);
|
||||
}
|
||||
|
||||
bool Slice::isEqualStringUnchecked(std::string const& attribute) const noexcept {
|
||||
bool Slice::isEqualStringUnchecked(StringRef const& attribute) const noexcept {
|
||||
ValueLength keyLength;
|
||||
char const* k = getStringUnchecked(keyLength);
|
||||
if (static_cast<size_t>(keyLength) != attribute.size()) {
|
||||
|
@ -982,7 +984,7 @@ bool Slice::isEqualStringUnchecked(std::string const& attribute) const noexcept
|
|||
return (memcmp(k, attribute.data(), attribute.size()) == 0);
|
||||
}
|
||||
|
||||
Slice Slice::getFromCompactObject(std::string const& attribute) const {
|
||||
Slice Slice::getFromCompactObject(StringRef const& attribute) const {
|
||||
ObjectIterator it(*this);
|
||||
while (it.valid()) {
|
||||
Slice key = it.key(false);
|
||||
|
@ -1116,7 +1118,7 @@ ValueLength Slice::getNthOffsetFromCompact(ValueLength index) const {
|
|||
}
|
||||
|
||||
// perform a linear search for the specified attribute inside an Object
|
||||
Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
||||
Slice Slice::searchObjectKeyLinear(StringRef const& attribute,
|
||||
ValueLength ieBase, ValueLength offsetSize,
|
||||
ValueLength n) const {
|
||||
bool const useTranslator = (Options::Defaults.attributeTranslator != nullptr);
|
||||
|
@ -1153,7 +1155,7 @@ Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
|||
|
||||
// perform a binary search for the specified attribute inside an Object
|
||||
template<ValueLength offsetSize>
|
||||
Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
||||
Slice Slice::searchObjectKeyBinary(StringRef const& attribute,
|
||||
ValueLength ieBase,
|
||||
ValueLength n) const {
|
||||
bool const useTranslator = (Options::Defaults.attributeTranslator != nullptr);
|
||||
|
@ -1205,10 +1207,10 @@ Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
|||
}
|
||||
|
||||
// template instanciations for searchObjectKeyBinary
|
||||
template Slice Slice::searchObjectKeyBinary<1>(std::string const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<2>(std::string const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<4>(std::string const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<8>(std::string const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<1>(StringRef const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<2>(StringRef const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<4>(StringRef const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
template Slice Slice::searchObjectKeyBinary<8>(StringRef const& attribute, ValueLength ieBase, ValueLength n) const;
|
||||
|
||||
SliceScope::SliceScope() : _allocations() {}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Library to build up VPack documents.
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2015 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Max Neunhoeffer
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2015, ArangoDB GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "velocypack/StringRef.h"
|
||||
#include "velocypack/Slice.h"
|
||||
|
||||
using namespace arangodb::velocypack;
|
||||
|
||||
StringRef::StringRef(arangodb::velocypack::Slice const& slice) {
|
||||
VELOCYPACK_ASSERT(slice.isString());
|
||||
arangodb::velocypack::ValueLength l;
|
||||
_data = slice.getString(l);
|
||||
_length = l;
|
||||
}
|
||||
|
||||
/// @brief create a StringRef from a VPack slice of type String
|
||||
StringRef& StringRef::operator=(arangodb::velocypack::Slice const& slice) {
|
||||
arangodb::velocypack::ValueLength l;
|
||||
_data = slice.getString(l);
|
||||
_length = l;
|
||||
return *this;
|
||||
}
|
|
@ -274,7 +274,7 @@ std::string ActiveFailoverJob::findBestFollower() {
|
|||
if (!resp.isArray() || resp.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
VPackSlice obj = resp.at(0).get({ Job::agencyPrefix, "AsyncReplication"});
|
||||
VPackSlice obj = resp.at(0).get<std::string>({ Job::agencyPrefix, std::string("AsyncReplication") });
|
||||
for (VPackObjectIterator::ObjectPair pair : VPackObjectIterator(obj)) {
|
||||
std::string srvUUID = pair.key.copyString();
|
||||
bool isAvailable = std::find(healthy.begin(), healthy.end(), srvUUID) != healthy.end();
|
||||
|
|
|
@ -124,6 +124,14 @@ struct AqlValueHintUInt {
|
|||
uint64_t const value;
|
||||
};
|
||||
|
||||
struct AqlValueHintEmptyArray {
|
||||
constexpr AqlValueHintEmptyArray() noexcept {}
|
||||
};
|
||||
|
||||
struct AqlValueHintEmptyObject {
|
||||
constexpr AqlValueHintEmptyObject() noexcept {}
|
||||
};
|
||||
|
||||
struct AqlValue final {
|
||||
friend struct std::hash<arangodb::aql::AqlValue>;
|
||||
friend struct std::equal_to<arangodb::aql::AqlValue>;
|
||||
|
@ -330,6 +338,16 @@ struct AqlValue final {
|
|||
// construct from std::string
|
||||
explicit AqlValue(std::string const& value) : AqlValue(value.c_str(), value.size()) {}
|
||||
|
||||
explicit AqlValue(AqlValueHintEmptyArray const&) noexcept {
|
||||
_data.internal[0] = 0x01; // empty array in VPack
|
||||
setType(AqlValueType::VPACK_INLINE);
|
||||
}
|
||||
|
||||
explicit AqlValue(AqlValueHintEmptyObject const&) noexcept {
|
||||
_data.internal[0] = 0x0a; // empty object in VPack
|
||||
setType(AqlValueType::VPACK_INLINE);
|
||||
}
|
||||
|
||||
// construct from Buffer, potentially taking over its ownership
|
||||
// (by adjusting the boolean passed)
|
||||
AqlValue(arangodb::velocypack::Buffer<uint8_t>* buffer, bool& shouldDelete) {
|
||||
|
|
|
@ -588,7 +588,7 @@ AqlValue Expression::executeSimpleExpressionArray(
|
|||
size_t const n = node->numMembers();
|
||||
|
||||
if (n == 0) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
transaction::BuilderLeaser builder(trx);
|
||||
|
@ -621,7 +621,7 @@ AqlValue Expression::executeSimpleExpressionObject(
|
|||
size_t const n = node->numMembers();
|
||||
|
||||
if (n == 0) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyObjectSlice());
|
||||
return AqlValue(AqlValueHintEmptyObject());
|
||||
}
|
||||
|
||||
// unordered map to make object keys unique afterwards
|
||||
|
@ -1398,7 +1398,7 @@ AqlValue Expression::executeSimpleExpressionExpansion(
|
|||
|
||||
if (offset < 0 || count <= 0) {
|
||||
// no items to return... can already stop here
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
// FILTER
|
||||
|
@ -1412,7 +1412,7 @@ AqlValue Expression::executeSimpleExpressionExpansion(
|
|||
filterNode = nullptr;
|
||||
} else {
|
||||
// filter expression is always false
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1431,7 +1431,7 @@ AqlValue Expression::executeSimpleExpressionExpansion(
|
|||
|
||||
if (!a.isArray()) {
|
||||
TRI_ASSERT(!mustDestroy);
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
VPackBuilder builder;
|
||||
|
@ -1473,7 +1473,7 @@ AqlValue Expression::executeSimpleExpressionExpansion(
|
|||
|
||||
if (!a.isArray()) {
|
||||
TRI_ASSERT(!mustDestroy);
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
mustDestroy = localMustDestroy; // maybe we need to destroy...
|
||||
|
|
|
@ -1207,7 +1207,7 @@ AqlValue mergeParameters(ExpressionContext* expressionContext,
|
|||
size_t const n = parameters.size();
|
||||
|
||||
if (n == 0) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyObjectSlice());
|
||||
return AqlValue(AqlValueHintEmptyObject());
|
||||
}
|
||||
|
||||
// use the first argument as the preliminary result
|
||||
|
@ -1749,7 +1749,7 @@ AqlValue Functions::ToArray(ExpressionContext*,
|
|||
}
|
||||
|
||||
if (value.isNull(true)) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
transaction::BuilderLeaser builder(trx);
|
||||
|
@ -2915,7 +2915,7 @@ AqlValue Functions::Split(ExpressionContext* expressionContext,
|
|||
return AqlValue(AqlValueHintNull());
|
||||
}
|
||||
if (limitNumber == 0) {
|
||||
return AqlValue(VPackSlice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3119,7 +3119,7 @@ AqlValue Functions::RegexSplit(ExpressionContext* expressionContext,
|
|||
return AqlValue(AqlValueHintNull());
|
||||
}
|
||||
if (limitNumber == 0) {
|
||||
return AqlValue(VPackSlice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4109,7 +4109,7 @@ AqlValue Functions::Attributes(ExpressionContext* expressionContext,
|
|||
|
||||
TRI_ASSERT(value.isObject());
|
||||
if (value.length() == 0) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
AqlValueMaterializer materializer(trx);
|
||||
|
@ -4173,7 +4173,7 @@ AqlValue Functions::Values(ExpressionContext* expressionContext,
|
|||
|
||||
TRI_ASSERT(value.isObject());
|
||||
if (value.length() == 0) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
AqlValueMaterializer materializer(trx);
|
||||
|
@ -6426,7 +6426,7 @@ AqlValue Functions::RemoveValue(ExpressionContext* expressionContext,
|
|||
AqlValue list = ExtractFunctionParameterValue(parameters, 0);
|
||||
|
||||
if (list.isNull(true)) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
if (!list.isArray()) {
|
||||
|
@ -6487,7 +6487,7 @@ AqlValue Functions::RemoveValues(ExpressionContext* expressionContext,
|
|||
}
|
||||
|
||||
if (list.isNull(true)) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
if (!list.isArray() || !values.isArray()) {
|
||||
|
@ -6522,7 +6522,7 @@ AqlValue Functions::RemoveNth(ExpressionContext* expressionContext,
|
|||
AqlValue list = ExtractFunctionParameterValue(parameters, 0);
|
||||
|
||||
if (list.isNull(true)) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
if (!list.isArray()) {
|
||||
|
@ -7061,7 +7061,7 @@ AqlValue Functions::PregelResult(ExpressionContext* expressionContext,
|
|||
pregel::PregelFeature* feature = pregel::PregelFeature::instance();
|
||||
if (!feature) {
|
||||
::registerWarning(expressionContext, AFN, TRI_ERROR_FAILED);
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
|
||||
auto buffer = std::make_unique<VPackBuffer<uint8_t>>();
|
||||
|
@ -7070,7 +7070,7 @@ AqlValue Functions::PregelResult(ExpressionContext* expressionContext,
|
|||
std::shared_ptr<pregel::Conductor> c = feature->conductor(execNr);
|
||||
if (!c) {
|
||||
::registerWarning(expressionContext, AFN, TRI_ERROR_HTTP_NOT_FOUND);
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
c->collectAQLResults(builder);
|
||||
|
||||
|
@ -7078,13 +7078,13 @@ AqlValue Functions::PregelResult(ExpressionContext* expressionContext,
|
|||
std::shared_ptr<pregel::IWorker> worker = feature->worker(execNr);
|
||||
if (!worker) {
|
||||
::registerWarning(expressionContext, AFN, TRI_ERROR_HTTP_NOT_FOUND);
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
worker->aqlResult(builder);
|
||||
}
|
||||
|
||||
if (builder.isEmpty()) {
|
||||
return AqlValue(arangodb::velocypack::Slice::emptyArraySlice());
|
||||
return AqlValue(AqlValueHintEmptyArray());
|
||||
}
|
||||
TRI_ASSERT(builder.slice().isArray());
|
||||
|
||||
|
|
|
@ -2232,7 +2232,7 @@ Result ClusterInfo::setViewPropertiesCoordinator(
|
|||
return { TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND };
|
||||
}
|
||||
|
||||
auto const view = res.slice()[0].get(
|
||||
auto const view = res.slice()[0].get<std::string>(
|
||||
{ AgencyCommManager::path(), "Plan", "Views", databaseName, viewID }
|
||||
);
|
||||
|
||||
|
|
|
@ -602,14 +602,14 @@ void HeartbeatThread::runSingleServer() {
|
|||
VPackSlice agentPool = response.get(".agency");
|
||||
updateAgentPool(agentPool);
|
||||
|
||||
VPackSlice shutdownSlice = response.get({AgencyCommManager::path(), "Shutdown"});
|
||||
VPackSlice shutdownSlice = response.get<std::string>({AgencyCommManager::path(), "Shutdown"});
|
||||
if (shutdownSlice.isBool() && shutdownSlice.getBool()) {
|
||||
ApplicationServer::server->beginShutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
// performing failover checks
|
||||
VPackSlice async = response.get({AgencyCommManager::path(), "Plan", "AsyncReplication"});
|
||||
VPackSlice async = response.get<std::string>({AgencyCommManager::path(), "Plan", "AsyncReplication"});
|
||||
if (!async.isObject()) {
|
||||
LOG_TOPIC(WARN, Logger::HEARTBEAT)
|
||||
<< "Heartbeat: Could not read async-replication metadata from agency!";
|
||||
|
|
|
@ -91,7 +91,7 @@ arangodb::Result Databases::info(TRI_vocbase_t* vocbase, VPackBuilder& result) {
|
|||
return Result(commRes.errorCode(), commRes.errorMessage());
|
||||
}
|
||||
|
||||
VPackSlice value = commRes.slice()[0].get(
|
||||
VPackSlice value = commRes.slice()[0].get<std::string>(
|
||||
{AgencyCommManager::path(), "Plan", "Databases", vocbase->name()});
|
||||
if (value.isObject() && value.hasKey("name")) {
|
||||
VPackValueLength l = 0;
|
||||
|
|
|
@ -102,7 +102,7 @@ void* LanguageFeature::prepareIcu(std::string const& binaryPath,
|
|||
"'; please make sure it is available; "
|
||||
"the variable ICU_DATA='";
|
||||
std::string icupath;
|
||||
if ( TRI_GETENV("ICU_DATA", icupath)) {
|
||||
if (TRI_GETENV("ICU_DATA", icupath)) {
|
||||
msg += icupath;
|
||||
}
|
||||
msg += "' should point to the directory containing '" + fn + "'";
|
||||
|
|
|
@ -42,7 +42,7 @@ class StringRef {
|
|||
constexpr StringRef() : _data(""), _length(0) {}
|
||||
|
||||
/// @brief create a StringRef from an std::string
|
||||
explicit StringRef(std::string const& str) : _data(str.c_str()), _length(str.size()) {}
|
||||
explicit StringRef(std::string const& str) noexcept : _data(str.data()), _length(str.size()) {}
|
||||
|
||||
/// @brief create a StringRef from a null-terminated C string
|
||||
explicit StringRef(char const* data) : _data(data), _length(strlen(data)) {}
|
||||
|
|
|
@ -75,6 +75,7 @@ set(LIB_ARANGO_VPACK
|
|||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Options.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Parser.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Slice.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/StringRef.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Utf8Helper.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/ValueType.cpp
|
||||
${PROJECT_SOURCE_DIR}/3rdParty/velocypack/src/Validator.cpp
|
||||
|
|
|
@ -261,7 +261,7 @@ std::unique_ptr<arangodb::aql::ExecutionPlan> planFromQuery(
|
|||
|
||||
uint64_t getCurrentPlanVersion() {
|
||||
auto const result = arangodb::AgencyComm().getValues("Plan");
|
||||
auto const planVersionSlice = result.slice()[0].get(
|
||||
auto const planVersionSlice = result.slice()[0].get<std::string>(
|
||||
{ arangodb::AgencyCommManager::path(), "Plan", "Version" }
|
||||
);
|
||||
return planVersionSlice.getNumber<uint64_t>();
|
||||
|
|
Loading…
Reference in New Issue