diff --git a/arangod/V8Server/V8Traverser.cpp b/arangod/V8Server/V8Traverser.cpp index ce8dd3eaef..20c0e8d2b4 100644 --- a/arangod/V8Server/V8Traverser.cpp +++ b/arangod/V8Server/V8Traverser.cpp @@ -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 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 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 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::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 const& example, - TRI_shaper_t* shaper, - TRI_voc_cid_t const& cid, - string& errorMessage) { +void BasicOptions::addEdgeFilter (v8::Isolate* isolate, + v8::Handle 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::Cast(example), shaper, errorMessage)); } - } else { + } + else { // Has to be Object if (it == _edgeFilter.end()) { _edgeFilter.emplace(cid, new ExampleMatcher(isolate, v8::Handle::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 TRI_RunShortestPathSearch ( +unique_ptr TRI_RunShortestPathSearch ( vector& 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 TRI_RunShortestPathSearch ( /// @brief search for distinct inbound neighbors //////////////////////////////////////////////////////////////////////////////// -static void inboundNeighbors ( - vector& collectionInfos, - NeighborsOptions& opts, - unordered_set& startVertices, - unordered_set& visited, - unordered_set& distinct, - vector& result, - uint64_t depth = 1) { +static void InboundNeighbors (vector& collectionInfos, + NeighborsOptions& opts, + unordered_set& startVertices, + unordered_set& visited, + unordered_set& distinct, + vector& result, + uint64_t depth = 1) { + TRI_edge_direction_e dir = TRI_EDGE_IN; unordered_set 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& collectionInfos, - NeighborsOptions& opts, - unordered_set& startVertices, - unordered_set& visited, - unordered_set& distinct, - vector& result, - uint64_t depth = 1) { +static void OutboundNeighbors (vector& collectionInfos, + NeighborsOptions& opts, + unordered_set& startVertices, + unordered_set& visited, + unordered_set& distinct, + vector& result, + uint64_t depth = 1) { + TRI_edge_direction_e dir = TRI_EDGE_OUT; + unordered_set 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& collectionInfos, - NeighborsOptions& opts, - unordered_set& startVertices, - unordered_set& visited, - unordered_set& distinct, - vector& result, - uint64_t depth = 1) { +static void AnyNeighbors (vector& collectionInfos, + NeighborsOptions& opts, + unordered_set& startVertices, + unordered_set& visited, + unordered_set& distinct, + vector& result, + uint64_t depth = 1) { TRI_edge_direction_e dir = TRI_EDGE_OUT; unordered_set 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; } -}; +} + diff --git a/arangod/V8Server/V8Traverser.h b/arangod/V8Server/V8Traverser.h index 67ddfd0e70..fb21c4aaa3 100644 --- a/arangod/V8Server/V8Traverser.h +++ b/arangod/V8Server/V8Traverser.h @@ -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 { public: - size_t operator()(VertexId const& s) const { + size_t operator() (VertexId const& s) const { size_t h1 = std::hash()(s.cid); size_t h2 = TRI_FnvHashString(s.key); return h1 ^ ( h2 << 1 ); @@ -78,7 +80,7 @@ namespace std { template<> struct equal_to { 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 { 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 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 const& example, + TRI_shaper_t* shaper, + TRI_voc_cid_t const& cid, + std::string& errorMessage); - void addEdgeFilter ( - v8::Isolate* isolate, - v8::Handle const& example, - TRI_shaper_t* shaper, - TRI_voc_cid_t const& cid, - std::string& errorMessage - ); - - void addVertexFilter ( - v8::Isolate* isolate, - v8::Handle 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 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 getEdges (TRI_edge_direction_e& direction, - VertexId& vertexId) { + std::vector getEdges (TRI_edge_direction_e direction, + VertexId const& vertexId) const { return TRI_LookupEdgesDocumentCollection(_edgeCollection, direction, vertexId.cid, const_cast(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 TRI_RunShortestPathSearch ( std::vector& collectionInfos, triagens::basics::traverser::ShortestPathOptions& opts @@ -350,11 +357,9 @@ std::unique_ptr TRI_RunShortestPathSearch ( /// @brief Wrapper for the neighbors computation //////////////////////////////////////////////////////////////////////////////// -void TRI_RunNeighborsSearch ( - std::vector& collectionInfos, - triagens::basics::traverser::NeighborsOptions& opts, - std::unordered_set& distinct, - std::vector& result -); +void TRI_RunNeighborsSearch (std::vector& collectionInfos, + triagens::basics::traverser::NeighborsOptions& opts, + std::unordered_set& distinct, + std::vector& result); #endif diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index a3aa7ba10f..f93cada348 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -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; } diff --git a/arangod/VocBase/ExampleMatcher.h b/arangod/VocBase/ExampleMatcher.h index 3b6df75865..26949a2302 100644 --- a/arangod/VocBase/ExampleMatcher.h +++ b/arangod/VocBase/ExampleMatcher.h @@ -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 definitions; - void fillExampleDefinition ( - v8::Isolate* isolate, - v8::Handle const& example, - v8::Handle const& names, - size_t& n, - std::string& errorMessage, - ExampleDefinition& def - ); - + void fillExampleDefinition (v8::Isolate* isolate, + v8::Handle const& example, + v8::Handle const& names, + size_t& n, + std::string& errorMessage, + ExampleDefinition& def); public: - ExampleMatcher ( - v8::Isolate* isolate, - v8::Handle const example, - TRI_shaper_t* shaper, - std::string& errorMessage - ); + ExampleMatcher (v8::Isolate* isolate, + v8::Handle const example, + TRI_shaper_t* shaper, + std::string& errorMessage); - ExampleMatcher ( - v8::Isolate* isolate, - v8::Handle const examples, - TRI_shaper_t* shaper, - std::string& errorMessage - ); + ExampleMatcher (v8::Isolate* isolate, + v8::Handle 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: