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 "velocypack/velocypack-common.h"
|
||||
#include "velocypack/Slice.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
|
@ -71,6 +72,30 @@ class AttributeTranslator {
|
|||
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
|
||||
|
||||
|
|
|
@ -115,20 +115,16 @@ class Builder {
|
|||
// 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,
|
||||
Options const*);
|
||||
static uint8_t const* findAttrName(uint8_t const* base, uint64_t& len);
|
||||
|
||||
static void sortObjectIndexShort(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const*);
|
||||
std::vector<ValueLength>& offsets);
|
||||
|
||||
static void sortObjectIndexLong(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const*);
|
||||
std::vector<ValueLength>& offsets);
|
||||
|
||||
static void sortObjectIndex(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const*);
|
||||
std::vector<ValueLength>& offsets);
|
||||
|
||||
public:
|
||||
Options const* options;
|
||||
|
@ -301,7 +297,7 @@ class Builder {
|
|||
if (isEmpty()) {
|
||||
return Slice();
|
||||
}
|
||||
return Slice(start(), options);
|
||||
return Slice(start());
|
||||
}
|
||||
|
||||
// Compute the actual size here, but only when sealed
|
||||
|
|
|
@ -71,7 +71,7 @@ class ArrayIterator {
|
|||
ArrayIterator& operator++() {
|
||||
++_position;
|
||||
if (_position <= _size && _current != nullptr) {
|
||||
_current += Slice(_current, _slice.options).byteSize();
|
||||
_current += Slice(_current).byteSize();
|
||||
} else {
|
||||
_current = nullptr;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ class ArrayIterator {
|
|||
|
||||
Slice operator*() const {
|
||||
if (_current != nullptr) {
|
||||
return Slice(_current, _slice.options);
|
||||
return Slice(_current);
|
||||
}
|
||||
return _slice.at(_position);
|
||||
}
|
||||
|
@ -181,9 +181,9 @@ class ObjectIterator {
|
|||
++_position;
|
||||
if (_position <= _size && _current != nullptr) {
|
||||
// skip over key
|
||||
_current += Slice(_current, _slice.options).byteSize();
|
||||
_current += Slice(_current).byteSize();
|
||||
// skip over value
|
||||
_current += Slice(_current, _slice.options).byteSize();
|
||||
_current += Slice(_current).byteSize();
|
||||
} else {
|
||||
_current = nullptr;
|
||||
}
|
||||
|
@ -203,8 +203,8 @@ class ObjectIterator {
|
|||
|
||||
ObjectPair operator*() const {
|
||||
if (_current != nullptr) {
|
||||
Slice key = Slice(_current, _slice.options);
|
||||
return ObjectPair(key, Slice(_current + key.byteSize(), _slice.options));
|
||||
Slice key = Slice(_current);
|
||||
return ObjectPair(key, Slice(_current + key.byteSize()));
|
||||
}
|
||||
return ObjectPair(_slice.keyAt(_position), _slice.valueAt(_position));
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ class ObjectIterator {
|
|||
throw Exception(Exception::IndexOutOfBounds);
|
||||
}
|
||||
if (_current != nullptr) {
|
||||
return Slice(_current, _slice.options);
|
||||
return Slice(_current);
|
||||
}
|
||||
return _slice.keyAt(_position);
|
||||
}
|
||||
|
@ -242,8 +242,8 @@ class ObjectIterator {
|
|||
throw Exception(Exception::IndexOutOfBounds);
|
||||
}
|
||||
if (_current != nullptr) {
|
||||
Slice key = Slice(_current, _slice.options);
|
||||
return Slice(_current + key.byteSize(), _slice.options);
|
||||
Slice key = Slice(_current);
|
||||
return Slice(_current + key.byteSize());
|
||||
}
|
||||
return _slice.valueAt(_position);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ struct CustomTypeHandler {
|
|||
|
||||
virtual void toJson(Slice const& value, Dumper* dumper,
|
||||
Slice const& base) = 0;
|
||||
virtual ValueLength byteSize(Slice const& value) = 0;
|
||||
};
|
||||
|
||||
struct Options {
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace velocypack {
|
|||
// forward for fasthash64 function declared elsewhere
|
||||
uint64_t fasthash64(void const*, size_t, uint64_t);
|
||||
|
||||
class AttributeTranslator;
|
||||
class SliceScope;
|
||||
|
||||
class Slice {
|
||||
|
@ -59,43 +60,17 @@ class Slice {
|
|||
uint8_t const* _start;
|
||||
|
||||
public:
|
||||
Options const* options;
|
||||
|
||||
static AttributeTranslator* attributeTranslator;
|
||||
|
||||
// constructor for an empty Value of type None
|
||||
Slice() : Slice("\x00", &Options::Defaults) {}
|
||||
Slice() : Slice("\x00") {}
|
||||
|
||||
explicit Slice(uint8_t const* start,
|
||||
Options const* options = &Options::Defaults)
|
||||
: _start(start), options(options) {
|
||||
VELOCYPACK_ASSERT(options != nullptr);
|
||||
}
|
||||
explicit Slice(uint8_t const* start)
|
||||
: _start(start) {}
|
||||
|
||||
explicit Slice(char const* start, Options const* options = &Options::Defaults)
|
||||
: _start(reinterpret_cast<uint8_t const*>(start)), options(options) {
|
||||
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;
|
||||
}
|
||||
explicit Slice(char const* start)
|
||||
: _start(reinterpret_cast<uint8_t const*>(start)) {}
|
||||
|
||||
// creates a Slice from Json and adds it to a scope
|
||||
static Slice fromJson(SliceScope& scope, std::string const& json,
|
||||
|
@ -281,7 +256,7 @@ class Slice {
|
|||
// find number of items
|
||||
if (h <= 0x05) { // No offset table or length, need to compute:
|
||||
ValueLength firstSubOffset = findDataOffset(h);
|
||||
Slice first(_start + firstSubOffset, options);
|
||||
Slice first(_start + firstSubOffset);
|
||||
return (end - firstSubOffset) / first.byteSize();
|
||||
} else if (offsetSize < 8) {
|
||||
return readInteger<ValueLength>(_start + offsetSize + 1, offsetSize);
|
||||
|
@ -322,7 +297,7 @@ class Slice {
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -334,7 +309,7 @@ class Slice {
|
|||
}
|
||||
|
||||
// use ourselves as the starting point
|
||||
Slice last = Slice(start(), options);
|
||||
Slice last = Slice(start());
|
||||
for (size_t i = 0; i < attributes.size(); ++i) {
|
||||
// fetch subattribute
|
||||
last = last.get(attributes[i]);
|
||||
|
@ -636,11 +611,41 @@ class Slice {
|
|||
}
|
||||
|
||||
case ValueType::Custom: {
|
||||
if (options->customTypeHandler == nullptr) {
|
||||
throw Exception(Exception::NeedCustomTypeHandler);
|
||||
}
|
||||
auto const h = head();
|
||||
switch (h) {
|
||||
case 0xf0: return 1 + 1;
|
||||
case 0xf1: return 1 + 2;
|
||||
case 0xf2: return 1 + 4;
|
||||
case 0xf3: return 1 + 8;
|
||||
|
||||
return options->customTypeHandler->byteSize(*this);
|
||||
case 0xf4:
|
||||
case 0xf5:
|
||||
case 0xf6: {
|
||||
return 1 + readInteger<ValueLength>(_start + 1, 1);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
std::string toJson() const;
|
||||
std::string toString() const;
|
||||
std::string toJson(Options const* options = &Options::Defaults) const;
|
||||
std::string toString(Options const* options = &Options::Defaults) const;
|
||||
std::string hexType() const;
|
||||
|
||||
private:
|
||||
|
@ -743,8 +748,7 @@ class SliceScope {
|
|||
SliceScope();
|
||||
~SliceScope();
|
||||
|
||||
Slice add(uint8_t const* data, ValueLength size,
|
||||
Options const* options = &Options::Defaults);
|
||||
Slice add(uint8_t const* data, ValueLength size);
|
||||
|
||||
private:
|
||||
std::vector<uint8_t*> _allocations;
|
||||
|
|
|
@ -118,7 +118,7 @@ class SliceContainer {
|
|||
if (_data == nullptr) {
|
||||
return Slice();
|
||||
}
|
||||
return Slice(_data, &Options::Defaults);
|
||||
return Slice(_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,
|
||||
Options const* options) {
|
||||
uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len) {
|
||||
uint8_t const b = *base;
|
||||
if (b >= 0x40 && b <= 0xbe) {
|
||||
// short UTF-8 string
|
||||
|
@ -86,13 +85,11 @@ uint8_t const* Builder::findAttrName(uint8_t const* base, uint64_t& len,
|
|||
}
|
||||
|
||||
// translate attribute name
|
||||
Slice s(base, options);
|
||||
return findAttrName(s.makeKey().start(), len, options);
|
||||
return findAttrName(Slice(base).makeKey().start(), len);
|
||||
}
|
||||
|
||||
void Builder::sortObjectIndexShort(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const* options) {
|
||||
std::vector<ValueLength>& offsets) {
|
||||
auto cmp = [&](ValueLength a, ValueLength b) -> bool {
|
||||
uint8_t const* aa = objBase + a;
|
||||
uint8_t const* bb = objBase + b;
|
||||
|
@ -104,8 +101,8 @@ void Builder::sortObjectIndexShort(uint8_t* objBase,
|
|||
} else {
|
||||
uint64_t lena;
|
||||
uint64_t lenb;
|
||||
aa = findAttrName(aa, lena, options);
|
||||
bb = findAttrName(bb, lenb, options);
|
||||
aa = findAttrName(aa, lena);
|
||||
bb = findAttrName(bb, lenb);
|
||||
uint64_t m = (std::min)(lena, lenb);
|
||||
int c = memcmp(aa, bb, checkOverflow(m));
|
||||
return (c < 0 || (c == 0 && lena < lenb));
|
||||
|
@ -115,8 +112,7 @@ void Builder::sortObjectIndexShort(uint8_t* objBase,
|
|||
}
|
||||
|
||||
void Builder::sortObjectIndexLong(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const* options) {
|
||||
std::vector<ValueLength>& offsets) {
|
||||
// on some platforms we can use a thread-local vector
|
||||
#if __llvm__ == 1
|
||||
// nono thread local
|
||||
|
@ -134,7 +130,7 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
|||
for (size_t i = 0; i < n; i++) {
|
||||
SortEntry e;
|
||||
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);
|
||||
}
|
||||
VELOCYPACK_ASSERT(entries.size() == n);
|
||||
|
@ -147,12 +143,11 @@ void Builder::sortObjectIndexLong(uint8_t* objBase,
|
|||
}
|
||||
|
||||
void Builder::sortObjectIndex(uint8_t* objBase,
|
||||
std::vector<ValueLength>& offsets,
|
||||
Options const* options) {
|
||||
std::vector<ValueLength>& offsets) {
|
||||
if (offsets.size() > 32) {
|
||||
sortObjectIndexLong(objBase, offsets, options);
|
||||
sortObjectIndexLong(objBase, offsets);
|
||||
} else {
|
||||
sortObjectIndexShort(objBase, offsets, options);
|
||||
sortObjectIndexShort(objBase, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +320,7 @@ Builder& Builder::close() {
|
|||
if (!options->sortAttributeNames) {
|
||||
_start[tos] = 0x0f; // unsorted
|
||||
} 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++) {
|
||||
|
@ -373,7 +368,7 @@ Builder& Builder::close() {
|
|||
if (options->checkAttributeUniqueness && index.size() > 1 &&
|
||||
_start[tos] >= 0x0b) {
|
||||
// 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
|
||||
|
@ -397,7 +392,7 @@ bool Builder::hasKey(std::string const& key) const {
|
|||
return false;
|
||||
}
|
||||
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)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -419,9 +414,9 @@ Slice Builder::getKey(std::string const& key) const {
|
|||
return Slice();
|
||||
}
|
||||
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)) {
|
||||
return Slice(s.start() + s.byteSize(), options);
|
||||
return Slice(s.start() + s.byteSize());
|
||||
}
|
||||
}
|
||||
return Slice();
|
||||
|
|
|
@ -391,7 +391,7 @@ void Dumper::dumpValue(Slice const* slice, Slice const* base) {
|
|||
}
|
||||
|
||||
case ValueType::External: {
|
||||
Slice const external(slice->getExternal(), slice->options);
|
||||
Slice const external(slice->getExternal());
|
||||
dumpValue(&external, base);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -478,14 +478,14 @@ void Parser::parseObject() {
|
|||
} else {
|
||||
parseString();
|
||||
if (options->attributeExcludeHandler->shouldExclude(
|
||||
Slice(_b->_start + lastPos, options), _nesting)) {
|
||||
Slice(_b->_start + lastPos), _nesting)) {
|
||||
excludeAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!excludeAttribute && options->attributeTranslator != nullptr) {
|
||||
// check if a translation for the attribute name exists
|
||||
Slice key(_b->_start + lastPos, options);
|
||||
Slice key(_b->_start + lastPos);
|
||||
|
||||
if (key.isString()) {
|
||||
ValueLength keyLength;
|
||||
|
@ -498,7 +498,7 @@ void Parser::parseObject() {
|
|||
// and simply overwrite the existing key with the numeric translation
|
||||
// id
|
||||
_b->_pos = lastPos;
|
||||
_b->addUInt(Slice(translated, options).getUInt());
|
||||
_b->addUInt(Slice(translated).getUInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
using namespace arangodb::velocypack;
|
||||
using VT = arangodb::velocypack::ValueType;
|
||||
|
||||
AttributeTranslator* Slice::attributeTranslator = nullptr;
|
||||
|
||||
VT const Slice::TypeMap[256] = {
|
||||
/* 0x00 */ VT::None, /* 0x01 */ VT::Array,
|
||||
|
@ -220,7 +222,7 @@ Slice Slice::fromJson(SliceScope& scope, std::string const& json,
|
|||
parser.parse(json);
|
||||
|
||||
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
|
||||
|
@ -230,12 +232,11 @@ Slice Slice::translate() const {
|
|||
"Cannot translate key of this type");
|
||||
}
|
||||
uint64_t id = getUInt();
|
||||
|
||||
if (options->attributeTranslator == nullptr) {
|
||||
if (attributeTranslator == nullptr) {
|
||||
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
|
||||
|
@ -254,7 +255,7 @@ bool Slice::equals(Slice const& other) const {
|
|||
arangodb::velocypack::checkOverflow(size)) == 0);
|
||||
}
|
||||
|
||||
std::string Slice::toJson() const {
|
||||
std::string Slice::toJson(Options const* options) const {
|
||||
std::string buffer;
|
||||
StringSink sink(&buffer);
|
||||
Dumper dumper(&sink, options);
|
||||
|
@ -262,7 +263,7 @@ std::string Slice::toJson() const {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
std::string Slice::toString() const {
|
||||
std::string Slice::toString(Options const* options) const {
|
||||
// copy options and set prettyPrint in copy
|
||||
Options prettyOptions = *options;
|
||||
prettyOptions.prettyPrint = true;
|
||||
|
@ -311,16 +312,16 @@ Slice Slice::get(std::string const& attribute) const {
|
|||
dataOffset = findDataOffset(h);
|
||||
}
|
||||
|
||||
Slice key = Slice(_start + dataOffset, options);
|
||||
Slice key = Slice(_start + dataOffset);
|
||||
|
||||
if (key.isString() && key.isEqualString(attribute)) {
|
||||
return Slice(key.start() + key.byteSize(), options);
|
||||
return Slice(key.start() + key.byteSize());
|
||||
}
|
||||
|
||||
if (key.isSmallInt() || key.isUInt()) {
|
||||
// translate key
|
||||
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()) {
|
||||
Slice key = it.key();
|
||||
if (key.makeKey().isEqualString(attribute)) {
|
||||
return Slice(key.start() + key.byteSize(), options);
|
||||
return Slice(key.start() + key.byteSize());
|
||||
}
|
||||
|
||||
it.next();
|
||||
|
@ -493,7 +494,7 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
|||
// find the number of items
|
||||
ValueLength n;
|
||||
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();
|
||||
} else if (offsetSize < 8) {
|
||||
n = readInteger<ValueLength>(_start + 1 + offsetSize, offsetSize);
|
||||
|
@ -514,8 +515,7 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
|||
if (dataOffset == 0) {
|
||||
dataOffset = findDataOffset(h);
|
||||
}
|
||||
Slice firstItem(_start + dataOffset, options);
|
||||
return dataOffset + index * firstItem.byteSize();
|
||||
return dataOffset + index * Slice(_start + dataOffset).byteSize();
|
||||
}
|
||||
|
||||
ValueLength const ieBase =
|
||||
|
@ -527,14 +527,14 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
|
|||
Slice Slice::getNth(ValueLength index) const {
|
||||
VELOCYPACK_ASSERT(type() == ValueType::Array);
|
||||
|
||||
return Slice(_start + getNthOffset(index), options);
|
||||
return Slice(_start + getNthOffset(index));
|
||||
}
|
||||
|
||||
// extract the nth member from an Object
|
||||
Slice Slice::getNthKey(ValueLength index, bool translate) const {
|
||||
VELOCYPACK_ASSERT(type() == ValueType::Object);
|
||||
|
||||
Slice s(_start + getNthOffset(index), options);
|
||||
Slice s(_start + getNthOffset(index));
|
||||
|
||||
if (translate) {
|
||||
return s.makeKey();
|
||||
|
@ -568,10 +568,9 @@ ValueLength Slice::getNthOffsetFromCompact(ValueLength index) const {
|
|||
ValueLength current = 0;
|
||||
while (current != index) {
|
||||
uint8_t const* s = _start + offset;
|
||||
Slice key = Slice(s, options);
|
||||
offset += key.byteSize();
|
||||
offset += Slice(s).byteSize();
|
||||
if (h == 0x14) {
|
||||
Slice value = Slice(_start + offset, options);
|
||||
Slice value = Slice(_start + offset);
|
||||
offset += value.byteSize();
|
||||
}
|
||||
++current;
|
||||
|
@ -585,8 +584,7 @@ Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
|||
ValueLength n) const {
|
||||
for (ValueLength index = 0; index < n; ++index) {
|
||||
ValueLength offset = ieBase + index * offsetSize;
|
||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
|
||||
options);
|
||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize));
|
||||
|
||||
if (key.isString()) {
|
||||
if (!key.isEqualString(attribute)) {
|
||||
|
@ -603,7 +601,7 @@ Slice Slice::searchObjectKeyLinear(std::string const& attribute,
|
|||
}
|
||||
|
||||
// key is identical. now return value
|
||||
return Slice(key.start() + key.byteSize(), options);
|
||||
return Slice(key.start() + key.byteSize());
|
||||
}
|
||||
|
||||
// nothing found
|
||||
|
@ -624,8 +622,7 @@ Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
|||
ValueLength index = l + ((r - l) / 2);
|
||||
|
||||
ValueLength offset = ieBase + index * offsetSize;
|
||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize),
|
||||
options);
|
||||
Slice key(_start + readInteger<ValueLength>(_start + offset, offsetSize));
|
||||
|
||||
int res;
|
||||
if (key.isString()) {
|
||||
|
@ -640,7 +637,7 @@ Slice Slice::searchObjectKeyBinary(std::string const& attribute,
|
|||
|
||||
if (res == 0) {
|
||||
// found
|
||||
return Slice(key.start() + key.byteSize(), options);
|
||||
return Slice(key.start() + key.byteSize());
|
||||
}
|
||||
|
||||
if (res > 0) {
|
||||
|
@ -665,15 +662,12 @@ SliceScope::~SliceScope() {
|
|||
}
|
||||
}
|
||||
|
||||
Slice SliceScope::add(uint8_t const* data, ValueLength size,
|
||||
Options const* options) {
|
||||
Slice SliceScope::add(uint8_t const* data, ValueLength size) {
|
||||
size_t const s = checkOverflow(size);
|
||||
std::unique_ptr<uint8_t[]> copy(new uint8_t[s]);
|
||||
memcpy(copy.get(), data, s);
|
||||
_allocations.push_back(copy.get());
|
||||
uint8_t const* start = copy.release();
|
||||
|
||||
return Slice(start, options);
|
||||
return Slice(copy.release());
|
||||
}
|
||||
|
||||
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) ==
|
||||
sizeof(void*) + sizeof(void*),
|
||||
"Slice has an unexpected size");
|
||||
sizeof(void*), "Slice has an unexpected size");
|
||||
|
|
|
@ -335,7 +335,7 @@ class MarkerAccessorDocument : public T {
|
|||
|
||||
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; }
|
||||
};
|
||||
|
@ -415,7 +415,7 @@ class MarkerAccessorStructural : public T {
|
|||
|
||||
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; }
|
||||
};
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
|
||||
#include "Options.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/Logger.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include <velocypack/AttributeTranslator.h>
|
||||
#include <velocypack/Dumper.h>
|
||||
#include <velocypack/Options.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/Value.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
@ -37,57 +37,26 @@ using namespace arangodb;
|
|||
|
||||
static std::unique_ptr<VPackAttributeTranslator> translator;
|
||||
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;
|
||||
|
||||
|
||||
void StorageOptions::initialize() {
|
||||
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 {
|
||||
// attribute exclude handler for skipping over system attributes
|
||||
struct SystemAttributeExcludeHandler : public VPackAttributeExcludeHandler {
|
||||
bool shouldExclude(VPackSlice const& key, int nesting) override final {
|
||||
VPackValueLength 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
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((keyLength == 3 && memcmp(p, "_id", keyLength) == 0) ||
|
||||
(keyLength == 4 && memcmp(p, "_rev", keyLength) == 0) ||
|
||||
(keyLength == 3 && memcmp(p, "_to", keyLength) == 0) ||
|
||||
(keyLength == 5 && memcmp(p, "_from", keyLength) == 0)) {
|
||||
// exclude these attribute
|
||||
// exclude these attributes (but not _key!)
|
||||
if ((keyLength == 3 && memcmp(p, TRI_VOC_ATTRIBUTE_ID, keyLength) == 0) ||
|
||||
(keyLength == 4 && memcmp(p, TRI_VOC_ATTRIBUTE_REV, keyLength) == 0) ||
|
||||
(keyLength == 3 && memcmp(p, TRI_VOC_ATTRIBUTE_TO, keyLength) == 0) ||
|
||||
(keyLength == 5 && memcmp(p, TRI_VOC_ATTRIBUTE_FROM, keyLength) == 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -96,89 +65,139 @@ struct ExcludeHandlerImpl : public VPackAttributeExcludeHandler {
|
|||
}
|
||||
};
|
||||
|
||||
struct CustomTypeHandlerImpl : public VPackCustomTypeHandler {
|
||||
explicit CustomTypeHandlerImpl(
|
||||
arangodb::CollectionNameResolver const* resolver)
|
||||
: resolver(resolver) {}
|
||||
|
||||
void toJson(VPackSlice const& value, VPackDumper* dumper,
|
||||
VPackSlice const& base) {
|
||||
if (value.head() == 0xf0) {
|
||||
// _id
|
||||
if (!base.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid value type");
|
||||
}
|
||||
uint64_t cid = arangodb::velocypack::readUInt64(value.start() + 1);
|
||||
char buffer[512]; // This is enough for collection name + _key
|
||||
size_t len = resolver->getCollectionName(&buffer[0], cid);
|
||||
buffer[len] = '/';
|
||||
VPackSlice key = base.get(TRI_VOC_ATTRIBUTE_KEY);
|
||||
|
||||
VPackValueLength keyLength;
|
||||
char const* p = key.getString(keyLength);
|
||||
if (p == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid _key value");
|
||||
}
|
||||
memcpy(&buffer[len + 1], p, 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!";
|
||||
// custom type value handler, used for determining the length of the _id attribute
|
||||
struct CustomIdLengthHandler : public VPackCustomTypeHandler {
|
||||
void toJson(VPackSlice const&, VPackDumper*,
|
||||
VPackSlice const&) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
VPackValueLength byteSize(VPackSlice const& value) {
|
||||
if (value.head() == 0xf0) {
|
||||
// _id
|
||||
return 1 + 8; // 0xf0 + 8 bytes for collection id
|
||||
if (value.head() != 0xf0) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid custom type");
|
||||
}
|
||||
|
||||
if (value.head() == 0xf1) {
|
||||
// _rev
|
||||
return 1 + 8; // 0xf1 + 8 bytes for tick value
|
||||
}
|
||||
|
||||
if (value.head() == 0xf2) {
|
||||
// _from, _to
|
||||
// TODO!!
|
||||
return 1;
|
||||
}
|
||||
|
||||
throw "unknown type!";
|
||||
|
||||
// _id
|
||||
return 1 + 8; // 0xf0 + 8 bytes for collection id
|
||||
}
|
||||
|
||||
arangodb::CollectionNameResolver const* resolver;
|
||||
TRI_voc_cid_t cid;
|
||||
};
|
||||
|
||||
StorageOptions::StorageOptions()
|
||||
: _translator(new VPackAttributeTranslator),
|
||||
_excludeHandler(new ExcludeHandlerImpl) {
|
||||
// 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,
|
||||
VPackSlice const& base) {
|
||||
if (value.head() != 0xf0) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid custom type");
|
||||
}
|
||||
|
||||
// _id
|
||||
if (!base.isObject()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid value type");
|
||||
}
|
||||
uint64_t cid = arangodb::velocypack::readUInt64(value.start() + 1);
|
||||
char buffer[512]; // This is enough for collection name + _key
|
||||
size_t len = getResolver()->getCollectionName(&buffer[0], cid);
|
||||
buffer[len] = '/';
|
||||
VPackSlice key = base.get(TRI_VOC_ATTRIBUTE_KEY);
|
||||
|
||||
VPackValueLength keyLength;
|
||||
char const* p = key.getString(keyLength);
|
||||
if (p == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"invalid _key value");
|
||||
}
|
||||
memcpy(&buffer[len + 1], p, keyLength);
|
||||
dumper->appendString(&buffer[0], len + 1 + keyLength);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
TRI_vocbase_t* vocbase;
|
||||
CollectionNameResolver* resolver;
|
||||
bool ownsResolver;
|
||||
};
|
||||
|
||||
|
||||
// initialize global vpack options
|
||||
void StorageOptions::initialize() {
|
||||
// initialize translator
|
||||
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->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();
|
||||
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
|
||||
JsonToDocumentTemplate.buildUnindexedArrays = false;
|
||||
JsonToDocumentTemplate.buildUnindexedObjects = false;
|
||||
|
@ -209,24 +228,4 @@ StorageOptions::StorageOptions()
|
|||
NonDocumentTemplate.escapeForwardSlashes = true;
|
||||
NonDocumentTemplate.unsupportedTypeBehavior =
|
||||
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 {
|
||||
void initialize();
|
||||
|
||||
VPackAttributeTranslator* getTranslator();
|
||||
VPackOptions* getOptions();
|
||||
|
||||
VPackOptions* getDocumentToJsonTemplate();
|
||||
VPackOptions* getJsonToDocumentTemplate();
|
||||
VPackOptions* getNonDocumentTemplate();
|
||||
// VPackCustomTypeHandler* createCustomHandler(
|
||||
// arangodb::CollectionNameResolver const*);
|
||||
VPackAttributeTranslator const* getTranslator();
|
||||
VPackOptions const* getDefaultOptions();
|
||||
VPackOptions const* getInsertOptions();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -185,26 +185,6 @@ class Transaction {
|
|||
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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -38,10 +38,3 @@ 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;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @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) {
|
||||
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,
|
||||
char const* excludeAttribute = nullptr) {
|
||||
|
||||
VPackSlice slice(VPackFromMarker(marker));
|
||||
auto slice = VPackFromMarker(marker);
|
||||
|
||||
VPackObjectIterator it(slice);
|
||||
while (it.valid()) {
|
||||
|
@ -143,7 +144,7 @@ static void KeysOfVPack(v8::PropertyCallbackInfo<v8::Array> const& args) {
|
|||
TRI_V8_RETURN(v8::Array::New(isolate));
|
||||
}
|
||||
|
||||
VPackSlice slice(VPackFromMarker(marker));
|
||||
auto slice = VPackFromMarker(marker);
|
||||
std::vector<std::string> keys(VPackCollection::keys(slice));
|
||||
|
||||
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>());
|
||||
}
|
||||
|
||||
VPackSlice slice(VPackFromMarker(marker));
|
||||
auto slice = VPackFromMarker(marker);
|
||||
|
||||
TRI_V8_RETURN(TRI_VPackToV8(isolate, slice.get(key)));
|
||||
} catch (...) {
|
||||
|
@ -322,7 +323,7 @@ static void PropertyQueryVPack(
|
|||
TRI_V8_RETURN(v8::Handle<v8::Integer>());
|
||||
}
|
||||
|
||||
VPackSlice slice(VPackFromMarker(marker));
|
||||
auto slice = VPackFromMarker(marker);
|
||||
|
||||
if (!slice.hasKey(key)) {
|
||||
// key not found
|
||||
|
|
|
@ -1069,11 +1069,11 @@ static int AddSystemAttributes(Transaction* trx, TRI_voc_cid_t cid,
|
|||
TRI_document_collection_t* document,
|
||||
VPackBuilder& builder) {
|
||||
// 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)) {
|
||||
// "_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));
|
||||
} else {
|
||||
// "_key" attribute is present in object
|
||||
|
@ -1090,19 +1090,16 @@ static int AddSystemAttributes(Transaction* trx, TRI_voc_cid_t cid,
|
|||
return res;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// now add _id attribute
|
||||
|
||||
// add _id attribute
|
||||
uint8_t* p = builder.add(TRI_VOC_ATTRIBUTE_ID,
|
||||
VPackValuePair(9ULL, VPackValueType::Custom));
|
||||
*p++ = 0xf0;
|
||||
arangodb::velocypack::storeUInt64(p, cid);
|
||||
|
||||
// now add _rev attribute
|
||||
p = builder.add(TRI_VOC_ATTRIBUTE_REV,
|
||||
VPackValuePair(9ULL, VPackValueType::Custom));
|
||||
*p++ = 0xf1;
|
||||
arangodb::velocypack::storeUInt64(p, tick);
|
||||
*/
|
||||
// add _rev attribute
|
||||
builder.add(TRI_VOC_ATTRIBUTE_REV, VPackValue(std::to_string(tick)));
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1236,6 +1233,8 @@ static void InsertVocbaseVPack(
|
|||
// invalid value type. must be a document
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
|
||||
}
|
||||
|
||||
VPackOptions const* vpackOptions = StorageOptions::getInsertOptions();
|
||||
|
||||
// load collection
|
||||
SingleCollectionWriteTransaction<1> trx(new V8TransactionContext(true),
|
||||
|
@ -1247,7 +1246,7 @@ static void InsertVocbaseVPack(
|
|||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
VPackBuilder builder(trx.vpackOptions());
|
||||
VPackBuilder builder(vpackOptions);
|
||||
res = TRI_V8ToVPack(isolate, builder, args[0]->ToObject(), true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -1257,8 +1256,7 @@ static void InsertVocbaseVPack(
|
|||
TRI_document_collection_t* document = trx.documentCollection();
|
||||
|
||||
// the AddSystemAttributes() needs the collection already loaded because it
|
||||
// references the
|
||||
// collection's key generator
|
||||
// references the collection's key generator
|
||||
res = AddSystemAttributes(&trx, col->_cid, document, builder);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -1298,18 +1296,13 @@ static void InsertVocbaseVPack(
|
|||
TRI_V8_RETURN_TRUE();
|
||||
}
|
||||
|
||||
VPackSlice vpack(mptr.vpack());
|
||||
std::string key = VPackSlice(mptr.vpack()).get(TRI_VOC_ATTRIBUTE_KEY).copyString();
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New(isolate);
|
||||
TRI_GET_GLOBAL_STRING(_IdKey);
|
||||
TRI_GET_GLOBAL_STRING(_RevKey);
|
||||
TRI_GET_GLOBAL_STRING(_KeyKey);
|
||||
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));
|
||||
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_ID), V8DocumentId(isolate, trx.resolver()->getCollectionName(col->_cid), key));
|
||||
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_REV), TRI_V8_STD_STRING(vpack.get(TRI_VOC_ATTRIBUTE_REV).copyString()));
|
||||
result->ForceSet(TRI_V8_STRING(TRI_VOC_ATTRIBUTE_KEY), TRI_V8_STD_STRING(key));
|
||||
|
||||
TRI_V8_RETURN(result);
|
||||
}
|
||||
|
@ -1844,9 +1837,7 @@ static void RemoveVocbaseVPack(
|
|||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
VPackOptions vpackOptions = trx.copyVPackOptions();
|
||||
vpackOptions.attributeExcludeHandler = nullptr;
|
||||
VPackBuilder builder(&vpackOptions);
|
||||
VPackBuilder builder(StorageOptions::getDefaultOptions());
|
||||
|
||||
builder.add(VPackValue(VPackValueType::Object));
|
||||
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) {
|
||||
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()) {
|
||||
TRI_V8_THROW_EXCEPTION_MEMORY();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Storage/Options.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "VocBase/document-collection.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) {
|
||||
auto b = reinterpret_cast<char const*>(marker) +
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -133,7 +134,7 @@ static inline TRI_voc_rid_t TRI_EXTRACT_MARKER_RID(
|
|||
if (marker->_type == TRI_WAL_MARKER_VPACK_DOCUMENT) {
|
||||
auto b = reinterpret_cast<char const*>(marker) +
|
||||
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);
|
||||
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) {
|
||||
auto b = reinterpret_cast<char const*>(marker) +
|
||||
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;
|
||||
char const* p = slice.get(TRI_VOC_ATTRIBUTE_KEY).getString(len);
|
||||
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) {
|
||||
auto lb = reinterpret_cast<char const*>(lm) +
|
||||
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;
|
||||
char const* p = ls.get(TRI_VOC_ATTRIBUTE_KEY).getString(llen);
|
||||
|
||||
auto rb = reinterpret_cast<char const*>(rm) +
|
||||
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;
|
||||
char const* q = rs.get(TRI_VOC_ATTRIBUTE_KEY).getString(rlen);
|
||||
|
||||
|
|
Loading…
Reference in New Issue