1
0
Fork 0

updated vpack library

This commit is contained in:
Jan Steemann 2016-02-12 16:33:26 +01:00
parent 80433b23bb
commit 0089b0fcf6
20 changed files with 299 additions and 335 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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 {

View File

@ -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;

View File

@ -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; }

View File

@ -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();

View File

@ -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;
} }

View File

@ -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());
} }
} }
} }

View File

@ -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");

View File

@ -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; }
}; };

View File

@ -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);
}
*/ */

View File

@ -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*);
} }
} }

View File

@ -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
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -38,10 +38,3 @@ TransactionContext::TransactionContext() {}
TransactionContext::~TransactionContext() {} TransactionContext::~TransactionContext() {}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the vpack options
////////////////////////////////////////////////////////////////////////////////
VPackOptions const* TransactionContext::getVPackOptions() const {
return StorageOptions::getOptions();
}

View File

@ -84,12 +84,6 @@ class TransactionContext {
virtual int unregisterTransaction() = 0; virtual int unregisterTransaction() = 0;
//////////////////////////////////////////////////////////////////////////////
/// @brief return the vpack options
//////////////////////////////////////////////////////////////////////////////
VPackOptions const* getVPackOptions() const;
}; };
} }

View File

@ -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

View File

@ -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,

View File

@ -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();

View File

@ -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);