1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/arangodb into devel

This commit is contained in:
Heiko Kernbach 2015-06-01 15:57:02 +02:00
commit f7eaad1ceb
19 changed files with 507 additions and 567 deletions

View File

@ -72,6 +72,7 @@ AqlItemBlock::AqlItemBlock (size_t nrItems,
AqlItemBlock::AqlItemBlock (Json const& json) {
bool exhausted = JsonHelper::getBooleanValue(json.json(), "exhausted", false);
if (exhausted) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "exhausted must be false");
}

View File

@ -52,6 +52,7 @@ AttributeAccessor::AttributeAccessor (std::vector<char const*> const& attributeP
_combinedName(),
_variable(variable),
_buffer(TRI_UNKNOWN_MEM_ZONE),
_shaper(nullptr),
_pid(0),
_nameCache({ "", 0 }),
_attributeType(ATTRIBUTE_TYPE_REGULAR) {
@ -78,11 +79,13 @@ AttributeAccessor::AttributeAccessor (std::vector<char const*> const& attributeP
}
}
for (auto const& it : _attributeParts) {
if (! _combinedName.empty()) {
_combinedName.push_back('.');
if (_attributeType == ATTRIBUTE_TYPE_REGULAR) {
for (auto const& it : _attributeParts) {
if (! _combinedName.empty()) {
_combinedName.push_back('.');
}
_combinedName.append(it);
}
_combinedName.append(it);
}
}
@ -223,6 +226,7 @@ AqlValue AttributeAccessor::extractId (AqlValue const& src,
_buffer.appendText(_nameCache.value);
_buffer.appendChar('/');
_buffer.appendText(TRI_EXTRACT_MARKER_KEY(src._marker));
auto json = new Json(TRI_UNKNOWN_MEM_ZONE, _buffer.c_str(), _buffer.length());
return AqlValue(json);
@ -291,24 +295,25 @@ AqlValue AttributeAccessor::extractTo (AqlValue const& src,
AqlValue AttributeAccessor::extractRegular (AqlValue const& src,
triagens::arango::AqlTransaction* trx,
TRI_document_collection_t const* document) {
auto shaper = document->getShaper();
if (_pid == 0) {
_pid = shaper->lookupAttributePathByName(shaper, _combinedName.c_str());
if (_shaper == nullptr) {
_shaper = document->getShaper();
_pid = _shaper->lookupAttributePathByName(_shaper, _combinedName.c_str());
}
if (_pid != 0) {
// attribute exists
TRI_ASSERT_EXPENSIVE(_shaper != nullptr);
TRI_shaped_json_t document;
TRI_EXTRACT_SHAPED_JSON_MARKER(document, src._marker);
TRI_shaped_json_t json;
TRI_shape_t const* shape;
bool ok = TRI_ExtractShapedJsonVocShaper(shaper, &document, 0, _pid, &json, &shape);
bool ok = TRI_ExtractShapedJsonVocShaper(_shaper, &document, 0, _pid, &json, &shape);
if (ok && shape != nullptr) {
std::unique_ptr<TRI_json_t> extracted(TRI_JsonShapedJson(shaper, &json));
std::unique_ptr<TRI_json_t> extracted(TRI_JsonShapedJson(_shaper, &json));
if (extracted == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);

View File

@ -169,6 +169,12 @@ namespace triagens {
triagens::basics::StringBuffer _buffer;
////////////////////////////////////////////////////////////////////////////////
/// @brief shaper
////////////////////////////////////////////////////////////////////////////////
TRI_shaper_t* _shaper;
////////////////////////////////////////////////////////////////////////////////
/// @brief attribute path id cache for shapes
////////////////////////////////////////////////////////////////////////////////

View File

@ -992,7 +992,8 @@ namespace triagens {
/// @brief find the shard that is responsible for a document
////////////////////////////////////////////////////////////////////////////////
int getResponsibleShard (CollectionID const&, TRI_json_t const*,
int getResponsibleShard (CollectionID const&,
TRI_json_t const*,
bool docComplete,
ShardID& shardID,
bool& usesDefaultShardingAttributes);

View File

@ -361,7 +361,7 @@ int TRI_InitHashArrayMulti (TRI_hash_array_multi_t* array,
array->_nrOverflowAlloc = 0;
array->_freelist = nullptr;
TRI_InitVectorPointer2(&array->_blocks, TRI_UNKNOWN_MEM_ZONE, 16);
TRI_InitVectorPointer(&array->_blocks, TRI_UNKNOWN_MEM_ZONE, 16);
return AllocateTable(array, InitialSize());
}

View File

@ -28,18 +28,18 @@
////////////////////////////////////////////////////////////////////////////////
#include "V8Traverser.h"
#include "v8.h"
#include "Utils/transactions.h"
#include "Utils/V8ResolverGuard.h"
#include "Utils/CollectionNameResolver.h"
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"
#include "V8Server/v8-vocbaseprivate.h"
#include "V8Server/v8-wrapshapedjson.h"
#include "V8Server/v8-vocindex.h"
#include "V8Server/v8-collection.h"
#include "Utils/transactions.h"
#include "Utils/V8ResolverGuard.h"
#include "Utils/CollectionNameResolver.h"
#include "VocBase/document-collection.h"
#include "VocBase/key-generator.h"
#include <v8.h>
using namespace std;
using namespace triagens::basics;
@ -224,15 +224,16 @@ class SimpleEdgeExpander {
/// @brief Insert a new vertex matcher object
////////////////////////////////////////////////////////////////////////////////
void BasicOptions::addVertexFilter(
v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
string& errorMessage) {
void BasicOptions::addVertexFilter (v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
string& errorMessage) {
auto it = _vertexFilter.find(cid);
if (example->IsArray()) {
if (it == _vertexFilter.end()) {
_vertexFilter.emplace(cid, VertexFilterInfo(
@ -241,7 +242,8 @@ void BasicOptions::addVertexFilter(
new ExampleMatcher(isolate, v8::Handle<v8::Array>::Cast(example), shaper, errorMessage)
));
}
} else {
}
else {
// Has to be Object
if (it == _vertexFilter.end()) {
_vertexFilter.emplace(cid, VertexFilterInfo(
@ -257,13 +259,14 @@ void BasicOptions::addVertexFilter(
/// @brief Checks if a vertex matches to given examples
////////////////////////////////////////////////////////////////////////////////
bool BasicOptions::matchesVertex (VertexId& v) const {
if (!useVertexFilter) {
bool BasicOptions::matchesVertex (VertexId const& v) const {
if (! useVertexFilter) {
// Nothing to do
return true;
}
auto it = _vertexFilter.find(v.cid);
if (it == _vertexFilter.end()) {
// This collection does not have any object of this shape.
// Short circuit.
@ -271,31 +274,33 @@ bool BasicOptions::matchesVertex (VertexId& v) const {
}
TRI_doc_mptr_copy_t vertex;
int res = it->second.trx->readSingle(it->second.col, &vertex, v.key);
if (res != TRI_ERROR_NO_ERROR) {
return false;
}
return it->second.matcher->matches(v.cid, &vertex);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Insert a new edge matcher object
////////////////////////////////////////////////////////////////////////////////
void BasicOptions::addEdgeFilter (
v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
string& errorMessage) {
void BasicOptions::addEdgeFilter (v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
string& errorMessage) {
auto it = _edgeFilter.find(cid);
if (example->IsArray()) {
if (it == _edgeFilter.end()) {
_edgeFilter.emplace(cid, new ExampleMatcher(isolate, v8::Handle<v8::Array>::Cast(example), shaper, errorMessage));
}
} else {
}
else {
// Has to be Object
if (it == _edgeFilter.end()) {
_edgeFilter.emplace(cid, new ExampleMatcher(isolate, v8::Handle<v8::Object>::Cast(example), shaper, errorMessage));
@ -308,16 +313,19 @@ void BasicOptions::addEdgeFilter (
////////////////////////////////////////////////////////////////////////////////
bool BasicOptions::matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const {
if (!useEdgeFilter) {
if (! useEdgeFilter) {
// Nothing to do
return true;
}
auto it = _edgeFilter.find(e.cid);
if (it == _edgeFilter.end()) {
// This collection does not have any object of this shape.
// Short circuit.
return false;
}
return it->second->matches(e.cid, edge);
}
@ -329,10 +337,11 @@ bool BasicOptions::matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const {
/// @brief Checks if a vertex matches to given examples
////////////////////////////////////////////////////////////////////////////////
bool ShortestPathOptions::matchesVertex (VertexId& v) const {
bool ShortestPathOptions::matchesVertex (VertexId const& v) const {
if (start == v || end == v) {
return true;
}
return BasicOptions::matchesVertex(v);
}
@ -344,9 +353,9 @@ bool ShortestPathOptions::matchesVertex (VertexId& v) const {
/// @brief Checks if a vertex matches to given examples
////////////////////////////////////////////////////////////////////////////////
bool NeighborsOptions::matchesVertex (VertexId& v) const {
bool NeighborsOptions::matchesVertex (VertexId const& v) const {
// If there are explicitly marked collections check them.
if (_explicitCollections.size() > 0) {
if (! _explicitCollections.empty()) {
// If the current collection is not stored the result is invalid
if (_explicitCollections.find(v.cid) == _explicitCollections.end()) {
return false;
@ -361,7 +370,7 @@ bool NeighborsOptions::matchesVertex (VertexId& v) const {
/// collection all are implicitly allowed.
////////////////////////////////////////////////////////////////////////////////
void NeighborsOptions::addCollectionRestriction (TRI_voc_cid_t& cid) {
void NeighborsOptions::addCollectionRestriction (TRI_voc_cid_t cid) {
_explicitCollections.insert(cid);
}
@ -373,26 +382,33 @@ void NeighborsOptions::addCollectionRestriction (TRI_voc_cid_t& cid) {
/// @brief Wrapper for the shortest path computation
////////////////////////////////////////////////////////////////////////////////
unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
vector<EdgeCollectionInfo*>& collectionInfos,
ShortestPathOptions& opts) {
TRI_edge_direction_e forward;
TRI_edge_direction_e backward;
if (opts.direction == "outbound") {
forward = TRI_EDGE_OUT;
backward = TRI_EDGE_IN;
} else if (opts.direction == "inbound") {
}
else if (opts.direction == "inbound") {
forward = TRI_EDGE_IN;
backward = TRI_EDGE_OUT;
} else {
}
else {
forward = TRI_EDGE_ANY;
backward = TRI_EDGE_ANY;
}
auto edgeFilterClosure = [&opts](EdgeId& e, TRI_doc_mptr_copy_t* edge) -> bool {return opts.matchesEdge(e, edge);};
auto edgeFilterClosure = [&opts](EdgeId& e, TRI_doc_mptr_copy_t* edge) -> bool {
return opts.matchesEdge(e, edge);
};
auto vertexFilterClosure = [&opts](VertexId& v) -> bool { return opts.matchesVertex(v); };
auto vertexFilterClosure = [&opts](VertexId& v) -> bool {
return opts.matchesVertex(v);
};
MultiCollectionEdgeExpander forwardExpander(forward, collectionInfos, edgeFilterClosure, vertexFilterClosure);
MultiCollectionEdgeExpander backwardExpander(backward, collectionInfos, edgeFilterClosure, vertexFilterClosure);
@ -414,21 +430,23 @@ unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
/// @brief search for distinct inbound neighbors
////////////////////////////////////////////////////////////////////////////////
static void inboundNeighbors (
vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
static void InboundNeighbors (vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
TRI_edge_direction_e dir = TRI_EDGE_IN;
unordered_set<VertexId> nextDepth;
for (auto col : collectionInfos) {
for (VertexId start : startVertices) {
for (auto const& col : collectionInfos) {
for (VertexId const& start : startVertices) {
auto edges = col->getEdges(dir, start);
for (size_t j = 0; j < edges.size(); ++j) {
EdgeId edgeId = col->extractEdgeId(edges[j]);
if (opts.matchesEdge(edgeId, &edges[j])) {
VertexId v = extractFromId(edges[j]);
if (visited.find(v) != visited.end()) {
@ -451,8 +469,9 @@ static void inboundNeighbors (
}
}
}
if (nextDepth.size() > 0) {
inboundNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
if (! nextDepth.empty()) {
InboundNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
}
}
@ -460,19 +479,21 @@ static void inboundNeighbors (
/// @brief search for distinct outbound neighbors
////////////////////////////////////////////////////////////////////////////////
static void outboundNeighbors (
vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
static void OutboundNeighbors (vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
TRI_edge_direction_e dir = TRI_EDGE_OUT;
unordered_set<VertexId> nextDepth;
for (auto col : collectionInfos) {
for (VertexId start : startVertices) {
for (auto const& col : collectionInfos) {
for (VertexId const& start : startVertices) {
auto edges = col->getEdges(dir, start);
for (size_t j = 0; j < edges.size(); ++j) {
EdgeId edgeId = col->extractEdgeId(edges[j]);
if (opts.matchesEdge(edgeId, &edges[j])) {
@ -497,8 +518,8 @@ static void outboundNeighbors (
}
}
}
if (nextDepth.size() > 0) {
outboundNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
if (! nextDepth.empty()) {
OutboundNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
}
}
@ -506,20 +527,21 @@ static void outboundNeighbors (
/// @brief search for distinct in- and outbound neighbors
////////////////////////////////////////////////////////////////////////////////
static void anyNeighbors (
vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
static void AnyNeighbors (vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
unordered_set<VertexId>& startVertices,
unordered_set<VertexId>& visited,
unordered_set<VertexId>& distinct,
vector<VertexId>& result,
uint64_t depth = 1) {
TRI_edge_direction_e dir = TRI_EDGE_OUT;
unordered_set<VertexId> nextDepth;
for (auto col : collectionInfos) {
for (VertexId start : startVertices) {
for (auto const& col : collectionInfos) {
for (VertexId const& start : startVertices) {
dir = TRI_EDGE_OUT;
auto edges = col->getEdges(dir, start);
for (size_t j = 0; j < edges.size(); ++j) {
EdgeId edgeId = col->extractEdgeId(edges[j]);
if (opts.matchesEdge(edgeId, &edges[j])) {
@ -568,8 +590,8 @@ static void anyNeighbors (
}
}
}
if (nextDepth.size() > 0) {
anyNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
if (! nextDepth.empty()) {
AnyNeighbors(collectionInfos, opts, nextDepth, visited, distinct, result, depth + 1);
}
}
@ -589,13 +611,14 @@ void TRI_RunNeighborsSearch (
switch (opts.direction) {
case TRI_EDGE_IN:
inboundNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
InboundNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
break;
case TRI_EDGE_OUT:
outboundNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
OutboundNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
break;
case TRI_EDGE_ANY:
anyNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
AnyNeighbors(collectionInfos, opts, startVertices, visited, distinct, result);
break;
}
};
}

View File

@ -44,7 +44,9 @@ struct VertexId {
TRI_voc_cid_t cid;
char const* key;
VertexId () : cid(0), key(nullptr) {
VertexId ()
: cid(0),
key(nullptr) {
}
VertexId (TRI_voc_cid_t cid, char const* key)
@ -68,7 +70,7 @@ namespace std {
template<>
struct hash<VertexId> {
public:
size_t operator()(VertexId const& s) const {
size_t operator() (VertexId const& s) const {
size_t h1 = std::hash<TRI_voc_cid_t>()(s.cid);
size_t h2 = TRI_FnvHashString(s.key);
return h1 ^ ( h2 << 1 );
@ -78,7 +80,7 @@ namespace std {
template<>
struct equal_to<VertexId> {
public:
bool operator()(VertexId const& s, VertexId const& t) const {
bool operator() (VertexId const& s, VertexId const& t) const {
return s.cid == t.cid && strcmp(s.key, t.key) == 0;
}
};
@ -86,7 +88,7 @@ namespace std {
template<>
struct less<VertexId> {
public:
bool operator()(const VertexId& lhs, const VertexId& rhs) {
bool operator() (const VertexId& lhs, const VertexId& rhs) {
if (lhs.cid != rhs.cid) {
return lhs.cid < rhs.cid;
}
@ -109,12 +111,14 @@ struct VertexFilterInfo {
TRI_transaction_collection_t* col;
triagens::arango::ExampleMatcher* matcher;
VertexFilterInfo (
triagens::arango::ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
triagens::arango::ExampleMatcher* matcher
) : trx(trx), col(col), matcher(matcher) {
}
VertexFilterInfo (triagens::arango::ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
triagens::arango::ExampleMatcher* matcher)
: trx(trx),
col(col),
matcher(matcher) {
}
};
////////////////////////////////////////////////////////////////////////////////
@ -124,8 +128,6 @@ struct VertexFilterInfo {
typedef triagens::basics::PathFinder<VertexId, EdgeId, double>
ArangoDBPathFinder;
namespace triagens {
namespace basics {
namespace traverser {
@ -144,33 +146,39 @@ namespace triagens {
useVertexFilter(false) {
}
~BasicOptions () {
// properly clean up the mess
for (auto& it : _edgeFilter) {
delete it.second;
}
for (auto& it: _vertexFilter) {
delete it.second.matcher;
it.second.matcher = nullptr;
}
}
public:
VertexId start;
bool useEdgeFilter;
bool useVertexFilter;
void addEdgeFilter (v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
std::string& errorMessage);
void addEdgeFilter (
v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
std::string& errorMessage
);
void addVertexFilter (
v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
triagens::arango::ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
std::string& errorMessage
);
void addVertexFilter (v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
triagens::arango::ExplicitTransaction* trx,
TRI_transaction_collection_t* col,
TRI_shaper_t* shaper,
TRI_voc_cid_t const& cid,
std::string& errorMessage);
bool matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const;
bool matchesVertex (VertexId& v) const;
bool matchesVertex (VertexId const& v) const;
};
@ -184,15 +192,15 @@ namespace triagens {
uint64_t minDepth;
uint64_t maxDepth;
NeighborsOptions () :
direction(TRI_EDGE_OUT),
minDepth(1),
maxDepth(1) {
NeighborsOptions ()
: direction(TRI_EDGE_OUT),
minDepth(1),
maxDepth(1) {
}
bool matchesVertex (VertexId& v) const;
bool matchesVertex (VertexId const&) const;
void addCollectionRestriction (TRI_voc_cid_t& cid);
void addCollectionRestriction (TRI_voc_cid_t cid);
};
@ -208,17 +216,16 @@ namespace triagens {
bool multiThreaded;
VertexId end;
ShortestPathOptions() :
direction("outbound"),
useWeight(false),
weightAttribute(""),
defaultWeight(1),
bidirectional(true),
multiThreaded(true) {
ShortestPathOptions ()
: direction("outbound"),
useWeight(false),
weightAttribute(""),
defaultWeight(1),
bidirectional(true),
multiThreaded(true) {
}
bool matchesVertex (VertexId& v) const;
bool matchesVertex (VertexId const&) const;
};
}
@ -261,34 +268,33 @@ class EdgeCollectionInfo {
public:
EdgeCollectionInfo(
TRI_voc_cid_t& edgeCollectionCid,
TRI_document_collection_t* edgeCollection,
WeightCalculatorFunction weighter
) : _edgeCollectionCid(edgeCollectionCid),
_edgeCollection(edgeCollection),
_weighter(weighter) {
EdgeCollectionInfo (TRI_voc_cid_t& edgeCollectionCid,
TRI_document_collection_t* edgeCollection,
WeightCalculatorFunction weighter)
: _edgeCollectionCid(edgeCollectionCid),
_edgeCollection(edgeCollection),
_weighter(weighter) {
}
EdgeId extractEdgeId(TRI_doc_mptr_copy_t& ptr) {
EdgeId extractEdgeId (TRI_doc_mptr_copy_t& ptr) {
return EdgeId(_edgeCollectionCid, TRI_EXTRACT_MARKER_KEY(&ptr));
}
std::vector<TRI_doc_mptr_copy_t> getEdges (TRI_edge_direction_e& direction,
VertexId& vertexId) {
std::vector<TRI_doc_mptr_copy_t> getEdges (TRI_edge_direction_e direction,
VertexId const& vertexId) const {
return TRI_LookupEdgesDocumentCollection(_edgeCollection,
direction, vertexId.cid, const_cast<char*>(vertexId.key));
}
TRI_voc_cid_t getCid() {
TRI_voc_cid_t getCid () {
return _edgeCollectionCid;
}
TRI_shaper_t* getShaper() {
TRI_shaper_t* getShaper () {
return _edgeCollection->getShaper();
}
double weightEdge(TRI_doc_mptr_copy_t& ptr) {
double weightEdge (TRI_doc_mptr_copy_t& ptr) {
return _weighter(ptr);
}
};
@ -299,6 +305,7 @@ class EdgeCollectionInfo {
////////////////////////////////////////////////////////////////////////////////
class VertexCollectionInfo {
private:
////////////////////////////////////////////////////////////////////////////////
@ -315,22 +322,21 @@ class VertexCollectionInfo {
public:
VertexCollectionInfo(
TRI_voc_cid_t& vertexCollectionCid,
TRI_transaction_collection_t* vertexCollection
) : _vertexCollectionCid(vertexCollectionCid),
_vertexCollection(vertexCollection) {
VertexCollectionInfo (TRI_voc_cid_t& vertexCollectionCid,
TRI_transaction_collection_t* vertexCollection)
: _vertexCollectionCid(vertexCollectionCid),
_vertexCollection(vertexCollection) {
}
TRI_voc_cid_t getCid() {
TRI_voc_cid_t getCid () {
return _vertexCollectionCid;
}
TRI_transaction_collection_t* getCollection() {
TRI_transaction_collection_t* getCollection () {
return _vertexCollection;
}
TRI_shaper_t* getShaper() {
TRI_shaper_t* getShaper () {
return _vertexCollection->_collection->_collection->getShaper();
}
};
@ -341,6 +347,7 @@ class VertexCollectionInfo {
////////////////////////////////////////////////////////////////////////////////
/// @brief Wrapper for the shortest path computation
////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
std::vector<EdgeCollectionInfo*>& collectionInfos,
triagens::basics::traverser::ShortestPathOptions& opts
@ -350,11 +357,9 @@ std::unique_ptr<ArangoDBPathFinder::Path> TRI_RunShortestPathSearch (
/// @brief Wrapper for the neighbors computation
////////////////////////////////////////////////////////////////////////////////
void TRI_RunNeighborsSearch (
std::vector<EdgeCollectionInfo*>& collectionInfos,
triagens::basics::traverser::NeighborsOptions& opts,
std::unordered_set<VertexId>& distinct,
std::vector<VertexId>& result
);
void TRI_RunNeighborsSearch (std::vector<EdgeCollectionInfo*>& collectionInfos,
triagens::basics::traverser::NeighborsOptions& opts,
std::unordered_set<VertexId>& distinct,
std::vector<VertexId>& result);
#endif

View File

@ -169,7 +169,7 @@ ExampleMatcher::ExampleMatcher (v8::Isolate* isolate,
size_t exCount = examples->Length();
for (size_t j = 0; j < exCount; ++j) {
auto tmp = examples->Get((uint32_t) j);
if (!tmp->IsObject() || tmp->IsArray()) {
if (! tmp->IsObject() || tmp->IsArray()) {
// Right now silently ignore this example
continue;
}

View File

@ -47,17 +47,17 @@ struct TRI_doc_mptr_t;
namespace triagens {
namespace arango {
class ExampleMatcher {
struct DocumentId {
TRI_voc_cid_t cid;
std::string key;
DocumentId (
TRI_voc_cid_t cid,
std::string key
) : cid(cid), key(key) {};
DocumentId (TRI_voc_cid_t cid,
std::string const& key)
: cid(cid),
key(key) {
}
};
enum internalAttr {
@ -76,42 +76,34 @@ namespace triagens {
TRI_shaper_t* _shaper;
std::vector<ExampleDefinition> definitions;
void fillExampleDefinition (
v8::Isolate* isolate,
v8::Handle<v8::Object> const& example,
v8::Handle<v8::Array> const& names,
size_t& n,
std::string& errorMessage,
ExampleDefinition& def
);
void fillExampleDefinition (v8::Isolate* isolate,
v8::Handle<v8::Object> const& example,
v8::Handle<v8::Array> const& names,
size_t& n,
std::string& errorMessage,
ExampleDefinition& def);
public:
ExampleMatcher (
v8::Isolate* isolate,
v8::Handle<v8::Object> const example,
TRI_shaper_t* shaper,
std::string& errorMessage
);
ExampleMatcher (v8::Isolate* isolate,
v8::Handle<v8::Object> const example,
TRI_shaper_t* shaper,
std::string& errorMessage);
ExampleMatcher (
v8::Isolate* isolate,
v8::Handle<v8::Array> const examples,
TRI_shaper_t* shaper,
std::string& errorMessage
);
ExampleMatcher (v8::Isolate* isolate,
v8::Handle<v8::Array> const examples,
TRI_shaper_t* shaper,
std::string& errorMessage);
ExampleMatcher (
TRI_json_t* example,
TRI_shaper_t* shaper
);
ExampleMatcher (TRI_json_t* example,
TRI_shaper_t* shaper);
~ExampleMatcher () {
cleanup();
};
bool matches (TRI_voc_cid_t cid, TRI_doc_mptr_t const* mptr) const;
bool matches (TRI_voc_cid_t cid,
TRI_doc_mptr_t const* mptr) const;
private:

View File

@ -76,7 +76,7 @@ TRI_headers_t::TRI_headers_t ()
_nrLinked(0),
_totalSize(0) {
TRI_InitVectorPointer2(&_blocks, TRI_UNKNOWN_MEM_ZONE, 16);
TRI_InitVectorPointer(&_blocks, TRI_UNKNOWN_MEM_ZONE, 16);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1797,7 +1797,7 @@ int TRI_InitServer (TRI_server_t* server,
TRI_InitReadWriteLock(&server->_databasesLock);
TRI_InitVectorPointer2(&server->_droppedDatabases, TRI_UNKNOWN_MEM_ZONE, 64);
TRI_InitVectorPointer(&server->_droppedDatabases, TRI_UNKNOWN_MEM_ZONE, 64);
TRI_InitMutex(&server->_createLock);

View File

@ -814,7 +814,7 @@ TRI_transaction_t* TRI_CreateTransaction (TRI_vocbase_t* vocbase,
trx->_type = TRI_TRANSACTION_WRITE;
}
TRI_InitVectorPointer2(&trx->_collections, TRI_UNKNOWN_MEM_ZONE, 2);
TRI_InitVectorPointer(&trx->_collections, TRI_UNKNOWN_MEM_ZONE, 2);
return trx;
}

View File

@ -600,22 +600,6 @@ size_t TRI_LengthVectorJson (TRI_json_t const* json) {
return TRI_LengthVector(&json->_value._objects);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type object
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsObjectJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_OBJECT;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type array
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsArrayJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_ARRAY;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type string
////////////////////////////////////////////////////////////////////////////////
@ -624,30 +608,6 @@ bool TRI_IsStringJson (TRI_json_t const* json) {
return IsString(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type number
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsNumberJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_NUMBER;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type boolean
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsBooleanJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_BOOLEAN;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type null
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsNullJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief adds a new sub-object to an array, copying it
////////////////////////////////////////////////////////////////////////////////
@ -820,7 +780,7 @@ TRI_json_t* TRI_LookupObjectJson (TRI_json_t const* object, char const* name) {
size_t const length = strlen(name) + 1;
for (size_t i = 0; i < n; i += 2) {
auto key = static_cast<TRI_json_t const*>(TRI_AtVector(&object->_value._objects, i));
auto key = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
if (! IsString(key)) {
continue;
@ -828,22 +788,22 @@ TRI_json_t* TRI_LookupObjectJson (TRI_json_t const* object, char const* name) {
// check string length first, and contents only if string lengths are equal
if (key->_value._string.length == length &&
TRI_EqualString(key->_value._string.data, name)) {
return static_cast<TRI_json_t*>(TRI_AtVector(&object->_value._objects, i + 1));
strcmp(key->_value._string.data, name) == 0) {
return static_cast<TRI_json_t*>(TRI_AddressVector(&object->_value._objects, i + 1));
}
}
}
else {
// simple case for smaller objects
for (size_t i = 0; i < n; i += 2) {
auto key = static_cast<TRI_json_t const*>(TRI_AtVector(&object->_value._objects, i));
auto key = static_cast<TRI_json_t const*>(TRI_AddressVector(&object->_value._objects, i));
if (! IsString(key)) {
continue;
}
if (TRI_EqualString(key->_value._string.data, name)) {
return static_cast<TRI_json_t*>(TRI_AtVector(&object->_value._objects, i + 1));
if (strcmp(key->_value._string.data, name) == 0) {
return static_cast<TRI_json_t*>(TRI_AddressVector(&object->_value._objects, i + 1));
}
}
}

View File

@ -220,37 +220,47 @@ size_t TRI_LengthVectorJson (TRI_json_t const*);
/// @brief determines whether the JSON passed is of type object
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsObjectJson (TRI_json_t const*);
static inline bool TRI_IsObjectJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_OBJECT;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type array
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsArrayJson (TRI_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type string
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsStringJson (TRI_json_t const*);
static inline bool TRI_IsArrayJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_ARRAY;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type number
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsNumberJson (TRI_json_t const*);
static inline bool TRI_IsNumberJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_NUMBER;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type boolean
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsBooleanJson (TRI_json_t const*);
static inline bool TRI_IsBooleanJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_BOOLEAN;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type null
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsNullJson (TRI_json_t const*);
static inline bool TRI_IsNullJson (TRI_json_t const* json) {
return json != nullptr && json->_type == TRI_JSON_NULL;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief determines whether the JSON passed is of type string
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsStringJson (TRI_json_t const* json);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds a new sub-object to an array, copying it

View File

@ -454,9 +454,9 @@ void TRI_InitVectorPointer (TRI_vector_pointer_t* vector,
/// @brief initialises a vector, with user-definable settings
////////////////////////////////////////////////////////////////////////////////
int TRI_InitVectorPointer2 (TRI_vector_pointer_t* vector,
TRI_memory_zone_t* zone,
size_t initialCapacity) {
int TRI_InitVectorPointer (TRI_vector_pointer_t* vector,
TRI_memory_zone_t* zone,
size_t initialCapacity) {
TRI_InitVectorPointer(vector, zone);
if (initialCapacity != 0) {
@ -608,14 +608,6 @@ bool TRI_EmptyVectorPointer (TRI_vector_pointer_t const* vector) {
return vector->_length == 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns length of the vector
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthVectorPointer (TRI_vector_pointer_t const* vector) {
return vector->_length;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clears the vector
////////////////////////////////////////////////////////////////////////////////
@ -974,14 +966,6 @@ bool TRI_EmptyVectorString (TRI_vector_string_t const* vector) {
return vector->_length == 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns length of vector
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthVectorString (TRI_vector_string_t const* vector) {
return vector->_length;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clears the vector
////////////////////////////////////////////////////////////////////////////////

View File

@ -245,9 +245,9 @@ void TRI_InitVectorPointer (TRI_vector_pointer_t*, TRI_memory_zone_t*);
/// @brief initialises a vector, with user-definable settings
////////////////////////////////////////////////////////////////////////////////
int TRI_InitVectorPointer2 (TRI_vector_pointer_t*,
TRI_memory_zone_t*,
size_t);
int TRI_InitVectorPointer (TRI_vector_pointer_t*,
TRI_memory_zone_t*,
size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a vector, but does not free the pointer
@ -303,7 +303,9 @@ bool TRI_EmptyVectorPointer (TRI_vector_pointer_t const*);
/// @brief returns length of vector
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthVectorPointer (TRI_vector_pointer_t const*);
static inline size_t TRI_LengthVectorPointer (TRI_vector_pointer_t const* vector) {
return vector->_length;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clears the vector
@ -431,7 +433,9 @@ bool TRI_EmptyVectorString (TRI_vector_string_t const*);
/// @brief returns length of vector
////////////////////////////////////////////////////////////////////////////////
size_t TRI_LengthVectorString (TRI_vector_string_t const*);
static inline size_t TRI_LengthVectorString (TRI_vector_string_t const* vector) {
return vector->_length;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clears the vector

View File

@ -28,7 +28,6 @@
////////////////////////////////////////////////////////////////////////////////
#include "shape-accessor.h"
#include "Basics/logging.h"
#include "Basics/vector.h"
#include "ShapedJson/json-shaper.h"
@ -71,6 +70,13 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
#endif
return false;
}
// we need at least 3 or 4 entries in the vector to store an accessor
TRI_vector_pointer_t ops;
if (TRI_InitVectorPointer(&ops, TRI_UNKNOWN_MEM_ZONE, 4) != TRI_ERROR_NO_ERROR) {
return false;
}
// find the attribute path
TRI_shape_path_t const* path = shaper->lookupAttributePathByPid(shaper, accessor->_pid);
@ -85,12 +91,6 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
TRI_shape_aid_t const* paids = (TRI_shape_aid_t*) (((char const*) path) + sizeof(TRI_shape_path_t));
// collect the bytecode
// we need at least 3 or 4 entries in the vector to store an accessor
TRI_vector_pointer_t ops;
TRI_InitVectorPointer2(&ops, TRI_UNKNOWN_MEM_ZONE, 4);
// and follow it
for (size_t i = 0; i < path->_aidLength; ++i, ++paids) {
#ifdef DEBUG_SHAPE_ACCESSOR
@ -102,39 +102,29 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
#endif
if (shape->_type == TRI_SHAPE_ARRAY) {
TRI_array_shape_t* s;
TRI_shape_aid_t const* aids;
TRI_shape_sid_t const* sids;
TRI_shape_sid_t sid;
TRI_shape_size_t const* offsetsF;
TRI_shape_size_t f;
TRI_shape_size_t n;
TRI_shape_size_t v;
char const* qtr;
s = (TRI_array_shape_t*) shape;
f = s->_fixedEntries;
v = s->_variableEntries;
n = f + v;
TRI_array_shape_t* s = (TRI_array_shape_t*) shape;
TRI_shape_size_t const f = s->_fixedEntries;
TRI_shape_size_t const v = s->_variableEntries;
TRI_shape_size_t n = f + v;
// find the aid within the shape
qtr = (char const*) shape;
char const* qtr = (char const*) shape;
qtr += sizeof(TRI_array_shape_t);
sids = (TRI_shape_sid_t const*) qtr;
TRI_shape_sid_t const* sids = (TRI_shape_sid_t const*) qtr;
qtr += n * sizeof(TRI_shape_sid_t);
aids = (TRI_shape_aid_t const*) qtr;
TRI_shape_aid_t const* aids = (TRI_shape_aid_t const*) qtr;
qtr += n * sizeof(TRI_shape_aid_t);
offsetsF = (TRI_shape_size_t const*) qtr;
TRI_shape_size_t const* offsetsF = (TRI_shape_size_t const*) qtr;
size_t j;
// check for fixed size aid
for (j = 0; j < f; ++j, ++sids, ++aids, ++offsetsF) {
if (*paids == *aids) {
sid = *sids;
TRI_shape_sid_t const sid = *sids;
LOG_TRACE("found aid '%ld' as fixed entry with sid '%ld' and offset '%ld' - '%ld'",
(unsigned long) *paids,
@ -145,31 +135,16 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
shape = shaper->lookupShapeId(shaper, sid);
if (shape == nullptr) {
LOG_ERROR("unknown shape id '%ld' for attribute id '%ld'",
(unsigned long) accessor->_sid,
(unsigned long) *paids);
LOG_ERROR("unknown shape id '%llu' for attribute id '%llu'",
(unsigned long long) accessor->_sid,
(unsigned long long) *paids);
TRI_DestroyVectorPointer(&ops);
return false;
}
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_FIX);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
res = TRI_PushBackVectorPointer(&ops, (void*) (uintptr_t) (offsetsF[0])); // offset is always smaller than 4 GByte
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
res = TRI_PushBackVectorPointer(&ops, (void*) (uintptr_t) (offsetsF[1])); // offset is always smaller than 4 GByte
// reserve a block big enough to hold the following 3 entries plus the final AC_DONE entry
int res = TRI_ReserveVectorPointer(&ops, 4);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
@ -177,6 +152,10 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
return false;
}
// this will always succeed as we reserve enough memory before
TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_FIX);
TRI_PushBackVectorPointer(&ops, (void*) (uintptr_t) (offsetsF[0])); // offset is always smaller than 4 GByte
TRI_PushBackVectorPointer(&ops, (void*) (uintptr_t) (offsetsF[1])); // offset is always smaller than 4 GByte
break;
}
}
@ -188,40 +167,35 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
// check for variable size aid
for (j = 0; j < v; ++j, ++sids, ++aids) {
if (*paids == *aids) {
sid = *sids;
TRI_shape_sid_t const sid = *sids;
LOG_TRACE("found aid '%ld' as variable entry with sid '%ld'",
(unsigned long) *paids,
(unsigned long) sid);
LOG_TRACE("found aid '%llu' as variable entry with sid '%llu'",
(unsigned long long) *paids,
(unsigned long long) sid);
shape = shaper->lookupShapeId(shaper, sid);
if (shape == nullptr) {
LOG_ERROR("unknown shape id '%ld' for attribute id '%ld'",
(unsigned long) accessor->_sid,
(unsigned long) *paids);
LOG_ERROR("unknown shape id '%llu' for attribute id '%llu'",
(unsigned long long) accessor->_sid,
(unsigned long long) *paids);
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_VAR);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
res = TRI_PushBackVectorPointer(&ops, (void*) j);
// reserve a block big enough to hold the following 2 entries plus the final AC_DONE entry
int res = TRI_ReserveVectorPointer(&ops, 3);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
// this will always succeed as we reserved enough memory in the vector before
TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_OFFSET_VAR);
TRI_PushBackVectorPointer(&ops, (void*) j);
break;
}
}
@ -230,7 +204,7 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
continue;
}
LOG_TRACE("unknown attribute id '%ld'", (unsigned long) *paids);
LOG_TRACE("unknown attribute id '%llu'", (unsigned long long) *paids);
}
TRI_DestroyVectorPointer(&ops);
@ -241,14 +215,9 @@ static bool BytecodeShapeAccessor (TRI_shaper_t* shaper,
return true;
}
// travel attribute path to the end
int res = TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_DONE);
if (res != TRI_ERROR_NO_ERROR) {
LOG_ERROR("out of memory");
TRI_DestroyVectorPointer(&ops);
return false;
}
// insert final "done" entry
// note that this must always succeed as we reserved enough space before
TRI_PushBackVectorPointer(&ops, (void*) TRI_SHAPE_AC_DONE);
// remember resulting sid
accessor->_resultSid = shape->_sid;

View File

@ -45,7 +45,7 @@
// -----------------------------------------------------------------------------
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json, size_t, bool);
static TRI_json_t* JsonShapeData (TRI_shaper_t* shaper, TRI_shape_t const* shape, char const* data, uint64_t size);
static int JsonShapeData (TRI_shaper_t* shaper, TRI_shape_t const* shape, TRI_json_t*, char const* data, uint64_t size);
static bool StringifyJsonShapeData (TRI_shaper_t* shaper, TRI_string_buffer_t* buffer, TRI_shape_t const* shape, char const* data, uint64_t size);
// -----------------------------------------------------------------------------
@ -968,126 +968,101 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper,
/// @brief converts a data null blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataNull (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
return TRI_CreateNullJson(shaper->_memoryZone);
static inline int JsonShapeDataNull (TRI_json_t* dst) {
TRI_InitNullJson(dst);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data boolean blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataBoolean (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
static inline int JsonShapeDataBoolean (TRI_json_t* dst,
char const* data) {
bool v = (* (TRI_shape_boolean_t const*) data) != 0;
return TRI_CreateBooleanJson(shaper->_memoryZone, v);
TRI_InitBooleanJson(dst, v);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data number blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataNumber (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
static inline int JsonShapeDataNumber (TRI_json_t* dst,
char const* data) {
TRI_shape_number_t v = * (TRI_shape_number_t const*) (void const*) data;
return TRI_CreateNumberJson(shaper->_memoryZone, v);
TRI_InitNumberJson(dst, v);
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data short string blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataShortString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
static inline int JsonShapeDataShortString (TRI_shaper_t* shaper,
TRI_json_t* dst,
char const* data) {
TRI_shape_length_short_string_t l = * (TRI_shape_length_short_string_t const*) data;
data += sizeof(TRI_shape_length_short_string_t);
return TRI_CreateStringCopyJson(shaper->_memoryZone, data, (size_t) (l - 1));
return TRI_InitStringCopyJson(shaper->_memoryZone, dst, data, static_cast<size_t>(l - 1));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data long string blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataLongString (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
static inline int JsonShapeDataLongString (TRI_shaper_t* shaper,
TRI_json_t* dst,
char const* data) {
TRI_shape_length_long_string_t l = * (TRI_shape_length_long_string_t const*) data;
data += sizeof(TRI_shape_length_long_string_t);
return TRI_CreateStringCopyJson(shaper->_memoryZone, data, l - 1);
return TRI_InitStringCopyJson(shaper->_memoryZone, dst, data, static_cast<size_t>(l - 1));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data array blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_array_shape_t const* s;
TRI_shape_size_t f;
TRI_shape_size_t v;
TRI_shape_size_t n;
TRI_shape_size_t i;
char const* qtr;
TRI_json_t* array;
TRI_shape_sid_t const* sids;
TRI_shape_aid_t const* aids;
TRI_shape_size_t const* offsetsF;
TRI_shape_size_t const* offsetsV;
shape_cache_t shapeCache;
s = (TRI_array_shape_t const*) shape;
f = s->_fixedEntries;
v = s->_variableEntries;
n = f + v;
static int JsonShapeDataArray (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
TRI_json_t* dst,
char const* data,
uint64_t size) {
TRI_array_shape_t const* s = (TRI_array_shape_t const*) shape;
TRI_shape_size_t const f = s->_fixedEntries;
TRI_shape_size_t const v = s->_variableEntries;
TRI_shape_size_t const n = f + v;
// create an array with the appropriate size
array = TRI_CreateObjectJson(shaper->_memoryZone, (size_t) n);
TRI_InitObjectJson(shaper->_memoryZone, dst, static_cast<size_t>(n));
if (array == nullptr) {
return nullptr;
int res = TRI_ReserveVector(&dst->_value._objects, static_cast<size_t>(n * 2));
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
qtr = (char const*) shape;
char const* qtr = (char const*) shape;
qtr += sizeof(TRI_array_shape_t);
sids = (TRI_shape_sid_t const*) qtr;
TRI_shape_sid_t const* sids = (TRI_shape_sid_t const*) qtr;
qtr += n * sizeof(TRI_shape_sid_t);
aids = (TRI_shape_aid_t const*) qtr;
TRI_shape_aid_t const* aids = (TRI_shape_aid_t const*) qtr;
qtr += n * sizeof(TRI_shape_aid_t);
offsetsF = (TRI_shape_size_t const*) qtr;
TRI_shape_size_t const* offsetsF = (TRI_shape_size_t const*) qtr;
shape_cache_t shapeCache;
shapeCache._sid = 0;
shapeCache._shape = nullptr;
for (i = 0; i < f; ++i, ++sids, ++aids, ++offsetsF) {
for (TRI_shape_size_t i = 0; i < f; ++i, ++sids, ++aids, ++offsetsF) {
TRI_shape_sid_t sid = *sids;
TRI_shape_aid_t aid = *aids;
TRI_shape_size_t offset;
TRI_shape_t const* subshape;
char const* name;
TRI_json_t* element;
offset = *offsetsF;
// use last sid if in cache
if (sid == shapeCache._sid && shapeCache._sid > 0) {
@ -1103,35 +1078,45 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
continue;
}
name = shaper->lookupAttributeId(shaper, aid);
char const* name = shaper->lookupAttributeId(shaper, aid);
if (name == nullptr) {
LOG_WARNING("cannot find attribute #%u", (unsigned int) aid);
continue;
}
element = JsonShapeData(shaper, subshape, data + offset, offsetsF[1] - offset);
TRI_shape_size_t offset = *offsetsF;
// calculate target address for key
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = TRI_InitStringCopyJson(shaper->_memoryZone, next, name, strlen(name));
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
if (res != TRI_ERROR_NO_ERROR) {
// return the element
TRI_ReturnVector(&dst->_value._objects);
return res;
}
// save position of key
auto key = next;
TRI_Insert2ObjectJson(shaper->_memoryZone, array, name, element);
TRI_Free(shaper->_memoryZone, element);
// calculate target address for value
next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = JsonShapeData(shaper, subshape, next, data + offset, offsetsF[1] - offset);
if (res != TRI_ERROR_NO_ERROR) {
TRI_DestroyJson(shaper->_memoryZone, key);
TRI_ReturnVector(&dst->_value._objects);
TRI_ReturnVector(&dst->_value._objects);
return res;
}
}
offsetsV = (TRI_shape_size_t const*) data;
TRI_shape_size_t const* offsetsV = (TRI_shape_size_t const*) data;
for (i = 0; i < v; ++i, ++sids, ++aids, ++offsetsV) {
for (TRI_shape_size_t i = 0; i < v; ++i, ++sids, ++aids, ++offsetsV) {
TRI_shape_sid_t sid = *sids;
TRI_shape_aid_t aid = *aids;
TRI_shape_size_t offset;
TRI_shape_t const* subshape;
char const* name;
TRI_json_t* element;
offset = *offsetsV;
// use last sid if in cache
if (sid == shapeCache._sid && shapeCache._sid > 0) {
@ -1147,74 +1132,79 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
continue;
}
name = shaper->lookupAttributeId(shaper, aid);
char const* name = shaper->lookupAttributeId(shaper, aid);
if (name == nullptr) {
LOG_WARNING("cannot find attribute #%u", (unsigned int) aid);
continue;
}
element = JsonShapeData(shaper, subshape, data + offset, offsetsV[1] - offset);
TRI_shape_size_t offset = *offsetsV;
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
// calculate target address for key
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = TRI_InitStringCopyJson(shaper->_memoryZone, next, name, strlen(name));
if (res != TRI_ERROR_NO_ERROR) {
// return the element
TRI_ReturnVector(&dst->_value._objects);
return res;
}
TRI_Insert2ObjectJson(shaper->_memoryZone, array, name, element);
TRI_Free(shaper->_memoryZone, element);
// save position of key
auto key = next;
// calculate target address for value
next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = JsonShapeData(shaper, subshape, next, data + offset, offsetsV[1] - offset);
if (res != TRI_ERROR_NO_ERROR) {
TRI_DestroyJson(shaper->_memoryZone, key);
TRI_ReturnVector(&dst->_value._objects);
TRI_ReturnVector(&dst->_value._objects);
return res;
}
}
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, array);
return nullptr;
}
return array;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data list blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
char const* ptr;
TRI_shape_sid_t const* sids;
TRI_shape_size_t const* offsets;
TRI_shape_length_list_t l;
TRI_shape_length_list_t i;
shape_cache_t shapeCache;
static int JsonShapeDataList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
TRI_json_t* dst,
char const* data,
uint64_t size) {
char const* ptr = data;
TRI_shape_length_list_t const l = * (TRI_shape_length_list_t const*) ptr;
ptr = data;
l = * (TRI_shape_length_list_t const*) ptr;
// create an array with the appropriate size
TRI_InitArrayJson(shaper->_memoryZone, dst, static_cast<size_t>(l));
// create a list with the appropriate size
TRI_json_t* list = TRI_CreateArrayJson(shaper->_memoryZone, (size_t) l);
int res = TRI_ReserveVector(&dst->_value._objects, static_cast<size_t>(l));
if (list == nullptr) {
return nullptr;
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
ptr += sizeof(TRI_shape_length_list_t);
sids = (TRI_shape_sid_t const*) ptr;
TRI_shape_sid_t const* sids = (TRI_shape_sid_t const*) ptr;
ptr += l * sizeof(TRI_shape_sid_t);
offsets = (TRI_shape_size_t const*) ptr;
TRI_shape_size_t const* offsets = (TRI_shape_size_t const*) ptr;
shape_cache_t shapeCache;
shapeCache._sid = 0;
shapeCache._shape = nullptr;
for (i = 0; i < l; ++i, ++sids, ++offsets) {
for (TRI_shape_length_list_t i = 0; i < l; ++i, ++sids, ++offsets) {
TRI_shape_sid_t sid = *sids;
TRI_shape_size_t offset;
TRI_shape_t const* subshape;
TRI_json_t* element;
offset = *offsets;
TRI_shape_size_t offset = *offsets;
// use last sid if in cache
if (sid == shapeCache._sid && shapeCache._sid > 0) {
@ -1229,191 +1219,167 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
continue;
}
// calculate target address for key
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = JsonShapeData(shaper, subshape, next, data + offset, offsets[1] - offset);
element = JsonShapeData(shaper, subshape, data + offset, offsets[1] - offset);
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
if (res != TRI_ERROR_NO_ERROR) {
// return the element
TRI_ReturnVector(&dst->_value._objects);
return res;
}
TRI_PushBack2ArrayJson(list, element);
TRI_Free(shaper->_memoryZone, element);
}
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, list);
return nullptr;
}
return list;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data homogeneous list blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataHomogeneousList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_homogeneous_list_shape_t const* s;
TRI_shape_length_list_t i;
TRI_shape_length_list_t l;
TRI_shape_sid_t sid;
TRI_shape_size_t const* offsets;
char const* ptr;
s = (TRI_homogeneous_list_shape_t const*) shape;
sid = s->_sidEntry;
static int JsonShapeDataHomogeneousList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
TRI_json_t* dst,
char const* data,
uint64_t size) {
TRI_homogeneous_list_shape_t const* s = (TRI_homogeneous_list_shape_t const*) shape;
TRI_shape_sid_t const sid = s->_sidEntry;
TRI_shape_t const* subshape = shaper->lookupShapeId(shaper, sid);
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
return nullptr;
return TRI_ERROR_INTERNAL;
}
ptr = data;
l = * (TRI_shape_length_list_t const*) ptr;
char const* ptr = data;
TRI_shape_length_list_t const l = * (TRI_shape_length_list_t const*) ptr;
// create a list with the appropriate size
TRI_json_t* list = TRI_CreateArrayJson(shaper->_memoryZone, (size_t) l);
// create an array with the appropriate size
TRI_InitArrayJson(shaper->_memoryZone, dst, static_cast<size_t>(l));
if (list == nullptr) {
return nullptr;
int res = TRI_ReserveVector(&dst->_value._objects, static_cast<size_t>(l));
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
ptr += sizeof(TRI_shape_length_list_t);
offsets = (TRI_shape_size_t const*) ptr;
TRI_shape_size_t const* offsets = (TRI_shape_size_t const*) ptr;
for (i = 0; i < l; ++i, ++offsets) {
TRI_shape_size_t offset;
TRI_json_t* element;
for (TRI_shape_length_list_t i = 0; i < l; ++i, ++offsets) {
TRI_shape_size_t offset = *offsets;
offset = *offsets;
element = JsonShapeData(shaper, subshape, data + offset, offsets[1] - offset);
// calculate target address for key
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = JsonShapeData(shaper, subshape, next, data + offset, offsets[1] - offset);
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
if (res != TRI_ERROR_NO_ERROR) {
// return the element
TRI_ReturnVector(&dst->_value._objects);
return res;
}
TRI_PushBack2ArrayJson(list, element);
TRI_Free(shaper->_memoryZone, element);
}
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, list);
return nullptr;
}
return list;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data homogeneous sized list blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeDataHomogeneousSizedList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
TRI_homogeneous_sized_list_shape_t const* s;
TRI_shape_length_list_t i;
TRI_shape_length_list_t l;
TRI_shape_sid_t sid;
TRI_shape_size_t length;
TRI_shape_size_t offset;
char const* ptr;
s = (TRI_homogeneous_sized_list_shape_t const*) shape;
sid = s->_sidEntry;
static int JsonShapeDataHomogeneousSizedList (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
TRI_json_t* dst,
char const* data,
uint64_t size) {
TRI_homogeneous_sized_list_shape_t const* s = (TRI_homogeneous_sized_list_shape_t const*) shape;
TRI_shape_sid_t const sid = s->_sidEntry;
TRI_shape_t const* subshape = shaper->lookupShapeId(shaper, sid);
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
return nullptr;
return TRI_ERROR_INTERNAL;
}
ptr = data;
l = * (TRI_shape_length_list_t const*) ptr;
char const* ptr = data;
TRI_shape_length_list_t const l = * (TRI_shape_length_list_t const*) ptr;
// create a list with the appropriate size
TRI_json_t* list = TRI_CreateArrayJson(shaper->_memoryZone, (size_t) l);
// create an array with the appropriate size
TRI_InitArrayJson(shaper->_memoryZone, dst, static_cast<size_t>(l));
if (list == nullptr) {
return nullptr;
int res = TRI_ReserveVector(&dst->_value._objects, static_cast<size_t>(l));
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
length = s->_sizeEntry;
offset = sizeof(TRI_shape_length_list_t);
TRI_shape_size_t const length = s->_sizeEntry;
TRI_shape_size_t offset = sizeof(TRI_shape_length_list_t);
for (i = 0; i < l; ++i, offset += length) {
TRI_json_t* element;
for (TRI_shape_length_list_t i = 0; i < l; ++i, offset += length) {
// calculate target address for key
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&dst->_value._objects));
res = JsonShapeData(shaper, subshape, next, data + offset, length);
element = JsonShapeData(shaper, subshape, data + offset, length);
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
if (res != TRI_ERROR_NO_ERROR) {
// return the element
TRI_ReturnVector(&dst->_value._objects);
return res;
}
TRI_PushBack2ArrayJson(list, element);
TRI_Free(shaper->_memoryZone, element);
}
return list;
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a data blob into a json object
////////////////////////////////////////////////////////////////////////////////
static TRI_json_t* JsonShapeData (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
static int JsonShapeData (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
TRI_json_t* dst,
char const* data,
uint64_t size) {
if (shape == nullptr) {
return nullptr;
return TRI_ERROR_INTERNAL;
}
switch (shape->_type) {
case TRI_SHAPE_NULL:
return JsonShapeDataNull(shaper, shape, data, size);
return JsonShapeDataNull(dst);
case TRI_SHAPE_BOOLEAN:
return JsonShapeDataBoolean(shaper, shape, data, size);
return JsonShapeDataBoolean(dst, data);
case TRI_SHAPE_NUMBER:
return JsonShapeDataNumber(shaper, shape, data, size);
return JsonShapeDataNumber(dst, data);
case TRI_SHAPE_SHORT_STRING:
return JsonShapeDataShortString(shaper, shape, data, size);
return JsonShapeDataShortString(shaper, dst, data);
case TRI_SHAPE_LONG_STRING:
return JsonShapeDataLongString(shaper, shape, data, size);
return JsonShapeDataLongString(shaper, dst, data);
case TRI_SHAPE_ARRAY:
return JsonShapeDataArray(shaper, shape, data, size);
return JsonShapeDataArray(shaper, shape, dst, data, size);
case TRI_SHAPE_LIST:
return JsonShapeDataList(shaper, shape, data, size);
return JsonShapeDataList(shaper, shape, dst, data, size);
case TRI_SHAPE_HOMOGENEOUS_LIST:
return JsonShapeDataHomogeneousList(shaper, shape, data, size);
return JsonShapeDataHomogeneousList(shaper, shape, dst, data, size);
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
return JsonShapeDataHomogeneousSizedList(shaper, shape, data, size);
return JsonShapeDataHomogeneousSizedList(shaper, shape, dst, data, size);
}
return nullptr;
return TRI_ERROR_INTERNAL;
}
////////////////////////////////////////////////////////////////////////////////
@ -2174,7 +2140,21 @@ TRI_json_t* TRI_JsonShapedJson (TRI_shaper_t* shaper,
return nullptr;
}
return JsonShapeData(shaper, shape, shaped->_data.data, shaped->_data.length);
auto dst = TRI_CreateNullJson(shaper->_memoryZone);
if (dst == nullptr) {
// out of memory
return nullptr;
}
int res = JsonShapeData(shaper, shape, dst, shaped->_data.data, shaped->_data.length);
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(shaper->_memoryZone, dst);
return nullptr;
}
return dst;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -1758,7 +1758,7 @@ static int ObjectToJson (v8::Isolate* isolate,
for (uint32_t i = 0; i < n; ++i) {
// get address of next element
TRI_json_t* next = static_cast<TRI_json_t*>(TRI_NextVector(&result->_value._objects));
auto next = static_cast<TRI_json_t*>(TRI_NextVector(&result->_value._objects));
// the reserve call above made sure we could not have run out of memory
TRI_ASSERT_EXPENSIVE(next != nullptr);