mirror of https://gitee.com/bigwinds/arangodb
updated vpack library
This commit is contained in:
parent
80433b23bb
commit
0089b0fcf6
|
@ -33,6 +33,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "velocypack/velocypack-common.h"
|
#include "velocypack/velocypack-common.h"
|
||||||
|
#include "velocypack/Slice.h"
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
namespace velocypack {
|
namespace velocypack {
|
||||||
|
@ -71,6 +72,30 @@ class AttributeTranslator {
|
||||||
size_t _count;
|
size_t _count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AttributeTranslatorScope {
|
||||||
|
private:
|
||||||
|
AttributeTranslatorScope(AttributeTranslatorScope const&) = delete;
|
||||||
|
AttributeTranslatorScope& operator= (AttributeTranslatorScope const&) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AttributeTranslatorScope(AttributeTranslator* translator)
|
||||||
|
: _old(Slice::attributeTranslator) {
|
||||||
|
Slice::attributeTranslator = translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
~AttributeTranslatorScope() {
|
||||||
|
revert();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prematurely revert the change
|
||||||
|
void revert() {
|
||||||
|
Slice::attributeTranslator = _old;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeTranslator* _old;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace arangodb::velocypack
|
} // namespace arangodb::velocypack
|
||||||
} // namespace arangodb
|
} // namespace arangodb
|
||||||
|
|
||||||
|
|
|
@ -115,20 +115,16 @@ class Builder {
|
||||||
// at position base, also determine the length len of the attribute.
|
// at position base, also determine the length len of the attribute.
|
||||||
// This takes into account the different possibilities for the format
|
// This takes into account the different possibilities for the format
|
||||||
// of attribute names:
|
// of attribute names:
|
||||||
static uint8_t const* findAttrName(uint8_t const* base, uint64_t& len,
|
static uint8_t const* findAttrName(uint8_t const* base, uint64_t& len);
|
||||||
Options const*);
|
|
||||||
|
|
||||||
static void sortObjectIndexShort(uint8_t* objBase,
|
static void sortObjectIndexShort(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets);
|
||||||
Options const*);
|
|
||||||
|
|
||||||
static void sortObjectIndexLong(uint8_t* objBase,
|
static void sortObjectIndexLong(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets);
|
||||||
Options const*);
|
|
||||||
|
|
||||||
static void sortObjectIndex(uint8_t* objBase,
|
static void sortObjectIndex(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets);
|
||||||
Options const*);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Options const* options;
|
Options const* options;
|
||||||
|
@ -301,7 +297,7 @@ class Builder {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return Slice();
|
return Slice();
|
||||||
}
|
}
|
||||||
return Slice(start(), options);
|
return Slice(start());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the actual size here, but only when sealed
|
// Compute the actual size here, but only when sealed
|
||||||
|
|
|
@ -71,7 +71,7 @@ class ArrayIterator {
|
||||||
ArrayIterator& operator++() {
|
ArrayIterator& operator++() {
|
||||||
++_position;
|
++_position;
|
||||||
if (_position <= _size && _current != nullptr) {
|
if (_position <= _size && _current != nullptr) {
|
||||||
_current += Slice(_current, _slice.options).byteSize();
|
_current += Slice(_current).byteSize();
|
||||||
} else {
|
} else {
|
||||||
_current = nullptr;
|
_current = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ class ArrayIterator {
|
||||||
|
|
||||||
Slice operator*() const {
|
Slice operator*() const {
|
||||||
if (_current != nullptr) {
|
if (_current != nullptr) {
|
||||||
return Slice(_current, _slice.options);
|
return Slice(_current);
|
||||||
}
|
}
|
||||||
return _slice.at(_position);
|
return _slice.at(_position);
|
||||||
}
|
}
|
||||||
|
@ -181,9 +181,9 @@ class ObjectIterator {
|
||||||
++_position;
|
++_position;
|
||||||
if (_position <= _size && _current != nullptr) {
|
if (_position <= _size && _current != nullptr) {
|
||||||
// skip over key
|
// skip over key
|
||||||
_current += Slice(_current, _slice.options).byteSize();
|
_current += Slice(_current).byteSize();
|
||||||
// skip over value
|
// skip over value
|
||||||
_current += Slice(_current, _slice.options).byteSize();
|
_current += Slice(_current).byteSize();
|
||||||
} else {
|
} else {
|
||||||
_current = nullptr;
|
_current = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -203,8 +203,8 @@ class ObjectIterator {
|
||||||
|
|
||||||
ObjectPair operator*() const {
|
ObjectPair operator*() const {
|
||||||
if (_current != nullptr) {
|
if (_current != nullptr) {
|
||||||
Slice key = Slice(_current, _slice.options);
|
Slice key = Slice(_current);
|
||||||
return ObjectPair(key, Slice(_current + key.byteSize(), _slice.options));
|
return ObjectPair(key, Slice(_current + key.byteSize()));
|
||||||
}
|
}
|
||||||
return ObjectPair(_slice.keyAt(_position), _slice.valueAt(_position));
|
return ObjectPair(_slice.keyAt(_position), _slice.valueAt(_position));
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ class ObjectIterator {
|
||||||
throw Exception(Exception::IndexOutOfBounds);
|
throw Exception(Exception::IndexOutOfBounds);
|
||||||
}
|
}
|
||||||
if (_current != nullptr) {
|
if (_current != nullptr) {
|
||||||
return Slice(_current, _slice.options);
|
return Slice(_current);
|
||||||
}
|
}
|
||||||
return _slice.keyAt(_position);
|
return _slice.keyAt(_position);
|
||||||
}
|
}
|
||||||
|
@ -242,8 +242,8 @@ class ObjectIterator {
|
||||||
throw Exception(Exception::IndexOutOfBounds);
|
throw Exception(Exception::IndexOutOfBounds);
|
||||||
}
|
}
|
||||||
if (_current != nullptr) {
|
if (_current != nullptr) {
|
||||||
Slice key = Slice(_current, _slice.options);
|
Slice key = Slice(_current);
|
||||||
return Slice(_current + key.byteSize(), _slice.options);
|
return Slice(_current + key.byteSize());
|
||||||
}
|
}
|
||||||
return _slice.valueAt(_position);
|
return _slice.valueAt(_position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ struct CustomTypeHandler {
|
||||||
|
|
||||||
virtual void toJson(Slice const& value, Dumper* dumper,
|
virtual void toJson(Slice const& value, Dumper* dumper,
|
||||||
Slice const& base) = 0;
|
Slice const& base) = 0;
|
||||||
virtual ValueLength byteSize(Slice const& value) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace velocypack {
|
||||||
// forward for fasthash64 function declared elsewhere
|
// forward for fasthash64 function declared elsewhere
|
||||||
uint64_t fasthash64(void const*, size_t, uint64_t);
|
uint64_t fasthash64(void const*, size_t, uint64_t);
|
||||||
|
|
||||||
|
class AttributeTranslator;
|
||||||
class SliceScope;
|
class SliceScope;
|
||||||
|
|
||||||
class Slice {
|
class Slice {
|
||||||
|
@ -59,43 +60,17 @@ class Slice {
|
||||||
uint8_t const* _start;
|
uint8_t const* _start;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Options const* options;
|
|
||||||
|
static AttributeTranslator* attributeTranslator;
|
||||||
|
|
||||||
// constructor for an empty Value of type None
|
// constructor for an empty Value of type None
|
||||||
Slice() : Slice("\x00", &Options::Defaults) {}
|
Slice() : Slice("\x00") {}
|
||||||
|
|
||||||
explicit Slice(uint8_t const* start,
|
explicit Slice(uint8_t const* start)
|
||||||
Options const* options = &Options::Defaults)
|
: _start(start) {}
|
||||||
: _start(start), options(options) {
|
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Slice(char const* start, Options const* options = &Options::Defaults)
|
explicit Slice(char const* start)
|
||||||
: _start(reinterpret_cast<uint8_t const*>(start)), options(options) {
|
: _start(reinterpret_cast<uint8_t const*>(start)) {}
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Slice(Slice const& other) : _start(other._start), options(other.options) {
|
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Slice(Slice&& other) : _start(other._start), options(other.options) {
|
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Slice& operator=(Slice const& other) {
|
|
||||||
_start = other._start;
|
|
||||||
options = other.options;
|
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Slice& operator=(Slice&& other) {
|
|
||||||
_start = other._start;
|
|
||||||
options = other.options;
|
|
||||||
VELOCYPACK_ASSERT(options != nullptr);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a Slice from Json and adds it to a scope
|
// creates a Slice from Json and adds it to a scope
|
||||||
static Slice fromJson(SliceScope& scope, std::string const& json,
|
static Slice fromJson(SliceScope& scope, std::string const& json,
|
||||||
|
@ -281,7 +256,7 @@ class Slice {
|
||||||
// find number of items
|
// find number of items
|
||||||
if (h <= 0x05) { // No offset table or length, need to compute:
|
if (h <= 0x05) { // No offset table or length, need to compute:
|
||||||
ValueLength firstSubOffset = findDataOffset(h);
|
ValueLength firstSubOffset = findDataOffset(h);
|
||||||
Slice first(_start + firstSubOffset, options);
|
Slice first(_start + firstSubOffset);
|
||||||
return (end - firstSubOffset) / first.byteSize();
|
return (end - firstSubOffset) / first.byteSize();
|
||||||
} else if (offsetSize < 8) {
|
} else if (offsetSize < 8) {
|
||||||
return readInteger<ValueLength>(_start + offsetSize + 1, offsetSize);
|
return readInteger<ValueLength>(_start + offsetSize + 1, offsetSize);
|
||||||
|
@ -322,7 +297,7 @@ class Slice {
|
||||||
}
|
}
|
||||||
|
|
||||||
Slice key = getNthKey(index, false);
|
Slice key = getNthKey(index, false);
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for the specified attribute path inside an Object
|
// look for the specified attribute path inside an Object
|
||||||
|
@ -334,7 +309,7 @@ class Slice {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use ourselves as the starting point
|
// use ourselves as the starting point
|
||||||
Slice last = Slice(start(), options);
|
Slice last = Slice(start());
|
||||||
for (size_t i = 0; i < attributes.size(); ++i) {
|
for (size_t i = 0; i < attributes.size(); ++i) {
|
||||||
// fetch subattribute
|
// fetch subattribute
|
||||||
last = last.get(attributes[i]);
|
last = last.get(attributes[i]);
|
||||||
|
@ -636,11 +611,41 @@ class Slice {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ValueType::Custom: {
|
case ValueType::Custom: {
|
||||||
if (options->customTypeHandler == nullptr) {
|
auto const h = head();
|
||||||
throw Exception(Exception::NeedCustomTypeHandler);
|
switch (h) {
|
||||||
|
case 0xf0: return 1 + 1;
|
||||||
|
case 0xf1: return 1 + 2;
|
||||||
|
case 0xf2: return 1 + 4;
|
||||||
|
case 0xf3: return 1 + 8;
|
||||||
|
|
||||||
|
case 0xf4:
|
||||||
|
case 0xf5:
|
||||||
|
case 0xf6: {
|
||||||
|
return 1 + readInteger<ValueLength>(_start + 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return options->customTypeHandler->byteSize(*this);
|
case 0xf7:
|
||||||
|
case 0xf8:
|
||||||
|
case 0xf9: {
|
||||||
|
return 1 + readInteger<ValueLength>(_start + 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xfa:
|
||||||
|
case 0xfb:
|
||||||
|
case 0xfc: {
|
||||||
|
return 1 + readInteger<ValueLength>(_start + 1, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xfd:
|
||||||
|
case 0xfe:
|
||||||
|
case 0xff: {
|
||||||
|
return 1 + readInteger<ValueLength>(_start + 1, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// fallthrough intentional
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,8 +664,8 @@ class Slice {
|
||||||
return Slice(left).equals(Slice(right));
|
return Slice(left).equals(Slice(right));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toJson() const;
|
std::string toJson(Options const* options = &Options::Defaults) const;
|
||||||
std::string toString() const;
|
std::string toString(Options const* options = &Options::Defaults) const;
|
||||||
std::string hexType() const;
|
std::string hexType() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -743,8 +748,7 @@ class SliceScope {
|
||||||
SliceScope();
|
SliceScope();
|
||||||
~SliceScope();
|
~SliceScope();
|
||||||
|
|
||||||
Slice add(uint8_t const* data, ValueLength size,
|
Slice add(uint8_t const* data, ValueLength size);
|
||||||
Options const* options = &Options::Defaults);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t*> _allocations;
|
std::vector<uint8_t*> _allocations;
|
||||||
|
|
|
@ -118,7 +118,7 @@ class SliceContainer {
|
||||||
if (_data == nullptr) {
|
if (_data == nullptr) {
|
||||||
return Slice();
|
return Slice();
|
||||||
}
|
}
|
||||||
return Slice(_data, &Options::Defaults);
|
return Slice(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t const* begin() const { return _data; }
|
inline uint8_t const* begin() const { return _data; }
|
||||||
|
|
|
@ -67,8 +67,7 @@ void Builder::doActualSort(std::vector<SortEntry>& entries) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len,
|
uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len) {
|
||||||
Options const* options) {
|
|
||||||
uint8_t const b = *base;
|
uint8_t const b = *base;
|
||||||
if (b >= 0x40 && b <= 0xbe) {
|
if (b >= 0x40 && b <= 0xbe) {
|
||||||
// short UTF-8 string
|
// short UTF-8 string
|
||||||
|
@ -86,13 +85,11 @@ uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len,
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate attribute name
|
// translate attribute name
|
||||||
Slice s(base, options);
|
return findAttrName(Slice(base).makeKey().start(), len);
|
||||||
return findAttrName(s.makeKey().start(), len, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::sortObjectIndexShort(uint8_t* objBase,
|
void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets) {
|
||||||
Options const* options) {
|
|
||||||
auto cmp = [&](ValueLength a, ValueLength b) -> bool {
|
auto cmp = [&](ValueLength a, ValueLength b) -> bool {
|
||||||
uint8_t const* aa = objBase + a;
|
uint8_t const* aa = objBase + a;
|
||||||
uint8_t const* bb = objBase + b;
|
uint8_t const* bb = objBase + b;
|
||||||
|
@ -104,8 +101,8 @@ void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||||
} else {
|
} else {
|
||||||
uint64_t lena;
|
uint64_t lena;
|
||||||
uint64_t lenb;
|
uint64_t lenb;
|
||||||
aa = findAttrName(aa, lena, options);
|
aa = findAttrName(aa, lena);
|
||||||
bb = findAttrName(bb, lenb, options);
|
bb = findAttrName(bb, lenb);
|
||||||
uint64_t m = (std::min)(lena, lenb);
|
uint64_t m = (std::min)(lena, lenb);
|
||||||
int c = memcmp(aa, bb, checkOverflow(m));
|
int c = memcmp(aa, bb, checkOverflow(m));
|
||||||
return (c < 0 || (c == 0 && lena < lenb));
|
return (c < 0 || (c == 0 && lena < lenb));
|
||||||
|
@ -115,8 +112,7 @@ void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::sortObjectIndexLong(uint8_t* objBase,
|
void Builder::sortObjectIndexLong(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets) {
|
||||||
Options const* options) {
|
|
||||||
// on some platforms we can use a thread-local vector
|
// on some platforms we can use a thread-local vector
|
||||||
#if __llvm__ == 1
|
#if __llvm__ == 1
|
||||||
// nono thread local
|
// nono thread local
|
||||||
|
@ -134,7 +130,7 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
SortEntry e;
|
SortEntry e;
|
||||||
e.offset = offsets[i];
|
e.offset = offsets[i];
|
||||||
e.nameStart = findAttrName(objBase + e.offset, e.nameSize, options);
|
e.nameStart = findAttrName(objBase + e.offset, e.nameSize);
|
||||||
entries.push_back(e);
|
entries.push_back(e);
|
||||||
}
|
}
|
||||||
VELOCYPACK_ASSERT(entries.size() == n);
|
VELOCYPACK_ASSERT(entries.size() == n);
|
||||||
|
@ -147,12 +143,11 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Builder::sortObjectIndex(uint8_t* objBase,
|
void Builder::sortObjectIndex(uint8_t* objBase,
|
||||||
std::vector<ValueLength>& offsets,
|
std::vector<ValueLength>& offsets) {
|
||||||
Options const* options) {
|
|
||||||
if (offsets.size() > 32) {
|
if (offsets.size() > 32) {
|
||||||
sortObjectIndexLong(objBase, offsets, options);
|
sortObjectIndexLong(objBase, offsets);
|
||||||
} else {
|
} else {
|
||||||
sortObjectIndexShort(objBase, offsets, options);
|
sortObjectIndexShort(objBase, offsets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +320,7 @@ Builder& Builder::close() {
|
||||||
if (!options->sortAttributeNames) {
|
if (!options->sortAttributeNames) {
|
||||||
_start[tos] = 0x0f; // unsorted
|
_start[tos] = 0x0f; // unsorted
|
||||||
} else if (index.size() >= 2 && options->sortAttributeNames) {
|
} else if (index.size() >= 2 && options->sortAttributeNames) {
|
||||||
sortObjectIndex(_start + tos, index, options);
|
sortObjectIndex(_start + tos, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < index.size(); i++) {
|
for (size_t i = 0; i < index.size(); i++) {
|
||||||
|
@ -373,7 +368,7 @@ Builder& Builder::close() {
|
||||||
if (options->checkAttributeUniqueness && index.size() > 1 &&
|
if (options->checkAttributeUniqueness && index.size() > 1 &&
|
||||||
_start[tos] >= 0x0b) {
|
_start[tos] >= 0x0b) {
|
||||||
// check uniqueness of attribute names
|
// check uniqueness of attribute names
|
||||||
checkAttributeUniqueness(Slice(_start + tos, options));
|
checkAttributeUniqueness(Slice(_start + tos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now the array or object is complete, we pop a ValueLength
|
// Now the array or object is complete, we pop a ValueLength
|
||||||
|
@ -397,7 +392,7 @@ bool Builder::hasKey(std::string const& key) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < index.size(); ++i) {
|
for (size_t i = 0; i < index.size(); ++i) {
|
||||||
Slice s(_start + tos + index[i], options);
|
Slice s(_start + tos + index[i]);
|
||||||
if (s.makeKey().isEqualString(key)) {
|
if (s.makeKey().isEqualString(key)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -419,9 +414,9 @@ Slice Builder::getKey(std::string const& key) const {
|
||||||
return Slice();
|
return Slice();
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < index.size(); ++i) {
|
for (size_t i = 0; i < index.size(); ++i) {
|
||||||
Slice s(_start + tos + index[i], options);
|
Slice s(_start + tos + index[i]);
|
||||||
if (s.makeKey().isEqualString(key)) {
|
if (s.makeKey().isEqualString(key)) {
|
||||||
return Slice(s.start() + s.byteSize(), options);
|
return Slice(s.start() + s.byteSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Slice();
|
return Slice();
|
||||||
|
|
|
@ -391,7 +391,7 @@ void Dumper::dumpValue(Slice const* slice, Slice const* base) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ValueType::External: {
|
case ValueType::External: {
|
||||||
Slice const external(slice->getExternal(), slice->options);
|
Slice const external(slice->getExternal());
|
||||||
dumpValue(&external, base);
|
dumpValue(&external, base);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,14 +478,14 @@ void Parser::parseObject() {
|
||||||
} else {
|
} else {
|
||||||
parseString();
|
parseString();
|
||||||
if (options->attributeExcludeHandler->shouldExclude(
|
if (options->attributeExcludeHandler->shouldExclude(
|
||||||
Slice(_b->_start + lastPos, options), _nesting)) {
|
Slice(_b->_start + lastPos), _nesting)) {
|
||||||
excludeAttribute = true;
|
excludeAttribute = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!excludeAttribute && options->attributeTranslator != nullptr) {
|
if (!excludeAttribute && options->attributeTranslator != nullptr) {
|
||||||
// check if a translation for the attribute name exists
|
// check if a translation for the attribute name exists
|
||||||
Slice key(_b->_start + lastPos, options);
|
Slice key(_b->_start + lastPos);
|
||||||
|
|
||||||
if (key.isString()) {
|
if (key.isString()) {
|
||||||
ValueLength keyLength;
|
ValueLength keyLength;
|
||||||
|
@ -498,7 +498,7 @@ void Parser::parseObject() {
|
||||||
// and simply overwrite the existing key with the numeric translation
|
// and simply overwrite the existing key with the numeric translation
|
||||||
// id
|
// id
|
||||||
_b->_pos = lastPos;
|
_b->_pos = lastPos;
|
||||||
_b->addUInt(Slice(translated, options).getUInt());
|
_b->addUInt(Slice(translated).getUInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
using namespace arangodb::velocypack;
|
using namespace arangodb::velocypack;
|
||||||
using VT = arangodb::velocypack::ValueType;
|
using VT = arangodb::velocypack::ValueType;
|
||||||
|
|
||||||
|
AttributeTranslator* Slice::attributeTranslator = nullptr;
|
||||||
|
|
||||||
VT const Slice::TypeMap[256] = {
|
VT const Slice::TypeMap[256] = {
|
||||||
/* 0x00 */ VT::None, /* 0x01 */ VT::Array,
|
/* 0x00 */ VT::None, /* 0x01 */ VT::Array,
|
||||||
/* 0x02 */ VT::Array, /* 0x03 */ VT::Array,
|
/* 0x02 */ VT::Array, /* 0x03 */ VT::Array,
|
||||||
|
@ -220,7 +222,7 @@ Slice Slice::fromJson(SliceScope& scope, std::string const& json,
|
||||||
parser.parse(json);
|
parser.parse(json);
|
||||||
|
|
||||||
Builder const& b = parser.builder(); // don't copy Builder contents here
|
Builder const& b = parser.builder(); // don't copy Builder contents here
|
||||||
return scope.add(b.start(), b.size(), options);
|
return scope.add(b.start(), b.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// translates an integer key into a string
|
// translates an integer key into a string
|
||||||
|
@ -230,12 +232,11 @@ Slice Slice::translate() const {
|
||||||
"Cannot translate key of this type");
|
"Cannot translate key of this type");
|
||||||
}
|
}
|
||||||
uint64_t id = getUInt();
|
uint64_t id = getUInt();
|
||||||
|
if (attributeTranslator == nullptr) {
|
||||||
if (options->attributeTranslator == nullptr) {
|
|
||||||
throw Exception(Exception::NeedAttributeTranslator);
|
throw Exception(Exception::NeedAttributeTranslator);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Slice(options->attributeTranslator->translate(id), options);
|
return Slice(attributeTranslator->translate(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if two Slices are equal on the binary level
|
// check if two Slices are equal on the binary level
|
||||||
|
@ -254,7 +255,7 @@ bool Slice::equals(Slice const& other) const {
|
||||||
arangodb::velocypack::checkOverflow(size)) == 0);
|
arangodb::velocypack::checkOverflow(size)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Slice::toJson() const {
|
std::string Slice::toJson(Options const* options) const {
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
StringSink sink(&buffer);
|
StringSink sink(&buffer);
|
||||||
Dumper dumper(&sink, options);
|
Dumper dumper(&sink, options);
|
||||||
|
@ -262,7 +263,7 @@ std::string Slice::toJson() const {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Slice::toString() const {
|
std::string Slice::toString(Options const* options) const {
|
||||||
// copy options and set prettyPrint in copy
|
// copy options and set prettyPrint in copy
|
||||||
Options prettyOptions = *options;
|
Options prettyOptions = *options;
|
||||||
prettyOptions.prettyPrint = true;
|
prettyOptions.prettyPrint = true;
|
||||||
|
@ -311,16 +312,16 @@ Slice Slice::get(std::string const& attribute) const {
|
||||||
dataOffset = findDataOffset(h);
|
dataOffset = findDataOffset(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
Slice key = Slice(_start + dataOffset, options);
|
Slice key = Slice(_start + dataOffset);
|
||||||
|
|
||||||
if (key.isString() && key.isEqualString(attribute)) {
|
if (key.isString() && key.isEqualString(attribute)) {
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.isSmallInt() || key.isUInt()) {
|
if (key.isSmallInt() || key.isUInt()) {
|
||||||
// translate key
|
// translate key
|
||||||
if (key.translate().isEqualString(attribute)) {
|
if (key.translate().isEqualString(attribute)) {
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +461,7 @@ Slice Slice::getFromCompactObject(std::string const& attribute) const {
|
||||||
while (it.valid()) {
|
while (it.valid()) {
|
||||||
Slice key = it.key();
|
Slice key = it.key();
|
||||||
if (key.makeKey().isEqualString(attribute)) {
|
if (key.makeKey().isEqualString(attribute)) {
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
it.next();
|
it.next();
|
||||||
|
@ -493,7 +494,7 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
||||||
// find the number of items
|
// find the number of items
|
||||||
ValueLength n;
|
ValueLength n;
|
||||||
if (h <= 0x05) { // No offset table or length, need to compute:
|
if (h <= 0x05) { // No offset table or length, need to compute:
|
||||||
Slice first(_start + dataOffset, options);
|
Slice first(_start + dataOffset);
|
||||||
n = (end - dataOffset) / first.byteSize();
|
n = (end - dataOffset) / first.byteSize();
|
||||||
} else if (offsetSize < 8) {
|
} else if (offsetSize < 8) {
|
||||||
n = readInteger<ValueLength>(_start + 1 + offsetSize, offsetSize);
|
n = readInteger<ValueLength>(_start + 1 + offsetSize, offsetSize);
|
||||||
|
@ -514,8 +515,7 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
||||||
if (dataOffset == 0) {
|
if (dataOffset == 0) {
|
||||||
dataOffset = findDataOffset(h);
|
dataOffset = findDataOffset(h);
|
||||||
}
|
}
|
||||||
Slice firstItem(_start + dataOffset, options);
|
return dataOffset + index * Slice(_start + dataOffset).byteSize();
|
||||||
return dataOffset + index * firstItem.byteSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueLength const ieBase =
|
ValueLength const ieBase =
|
||||||
|
@ -527,14 +527,14 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
||||||
Slice Slice::getNth(ValueLength index) const {
|
Slice Slice::getNth(ValueLength index) const {
|
||||||
VELOCYPACK_ASSERT(type() == ValueType::Array);
|
VELOCYPACK_ASSERT(type() == ValueType::Array);
|
||||||
|
|
||||||
return Slice(_start + getNthOffset(index), options);
|
return Slice(_start + getNthOffset(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the nth member from an Object
|
// extract the nth member from an Object
|
||||||
Slice Slice::getNthKey(ValueLength index, bool translate) const {
|
Slice Slice::getNthKey(ValueLength index, bool translate) const {
|
||||||
VELOCYPACK_ASSERT(type() == ValueType::Object);
|
VELOCYPACK_ASSERT(type() == ValueType::Object);
|
||||||
|
|
||||||
Slice s(_start + getNthOffset(index), options);
|
Slice s(_start + getNthOffset(index));
|
||||||
|
|
||||||
if (translate) {
|
if (translate) {
|
||||||
return s.makeKey();
|
return s.makeKey();
|
||||||
|
@ -568,10 +568,9 @@ ValueLength Slice::getNthOffsetFromCompact(ValueLength index) const {
|
||||||
ValueLength current = 0;
|
ValueLength current = 0;
|
||||||
while (current != index) {
|
while (current != index) {
|
||||||
uint8_t const* s = _start + offset;
|
uint8_t const* s = _start + offset;
|
||||||
Slice key = Slice(s, options);
|
offset += Slice(s).byteSize();
|
||||||
offset += key.byteSize();
|
|
||||||
if (h == 0x14) {
|
if (h == 0x14) {
|
||||||
Slice value = Slice(_start + offset, options);
|
Slice value = Slice(_start + offset);
|
||||||
offset += value.byteSize();
|
offset += value.byteSize();
|
||||||
}
|
}
|
||||||
++current;
|
++current;
|
||||||
|
@ -585,8 +584,7 @@ Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
||||||
ValueLength n) const {
|
ValueLength n) const {
|
||||||
for (ValueLength index = 0; index < n; ++index) {
|
for (ValueLength index = 0; index < n; ++index) {
|
||||||
ValueLength offset = ieBase + index * offsetSize;
|
ValueLength offset = ieBase + index * offsetSize;
|
||||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
|
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize));
|
||||||
options);
|
|
||||||
|
|
||||||
if (key.isString()) {
|
if (key.isString()) {
|
||||||
if (!key.isEqualString(attribute)) {
|
if (!key.isEqualString(attribute)) {
|
||||||
|
@ -603,7 +601,7 @@ Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
||||||
}
|
}
|
||||||
|
|
||||||
// key is identical. now return value
|
// key is identical. now return value
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing found
|
// nothing found
|
||||||
|
@ -624,8 +622,7 @@ Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
||||||
ValueLength index = l + ((r - l) / 2);
|
ValueLength index = l + ((r - l) / 2);
|
||||||
|
|
||||||
ValueLength offset = ieBase + index * offsetSize;
|
ValueLength offset = ieBase + index * offsetSize;
|
||||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
|
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize));
|
||||||
options);
|
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
if (key.isString()) {
|
if (key.isString()) {
|
||||||
|
@ -640,7 +637,7 @@ Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
// found
|
// found
|
||||||
return Slice(key.start() + key.byteSize(), options);
|
return Slice(key.start() + key.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
|
@ -665,15 +662,12 @@ SliceScope::~SliceScope() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Slice SliceScope::add(uint8_t const* data, ValueLength size,
|
Slice SliceScope::add(uint8_t const* data, ValueLength size) {
|
||||||
Options const* options) {
|
|
||||||
size_t const s = checkOverflow(size);
|
size_t const s = checkOverflow(size);
|
||||||
std::unique_ptr<uint8_t[]> copy(new uint8_t[s]);
|
std::unique_ptr<uint8_t[]> copy(new uint8_t[s]);
|
||||||
memcpy(copy.get(), data, s);
|
memcpy(copy.get(), data, s);
|
||||||
_allocations.push_back(copy.get());
|
_allocations.push_back(copy.get());
|
||||||
uint8_t const* start = copy.release();
|
return Slice(copy.release());
|
||||||
|
|
||||||
return Slice(start, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, Slice const* slice) {
|
std::ostream& operator<<(std::ostream& stream, Slice const* slice) {
|
||||||
|
@ -687,5 +681,4 @@ std::ostream& operator<<(std::ostream& stream, Slice const& slice) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(arangodb::velocypack::Slice) ==
|
static_assert(sizeof(arangodb::velocypack::Slice) ==
|
||||||
sizeof(void*) + sizeof(void*),
|
sizeof(void*), "Slice has an unexpected size");
|
||||||
"Slice has an unexpected size");
|
|
||||||
|
|
|
@ -335,7 +335,7 @@ class MarkerAccessorDocument : public T {
|
||||||
|
|
||||||
uint8_t* vPackValue() const { return versionedVPackValue() + 1; }
|
uint8_t* vPackValue() const { return versionedVPackValue() + 1; }
|
||||||
|
|
||||||
VPackSlice slice() const { return VPackSlice(this->vpackValue(), StorageOptions::getOptions()); }
|
VPackSlice slice() const { return VPackSlice(this->vpackValue(), StorageOptions::getDefaultOptions()); }
|
||||||
|
|
||||||
static uint64_t staticLength() { return 8; }
|
static uint64_t staticLength() { return 8; }
|
||||||
};
|
};
|
||||||
|
@ -415,7 +415,7 @@ class MarkerAccessorStructural : public T {
|
||||||
|
|
||||||
uint8_t* vPackValue() const { return versionedVPackValue() + 1; }
|
uint8_t* vPackValue() const { return versionedVPackValue() + 1; }
|
||||||
|
|
||||||
VPackSlice slice() const { return VPackSlice(this->vpackValue(), StorageOptions::getOptions()); }
|
VPackSlice slice() const { return VPackSlice(this->vpackValue(), StorageOptions::getDefaultOptions()); }
|
||||||
|
|
||||||
static uint64_t staticLength() { return 0; }
|
static uint64_t staticLength() { return 0; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,12 +23,12 @@
|
||||||
|
|
||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Basics/Exceptions.h"
|
#include "Basics/Exceptions.h"
|
||||||
#include "Basics/Logger.h"
|
|
||||||
#include "Utils/CollectionNameResolver.h"
|
#include "Utils/CollectionNameResolver.h"
|
||||||
#include "VocBase/voc-types.h"
|
#include "VocBase/vocbase.h"
|
||||||
|
|
||||||
#include <velocypack/AttributeTranslator.h>
|
#include <velocypack/AttributeTranslator.h>
|
||||||
#include <velocypack/Dumper.h>
|
#include <velocypack/Dumper.h>
|
||||||
|
#include <velocypack/Options.h>
|
||||||
#include <velocypack/Slice.h>
|
#include <velocypack/Slice.h>
|
||||||
#include <velocypack/Value.h>
|
#include <velocypack/Value.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
@ -37,57 +37,26 @@ using namespace arangodb;
|
||||||
|
|
||||||
static std::unique_ptr<VPackAttributeTranslator> translator;
|
static std::unique_ptr<VPackAttributeTranslator> translator;
|
||||||
static std::unique_ptr<VPackAttributeExcludeHandler> excludeHandler;
|
static std::unique_ptr<VPackAttributeExcludeHandler> excludeHandler;
|
||||||
static std::unique_ptr<VPackOptions> options;
|
static std::unique_ptr<VPackCustomTypeHandler> customLengthHandler;
|
||||||
|
static std::unique_ptr<VPackOptions> defaultOptions;
|
||||||
|
static std::unique_ptr<VPackOptions> insertOptions;
|
||||||
|
|
||||||
|
// attribute exclude handler for skipping over system attributes
|
||||||
void StorageOptions::initialize() {
|
struct SystemAttributeExcludeHandler : public VPackAttributeExcludeHandler {
|
||||||
translator.reset(new VPackAttributeTranslator);
|
|
||||||
/*
|
|
||||||
// these attribute names will be translated into short integer values
|
|
||||||
translator->add(TRI_VOC_ATTRIBUTE_KEY, 1);
|
|
||||||
translator->add(TRI_VOC_ATTRIBUTE_REV, 2);
|
|
||||||
translator->add(TRI_VOC_ATTRIBUTE_ID, 3);
|
|
||||||
translator->add(TRI_VOC_ATTRIBUTE_FROM, 4);
|
|
||||||
translator->add(TRI_VOC_ATTRIBUTE_TO, 5);
|
|
||||||
*/
|
|
||||||
translator->seal();
|
|
||||||
|
|
||||||
options.reset(new VPackOptions);
|
|
||||||
// options->attributeTranslator = translator.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
VPackAttributeTranslator* StorageOptions::getTranslator() {
|
|
||||||
return translator.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
VPackOptions* StorageOptions::getOptions() {
|
|
||||||
return options.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// global options used when converting JSON into a document
|
|
||||||
VPackOptions StorageOptions::JsonToDocumentTemplate;
|
|
||||||
// global options used when converting documents into JSON
|
|
||||||
VPackOptions StorageOptions::DocumentToJsonTemplate;
|
|
||||||
// global options used for other conversions
|
|
||||||
VPackOptions StorageOptions::NonDocumentTemplate;
|
|
||||||
|
|
||||||
struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
|
||||||
bool shouldExclude(VPackSlice const& key, int nesting) override final {
|
bool shouldExclude(VPackSlice const& key, int nesting) override final {
|
||||||
VPackValueLength keyLength;
|
VPackValueLength keyLength;
|
||||||
char const* p = key.getString(keyLength);
|
char const* p = key.getString(keyLength);
|
||||||
|
|
||||||
if (p == nullptr || *p != '_' || keyLength < 3 || keyLength > 5) {
|
if (p == nullptr || *p != '_' || keyLength < 3 || keyLength > 5 || nesting > 0) {
|
||||||
// keep attribute
|
// keep attribute
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((keyLength == 3 && memcmp(p, "_id", keyLength) == 0) ||
|
// exclude these attributes (but not _key!)
|
||||||
(keyLength == 4 && memcmp(p, "_rev", keyLength) == 0) ||
|
if ((keyLength == 3 && memcmp(p, TRI_VOC_ATTRIBUTE_ID, keyLength) == 0) ||
|
||||||
(keyLength == 3 && memcmp(p, "_to", keyLength) == 0) ||
|
(keyLength == 4 && memcmp(p, TRI_VOC_ATTRIBUTE_REV, keyLength) == 0) ||
|
||||||
(keyLength == 5 && memcmp(p, "_from", keyLength) == 0)) {
|
(keyLength == 3 && memcmp(p, TRI_VOC_ATTRIBUTE_TO, keyLength) == 0) ||
|
||||||
// exclude these attribute
|
(keyLength == 5 && memcmp(p, TRI_VOC_ATTRIBUTE_FROM, keyLength) == 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,14 +65,54 @@ struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
|
||||||
explicit CustomTypeHandlerImpl(
|
// custom type value handler, used for determining the length of the _id attribute
|
||||||
arangodb::CollectionNameResolver const* resolver)
|
struct CustomIdLengthHandler : public VPackCustomTypeHandler {
|
||||||
: resolver(resolver) {}
|
void toJson(VPackSlice const&, VPackDumper*,
|
||||||
|
VPackSlice const&) {
|
||||||
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackValueLength byteSize(VPackSlice const& value) {
|
||||||
|
if (value.head() != 0xf0) {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||||
|
"invalid custom type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// _id
|
||||||
|
return 1 + 8; // 0xf0 + 8 bytes for collection id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// custom type value handler, used for deciphering the _id attribute
|
||||||
|
struct CustomIdTypeHandler : public VPackCustomTypeHandler {
|
||||||
|
explicit CustomIdTypeHandler(TRI_vocbase_t* vocbase)
|
||||||
|
: vocbase(vocbase), resolver(nullptr), ownsResolver(false) {}
|
||||||
|
|
||||||
|
CustomIdTypeHandler(TRI_vocbase_t* vocbase, CollectionNameResolver* resolver)
|
||||||
|
: vocbase(vocbase), resolver(resolver), ownsResolver(false) {}
|
||||||
|
|
||||||
|
~CustomIdTypeHandler() {
|
||||||
|
if (ownsResolver) {
|
||||||
|
delete resolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CollectionNameResolver* getResolver() {
|
||||||
|
if (resolver == nullptr) {
|
||||||
|
resolver = new CollectionNameResolver(vocbase);
|
||||||
|
ownsResolver = true;
|
||||||
|
}
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
void toJson(VPackSlice const& value, VPackDumper* dumper,
|
void toJson(VPackSlice const& value, VPackDumper* dumper,
|
||||||
VPackSlice const& base) {
|
VPackSlice const& base) {
|
||||||
if (value.head() == 0xf0) {
|
if (value.head() != 0xf0) {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||||
|
"invalid custom type");
|
||||||
|
}
|
||||||
|
|
||||||
// _id
|
// _id
|
||||||
if (!base.isObject()) {
|
if (!base.isObject()) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||||
|
@ -111,7 +120,7 @@ struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
||||||
}
|
}
|
||||||
uint64_t cid = arangodb::velocypack::readUInt64(value.start() + 1);
|
uint64_t cid = arangodb::velocypack::readUInt64(value.start() + 1);
|
||||||
char buffer[512]; // This is enough for collection name + _key
|
char buffer[512]; // This is enough for collection name + _key
|
||||||
size_t len = resolver->getCollectionName(&buffer[0], cid);
|
size_t len = getResolver()->getCollectionName(&buffer[0], cid);
|
||||||
buffer[len] = '/';
|
buffer[len] = '/';
|
||||||
VPackSlice key = base.get(TRI_VOC_ATTRIBUTE_KEY);
|
VPackSlice key = base.get(TRI_VOC_ATTRIBUTE_KEY);
|
||||||
|
|
||||||
|
@ -123,62 +132,72 @@ struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
||||||
}
|
}
|
||||||
memcpy(&buffer[len + 1], p, keyLength);
|
memcpy(&buffer[len + 1], p, keyLength);
|
||||||
dumper->appendString(&buffer[0], len + 1 + keyLength);
|
dumper->appendString(&buffer[0], len + 1 + keyLength);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.head() == 0xf1) {
|
|
||||||
// _rev
|
|
||||||
dumper->sink()->push_back('"');
|
|
||||||
dumper->appendUInt(arangodb::velocypack::readUInt64(value.start() + 1));
|
|
||||||
dumper->sink()->push_back('"');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.head() == 0xf2) {
|
|
||||||
// _from, _to
|
|
||||||
// TODO
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw "unknown type!";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackValueLength byteSize(VPackSlice const& value) {
|
VPackValueLength byteSize(VPackSlice const& value) {
|
||||||
if (value.head() == 0xf0) {
|
if (value.head() != 0xf0) {
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||||
|
"invalid custom type");
|
||||||
|
}
|
||||||
|
|
||||||
// _id
|
// _id
|
||||||
return 1 + 8; // 0xf0 + 8 bytes for collection id
|
return 1 + 8; // 0xf0 + 8 bytes for collection id
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.head() == 0xf1) {
|
TRI_vocbase_t* vocbase;
|
||||||
// _rev
|
CollectionNameResolver* resolver;
|
||||||
return 1 + 8; // 0xf1 + 8 bytes for tick value
|
bool ownsResolver;
|
||||||
}
|
|
||||||
|
|
||||||
if (value.head() == 0xf2) {
|
|
||||||
// _from, _to
|
|
||||||
// TODO!!
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw "unknown type!";
|
|
||||||
}
|
|
||||||
|
|
||||||
arangodb::CollectionNameResolver const* resolver;
|
|
||||||
TRI_voc_cid_t cid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
StorageOptions::StorageOptions()
|
|
||||||
: _translator(new VPackAttributeTranslator),
|
// initialize global vpack options
|
||||||
_excludeHandler(new ExcludeHandlerImpl) {
|
void StorageOptions::initialize() {
|
||||||
|
// initialize translator
|
||||||
|
translator.reset(new VPackAttributeTranslator);
|
||||||
|
|
||||||
// these attribute names will be translated into short integer values
|
// these attribute names will be translated into short integer values
|
||||||
_translator->add(TRI_VOC_ATTRIBUTE_KEY, 1);
|
translator->add(TRI_VOC_ATTRIBUTE_KEY, 1);
|
||||||
_translator->add(TRI_VOC_ATTRIBUTE_REV, 2);
|
translator->add(TRI_VOC_ATTRIBUTE_REV, 2);
|
||||||
_translator->add(TRI_VOC_ATTRIBUTE_ID, 3);
|
translator->add(TRI_VOC_ATTRIBUTE_ID, 3);
|
||||||
_translator->add(TRI_VOC_ATTRIBUTE_FROM, 4);
|
translator->add(TRI_VOC_ATTRIBUTE_FROM, 4);
|
||||||
_translator->add(TRI_VOC_ATTRIBUTE_TO, 5);
|
translator->add(TRI_VOC_ATTRIBUTE_TO, 5);
|
||||||
|
|
||||||
_translator->seal();
|
translator->seal();
|
||||||
|
|
||||||
|
// initialize system attribute exclude handler
|
||||||
|
excludeHandler.reset(new SystemAttributeExcludeHandler);
|
||||||
|
|
||||||
|
customLengthHandler.reset(new CustomIdLengthHandler);
|
||||||
|
|
||||||
|
// initialize default options
|
||||||
|
defaultOptions.reset(new VPackOptions);
|
||||||
|
defaultOptions->attributeTranslator = nullptr;
|
||||||
|
defaultOptions->customTypeHandler = nullptr;
|
||||||
|
|
||||||
|
// initialize options for inserting documents
|
||||||
|
insertOptions.reset(new VPackOptions);
|
||||||
|
insertOptions->buildUnindexedArrays = false;
|
||||||
|
insertOptions->buildUnindexedObjects = false;
|
||||||
|
insertOptions->checkAttributeUniqueness = true;
|
||||||
|
insertOptions->sortAttributeNames = true;
|
||||||
|
insertOptions->attributeTranslator = translator.get();
|
||||||
|
insertOptions->customTypeHandler = customLengthHandler.get();
|
||||||
|
insertOptions->attributeExcludeHandler = excludeHandler.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackAttributeTranslator const* StorageOptions::getTranslator() {
|
||||||
|
return translator.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackOptions const* StorageOptions::getDefaultOptions() {
|
||||||
|
return defaultOptions.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackOptions const* StorageOptions::getInsertOptions() {
|
||||||
|
return insertOptions.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// set options for JSON to document conversion
|
// set options for JSON to document conversion
|
||||||
JsonToDocumentTemplate.buildUnindexedArrays = false;
|
JsonToDocumentTemplate.buildUnindexedArrays = false;
|
||||||
JsonToDocumentTemplate.buildUnindexedObjects = false;
|
JsonToDocumentTemplate.buildUnindexedObjects = false;
|
||||||
|
@ -209,24 +228,4 @@ StorageOptions::StorageOptions()
|
||||||
NonDocumentTemplate.escapeForwardSlashes = true;
|
NonDocumentTemplate.escapeForwardSlashes = true;
|
||||||
NonDocumentTemplate.unsupportedTypeBehavior =
|
NonDocumentTemplate.unsupportedTypeBehavior =
|
||||||
VPackOptions::FailOnUnsupportedType;
|
VPackOptions::FailOnUnsupportedType;
|
||||||
}
|
|
||||||
|
|
||||||
StorageOptions::~StorageOptions() {}
|
|
||||||
|
|
||||||
VPackOptions StorageOptions::getDocumentToJsonTemplate() {
|
|
||||||
return DocumentToJsonTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
VPackOptions StorageOptions::getJsonToDocumentTemplate() {
|
|
||||||
return JsonToDocumentTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
VPackOptions StorageOptions::getNonDocumentTemplate() {
|
|
||||||
return NonDocumentTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
VPackCustomTypeHandler* StorageOptions::createCustomHandler(
|
|
||||||
arangodb::CollectionNameResolver const* resolver) {
|
|
||||||
return new CustomTypeHandlerImpl(resolver);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,14 +35,9 @@ namespace arangodb {
|
||||||
namespace StorageOptions {
|
namespace StorageOptions {
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
VPackAttributeTranslator* getTranslator();
|
VPackAttributeTranslator const* getTranslator();
|
||||||
VPackOptions* getOptions();
|
VPackOptions const* getDefaultOptions();
|
||||||
|
VPackOptions const* getInsertOptions();
|
||||||
VPackOptions* getDocumentToJsonTemplate();
|
|
||||||
VPackOptions* getJsonToDocumentTemplate();
|
|
||||||
VPackOptions* getNonDocumentTemplate();
|
|
||||||
// VPackCustomTypeHandler* createCustomHandler(
|
|
||||||
// arangodb::CollectionNameResolver const*);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,26 +185,6 @@ class Transaction {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the vpack options
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
VPackOptions const* vpackOptions() const {
|
|
||||||
VPackOptions const* o = this->_transactionContext->getVPackOptions();
|
|
||||||
TRI_ASSERT(o != nullptr);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return a copy of the vpack options
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
VPackOptions copyVPackOptions() const {
|
|
||||||
VPackOptions const* o = this->_transactionContext->getVPackOptions();
|
|
||||||
TRI_ASSERT(o != nullptr);
|
|
||||||
return *o;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief whether or not the transaction is embedded
|
/// @brief whether or not the transaction is embedded
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -38,10 +38,3 @@ TransactionContext::TransactionContext() {}
|
||||||
|
|
||||||
TransactionContext::~TransactionContext() {}
|
TransactionContext::~TransactionContext() {}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the vpack options
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
VPackOptions const* TransactionContext::getVPackOptions() const {
|
|
||||||
return StorageOptions::getOptions();
|
|
||||||
}
|
|
||||||
|
|
|
@ -84,12 +84,6 @@ class TransactionContext {
|
||||||
|
|
||||||
virtual int unregisterTransaction() = 0;
|
virtual int unregisterTransaction() = 0;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the vpack options
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
VPackOptions const* getVPackOptions() const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ static int const SLOT_DITCH = 2;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static inline VPackSlice VPackFromMarker(TRI_df_marker_t const* marker) {
|
static inline VPackSlice VPackFromMarker(TRI_df_marker_t const* marker) {
|
||||||
return VPackSlice(reinterpret_cast<uint8_t const*>(marker) + sizeof(TRI_df_marker_t) + 24); // TODO: remove hard-coded value
|
uint8_t const* ptr = reinterpret_cast<uint8_t const*>(marker) + sizeof(TRI_df_marker_t) + 24; // TODO: remove hard-coded value
|
||||||
|
return VPackSlice(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -108,7 +109,7 @@ static void CopyAttributes(v8::Isolate* isolate, v8::Handle<v8::Object> self,
|
||||||
TRI_df_marker_t const* marker,
|
TRI_df_marker_t const* marker,
|
||||||
char const* excludeAttribute = nullptr) {
|
char const* excludeAttribute = nullptr) {
|
||||||
|
|
||||||
VPackSlice slice(VPackFromMarker(marker));
|
auto slice = VPackFromMarker(marker);
|
||||||
|
|
||||||
VPackObjectIterator it(slice);
|
VPackObjectIterator it(slice);
|
||||||
while (it.valid()) {
|
while (it.valid()) {
|
||||||
|
@ -143,7 +144,7 @@ static void KeysOfVPack(v8::PropertyCallbackInfo<v8::Array> const& args) {
|
||||||
TRI_V8_RETURN(v8::Array::New(isolate));
|
TRI_V8_RETURN(v8::Array::New(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackSlice slice(VPackFromMarker(marker));
|
auto slice = VPackFromMarker(marker);
|
||||||
std::vector<std::string> keys(VPackCollection::keys(slice));
|
std::vector<std::string> keys(VPackCollection::keys(slice));
|
||||||
|
|
||||||
v8::Handle<v8::Array> result = v8::Array::New(isolate, static_cast<int>(keys.size()));
|
v8::Handle<v8::Array> result = v8::Array::New(isolate, static_cast<int>(keys.size()));
|
||||||
|
@ -190,7 +191,7 @@ static void MapGetNamedVPack(
|
||||||
TRI_V8_RETURN(v8::Handle<v8::Value>());
|
TRI_V8_RETURN(v8::Handle<v8::Value>());
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackSlice slice(VPackFromMarker(marker));
|
auto slice = VPackFromMarker(marker);
|
||||||
|
|
||||||
TRI_V8_RETURN(TRI_VPackToV8(isolate, slice.get(key)));
|
TRI_V8_RETURN(TRI_VPackToV8(isolate, slice.get(key)));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -322,7 +323,7 @@ static void PropertyQueryVPack(
|
||||||
TRI_V8_RETURN(v8::Handle<v8::Integer>());
|
TRI_V8_RETURN(v8::Handle<v8::Integer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackSlice slice(VPackFromMarker(marker));
|
auto slice = VPackFromMarker(marker);
|
||||||
|
|
||||||
if (!slice.hasKey(key)) {
|
if (!slice.hasKey(key)) {
|
||||||
// key not found
|
// key not found
|
||||||
|
|
|
@ -1069,11 +1069,11 @@ static int AddSystemAttributes(Transaction* trx, TRI_voc_cid_t cid,
|
||||||
TRI_document_collection_t* document,
|
TRI_document_collection_t* document,
|
||||||
VPackBuilder& builder) {
|
VPackBuilder& builder) {
|
||||||
// generate a new tick value
|
// generate a new tick value
|
||||||
uint64_t const tick = TRI_NewTickServer();
|
TRI_voc_tick_t const tick = TRI_NewTickServer();
|
||||||
|
|
||||||
if (!builder.hasKey(TRI_VOC_ATTRIBUTE_KEY)) {
|
if (!builder.hasKey(TRI_VOC_ATTRIBUTE_KEY)) {
|
||||||
// "_key" attribute not present in object
|
// "_key" attribute not present in object
|
||||||
std::string const keyString = document->_keyGenerator->generate(tick);
|
std::string keyString = document->_keyGenerator->generate(tick);
|
||||||
builder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(keyString));
|
builder.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(keyString));
|
||||||
} else {
|
} else {
|
||||||
// "_key" attribute is present in object
|
// "_key" attribute is present in object
|
||||||
|
@ -1090,19 +1090,16 @@ static int AddSystemAttributes(Transaction* trx, TRI_voc_cid_t cid,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// now add _id attribute
|
// add _id attribute
|
||||||
uint8_t* p = builder.add(TRI_VOC_ATTRIBUTE_ID,
|
uint8_t* p = builder.add(TRI_VOC_ATTRIBUTE_ID,
|
||||||
VPackValuePair(9ULL, VPackValueType::Custom));
|
VPackValuePair(9ULL, VPackValueType::Custom));
|
||||||
*p++ = 0xf0;
|
*p++ = 0xf0;
|
||||||
arangodb::velocypack::storeUInt64(p, cid);
|
arangodb::velocypack::storeUInt64(p, cid);
|
||||||
|
|
||||||
// now add _rev attribute
|
// add _rev attribute
|
||||||
p = builder.add(TRI_VOC_ATTRIBUTE_REV,
|
builder.add(TRI_VOC_ATTRIBUTE_REV, VPackValue(std::to_string(tick)));
|
||||||
VPackValuePair(9ULL, VPackValueType::Custom));
|
|
||||||
*p++ = 0xf1;
|
|
||||||
arangodb::velocypack::storeUInt64(p, tick);
|
|
||||||
*/
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,6 +1234,8 @@ static void InsertVocbaseVPack(
|
||||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VPackOptions const* vpackOptions = StorageOptions::getInsertOptions();
|
||||||
|
|
||||||
// load collection
|
// load collection
|
||||||
SingleCollectionWriteTransaction<1> trx(new V8TransactionContext(true),
|
SingleCollectionWriteTransaction<1> trx(new V8TransactionContext(true),
|
||||||
col->_vocbase, col->_cid);
|
col->_vocbase, col->_cid);
|
||||||
|
@ -1247,7 +1246,7 @@ static void InsertVocbaseVPack(
|
||||||
TRI_V8_THROW_EXCEPTION(res);
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackBuilder builder(trx.vpackOptions());
|
VPackBuilder builder(vpackOptions);
|
||||||
res = TRI_V8ToVPack(isolate, builder, args[0]->ToObject(), true);
|
res = TRI_V8ToVPack(isolate, builder, args[0]->ToObject(), true);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -1257,8 +1256,7 @@ static void InsertVocbaseVPack(
|
||||||
TRI_document_collection_t* document = trx.documentCollection();
|
TRI_document_collection_t* document = trx.documentCollection();
|
||||||
|
|
||||||
// the AddSystemAttributes() needs the collection already loaded because it
|
// the AddSystemAttributes() needs the collection already loaded because it
|
||||||
// references the
|
// references the collection's key generator
|
||||||
// collection's key generator
|
|
||||||
res = AddSystemAttributes(&trx, col->_cid, document, builder);
|
res = AddSystemAttributes(&trx, col->_cid, document, builder);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -1298,18 +1296,13 @@ static void InsertVocbaseVPack(
|
||||||
TRI_V8_RETURN_TRUE();
|
TRI_V8_RETURN_TRUE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VPackSlice vpack(mptr.vpack());
|
||||||
std::string key = VPackSlice(mptr.vpack()).get(TRI_VOC_ATTRIBUTE_KEY).copyString();
|
std::string key = VPackSlice(mptr.vpack()).get(TRI_VOC_ATTRIBUTE_KEY).copyString();
|
||||||
|
|
||||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||||
TRI_GET_GLOBAL_STRING(_IdKey);
|
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_ID), V8DocumentId(isolate, trx.resolver()->getCollectionName(col->_cid), key));
|
||||||
TRI_GET_GLOBAL_STRING(_RevKey);
|
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_REV), TRI_V8_STD_STRING(vpack.get(TRI_VOC_ATTRIBUTE_REV).copyString()));
|
||||||
TRI_GET_GLOBAL_STRING(_KeyKey);
|
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_KEY), TRI_V8_STD_STRING(key));
|
||||||
result->Set(
|
|
||||||
_IdKey,
|
|
||||||
V8DocumentId(isolate, trx.resolver()->getCollectionName(col->_cid), key));
|
|
||||||
// result->Set(_RevKey,
|
|
||||||
// V8RevisionId(isolate, TRI_EXTRACT_MARKER_RID(&trx, &mptr)));
|
|
||||||
result->Set(_KeyKey, TRI_V8_STD_STRING(key));
|
|
||||||
|
|
||||||
TRI_V8_RETURN(result);
|
TRI_V8_RETURN(result);
|
||||||
}
|
}
|
||||||
|
@ -1844,9 +1837,7 @@ static void RemoveVocbaseVPack(
|
||||||
TRI_V8_THROW_EXCEPTION(res);
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackOptions vpackOptions = trx.copyVPackOptions();
|
VPackBuilder builder(StorageOptions::getDefaultOptions());
|
||||||
vpackOptions.attributeExcludeHandler = nullptr;
|
|
||||||
VPackBuilder builder(&vpackOptions);
|
|
||||||
|
|
||||||
builder.add(VPackValue(VPackValueType::Object));
|
builder.add(VPackValue(VPackValueType::Object));
|
||||||
builder.add(TRI_VOC_ATTRIBUTE_KEY,
|
builder.add(TRI_VOC_ATTRIBUTE_KEY,
|
||||||
|
|
|
@ -914,8 +914,6 @@ static void JS_AllQuery(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
for (uint64_t i = 0; i < n; ++i) {
|
for (uint64_t i = 0; i < n; ++i) {
|
||||||
v8::Handle<v8::Value> doc = V8VPackWrapper::wrap(isolate, &trx, cid, ditch, static_cast<TRI_df_marker_t const*>(docs[i].getDataPtr()));
|
v8::Handle<v8::Value> doc = V8VPackWrapper::wrap(isolate, &trx, cid, ditch, static_cast<TRI_df_marker_t const*>(docs[i].getDataPtr()));
|
||||||
// v8::Handle<v8::Value> doc = TRI_VPackToV8(isolate, VPackSlice(docs[i].vpack()));
|
|
||||||
// WRAP_SHAPED_JSON(trx, col->_cid, docs[i].getDataPtr());
|
|
||||||
|
|
||||||
if (doc.IsEmpty()) {
|
if (doc.IsEmpty()) {
|
||||||
TRI_V8_THROW_EXCEPTION_MEMORY();
|
TRI_V8_THROW_EXCEPTION_MEMORY();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "Basics/JsonHelper.h"
|
#include "Basics/JsonHelper.h"
|
||||||
|
#include "Storage/Options.h"
|
||||||
#include "Utils/Transaction.h"
|
#include "Utils/Transaction.h"
|
||||||
#include "VocBase/document-collection.h"
|
#include "VocBase/document-collection.h"
|
||||||
#include "VocBase/shape-accessor.h"
|
#include "VocBase/shape-accessor.h"
|
||||||
|
@ -102,7 +103,7 @@ static inline std::string TRI_EXTRACT_MARKER_KEY(
|
||||||
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
||||||
auto b = reinterpret_cast<char const*>(marker) +
|
auto b = reinterpret_cast<char const*>(marker) +
|
||||||
sizeof(arangodb::wal::vpack_document_marker_t);
|
sizeof(arangodb::wal::vpack_document_marker_t);
|
||||||
VPackSlice slice(reinterpret_cast<uint8_t const*>(b), trx->vpackOptions());
|
VPackSlice slice(reinterpret_cast<uint8_t const*>(b));
|
||||||
return slice.get(TRI_VOC_ATTRIBUTE_KEY).copyString();
|
return slice.get(TRI_VOC_ATTRIBUTE_KEY).copyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ static inline TRI_voc_rid_t TRI_EXTRACT_MARKER_RID(
|
||||||
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
||||||
auto b = reinterpret_cast<char const*>(marker) +
|
auto b = reinterpret_cast<char const*>(marker) +
|
||||||
sizeof(arangodb::wal::vpack_document_marker_t);
|
sizeof(arangodb::wal::vpack_document_marker_t);
|
||||||
VPackSlice slice(reinterpret_cast<uint8_t const*>(b), trx->vpackOptions());
|
VPackSlice slice(reinterpret_cast<uint8_t const*>(b));
|
||||||
VPackSlice value = slice.get(TRI_VOC_ATTRIBUTE_REV);
|
VPackSlice value = slice.get(TRI_VOC_ATTRIBUTE_REV);
|
||||||
return arangodb::velocypack::readUInt64(value.start() + 1);
|
return arangodb::velocypack::readUInt64(value.start() + 1);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +169,7 @@ static inline bool TRI_MATCHES_MARKER_KEY(arangodb::Transaction* trx,
|
||||||
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
||||||
auto b = reinterpret_cast<char const*>(marker) +
|
auto b = reinterpret_cast<char const*>(marker) +
|
||||||
sizeof(arangodb::wal::vpack_document_marker_t);
|
sizeof(arangodb::wal::vpack_document_marker_t);
|
||||||
VPackSlice slice(reinterpret_cast<uint8_t const*>(b), trx->vpackOptions());
|
VPackSlice slice(reinterpret_cast<uint8_t const*>(b));
|
||||||
VPackValueLength len;
|
VPackValueLength len;
|
||||||
char const* p = slice.get(TRI_VOC_ATTRIBUTE_KEY).getString(len);
|
char const* p = slice.get(TRI_VOC_ATTRIBUTE_KEY).getString(len);
|
||||||
if (len != strlen(key)) {
|
if (len != strlen(key)) {
|
||||||
|
@ -198,13 +199,13 @@ static inline bool TRI_MATCHES_MARKER_KEY(arangodb::Transaction* trx,
|
||||||
rm->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
rm->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
||||||
auto lb = reinterpret_cast<char const*>(lm) +
|
auto lb = reinterpret_cast<char const*>(lm) +
|
||||||
sizeof(arangodb::wal::vpack_document_marker_t);
|
sizeof(arangodb::wal::vpack_document_marker_t);
|
||||||
VPackSlice ls(reinterpret_cast<uint8_t const*>(lb), trx->vpackOptions());
|
VPackSlice ls(reinterpret_cast<uint8_t const*>(lb));
|
||||||
VPackValueLength llen;
|
VPackValueLength llen;
|
||||||
char const* p = ls.get(TRI_VOC_ATTRIBUTE_KEY).getString(llen);
|
char const* p = ls.get(TRI_VOC_ATTRIBUTE_KEY).getString(llen);
|
||||||
|
|
||||||
auto rb = reinterpret_cast<char const*>(rm) +
|
auto rb = reinterpret_cast<char const*>(rm) +
|
||||||
sizeof(arangodb::wal::vpack_document_marker_t);
|
sizeof(arangodb::wal::vpack_document_marker_t);
|
||||||
VPackSlice rs(reinterpret_cast<uint8_t const*>(rb), trx->vpackOptions());
|
VPackSlice rs(reinterpret_cast<uint8_t const*>(rb));
|
||||||
VPackValueLength rlen;
|
VPackValueLength rlen;
|
||||||
char const* q = rs.get(TRI_VOC_ATTRIBUTE_KEY).getString(rlen);
|
char const* q = rs.get(TRI_VOC_ATTRIBUTE_KEY).getString(rlen);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue