mirror of https://gitee.com/bigwinds/arangodb
Neighbors is now able to take exactly one edge example onto the CPP level. Now working on a list of examples
This commit is contained in:
parent
b0723dbb75
commit
76c33a577c
|
@ -220,6 +220,22 @@ class SimpleEdgeExpander {
|
|||
// --SECTION-- ShortestPathOptions FUNCTIONS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Insert a new edge matcher object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ShortestPathOptions::addEdgeFilter(
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_voc_cid_t const& cid,
|
||||
string& errorMessage) {
|
||||
auto it = _edgeFilter.find(cid);
|
||||
if (it == _edgeFilter.end()) {
|
||||
_edgeFilter.emplace(cid, new ExampleMatcher(isolate, example, shaper, errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks if an edge matches to given examples
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -238,22 +254,6 @@ bool ShortestPathOptions::matchesEdge(EdgeId& e, TRI_doc_mptr_copy_t* edge) cons
|
|||
return it->second->matches(edge);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Insert a new edge matcher object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ShortestPathOptions::addEdgeFilter(
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_voc_cid_t const& cid,
|
||||
string& errorMessage) {
|
||||
auto it = _edgeFilter.find(cid);
|
||||
if (it == _edgeFilter.end()) {
|
||||
_edgeFilter.emplace(cid, new ExampleMatcher(isolate, example, shaper, errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Insert a new vertex matcher object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -304,6 +304,45 @@ bool ShortestPathOptions::matchesVertex(VertexId& v) const {
|
|||
return it->second.matcher->matches(&vertex);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- NeighborsOptions FUNCTIONS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Insert a new edge matcher object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void NeighborsOptions::addEdgeFilter(
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_voc_cid_t const& cid,
|
||||
string& errorMessage) {
|
||||
auto it = _edgeFilter.find(cid);
|
||||
if (it == _edgeFilter.end()) {
|
||||
_edgeFilter.emplace(cid, new ExampleMatcher(isolate, example, shaper, errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks if an edge matches to given examples
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool NeighborsOptions::matchesEdge(EdgeId& e, TRI_doc_mptr_copy_t* edge) const {
|
||||
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(edge);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private Helper Functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -361,9 +400,12 @@ void TRI_RunNeighborsSearch (
|
|||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
auto p = distinct.insert(extractFromId(edges[j]));
|
||||
if (p.second) {
|
||||
result.push_back(*p.first);
|
||||
EdgeId edgeId = col->extractEdgeId(edges[j]);
|
||||
if (opts.matchesEdge(edgeId, &edges[j])) {
|
||||
auto p = distinct.insert(extractFromId(edges[j]));
|
||||
if (p.second) {
|
||||
result.push_back(*p.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -373,9 +415,12 @@ void TRI_RunNeighborsSearch (
|
|||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
auto p = distinct.insert(extractToId(edges[j]));
|
||||
if (p.second) {
|
||||
result.push_back(*p.first);
|
||||
EdgeId edgeId = col->extractEdgeId(edges[j]);
|
||||
if (opts.matchesEdge(edgeId, &edges[j])) {
|
||||
auto p = distinct.insert(extractToId(edges[j]));
|
||||
if (p.second) {
|
||||
result.push_back(*p.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,7 +431,10 @@ void TRI_RunNeighborsSearch (
|
|||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractFromId(edges[j]));
|
||||
EdgeId edgeId = col->extractEdgeId(edges[j]);
|
||||
if (opts.matchesEdge(edgeId, &edges[j])) {
|
||||
result.push_back(extractFromId(edges[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,7 +443,10 @@ void TRI_RunNeighborsSearch (
|
|||
for (auto col : collectionInfos) {
|
||||
auto edges = col->getEdges(dir, opts.start);
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
result.push_back(extractToId(edges[j]));
|
||||
EdgeId edgeId = col->extractEdgeId(edges[j]);
|
||||
if (opts.matchesEdge(edgeId, &edges[j])) {
|
||||
result.push_back(extractToId(edges[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,14 +184,30 @@ namespace triagens {
|
|||
};
|
||||
|
||||
struct NeighborsOptions {
|
||||
TRI_edge_direction_e direction;
|
||||
bool distinct;
|
||||
VertexId start;
|
||||
private:
|
||||
std::unordered_map<TRI_voc_cid_t, triagens::arango::ExampleMatcher*> _edgeFilter;
|
||||
|
||||
NeighborsOptions () :
|
||||
direction(TRI_EDGE_OUT),
|
||||
distinct(true) {
|
||||
}
|
||||
public:
|
||||
TRI_edge_direction_e direction;
|
||||
bool distinct;
|
||||
VertexId start;
|
||||
bool useEdgeFilter;
|
||||
|
||||
NeighborsOptions () :
|
||||
direction(TRI_EDGE_OUT),
|
||||
distinct(true),
|
||||
useEdgeFilter(false) {
|
||||
}
|
||||
|
||||
void addEdgeFilter (
|
||||
v8::Isolate* isolate,
|
||||
v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_voc_cid_t const& cid,
|
||||
std::string& errorMessage
|
||||
);
|
||||
|
||||
bool matchesEdge (EdgeId& e, TRI_doc_mptr_copy_t* edge) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -2155,7 +2155,7 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
|
||||
traverser::NeighborsOptions opts;
|
||||
bool includeData = false;
|
||||
v8::Handle<v8::Object> vertexExample;
|
||||
v8::Handle<v8::Object> edgeExample;
|
||||
|
||||
if (args.Length() == 4) {
|
||||
if (! args[3]->IsObject()) {
|
||||
|
@ -2190,6 +2190,12 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
includeData = TRI_ObjectToBoolean(options->Get(keyIncludeData));
|
||||
}
|
||||
|
||||
// Parse examples
|
||||
v8::Local<v8::String> keyExamples = TRI_V8_ASCII_STRING("examples");
|
||||
if (options->Has(keyExamples)) {
|
||||
opts.useEdgeFilter = true;
|
||||
edgeExample = v8::Handle<v8::Object>::Cast(options->Get(keyExamples));
|
||||
}
|
||||
}
|
||||
|
||||
vector<TRI_voc_cid_t> readCollections;
|
||||
|
@ -2249,6 +2255,21 @@ static void JS_QueryNeighbors (const v8::FunctionCallbackInfo<v8::Value>& args)
|
|||
|
||||
unordered_set<VertexId> distinctNeighbors;
|
||||
vector<VertexId> neighbors;
|
||||
|
||||
if (opts.useEdgeFilter) {
|
||||
string errorMessage;
|
||||
for (auto it: edgeCollectionInfos) {
|
||||
try {
|
||||
opts.addEdgeFilter(isolate, edgeExample, it->getShaper(), it->getCid(), errorMessage);
|
||||
} catch (int e) {
|
||||
// ELEMENT not found is expected, if there is no shape of this type in this collection
|
||||
if (e != TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
// TODO Max fragen was mit Fehlern passieren muss
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& startVertex : startVertices) {
|
||||
try {
|
||||
opts.start = idStringToVertexId(resolver, startVertex);
|
||||
|
|
|
@ -6523,18 +6523,18 @@ function AQL_NEIGHBORS (vertexCollection,
|
|||
vertex = TO_ID(vertex, vertexCollection);
|
||||
options = options || {};
|
||||
options.direction = direction;
|
||||
options.examples = examples;
|
||||
if (examples === undefined ||
|
||||
(Array.isArray(examples) && examples.length === 0)) {
|
||||
(Array.isArray(examples) && examples.length <= 1)) {
|
||||
if (examples.length === 1) {
|
||||
options.examples = examples[0];
|
||||
}
|
||||
if (typeof options.distance === "number" && options.distance > 1) {
|
||||
return useCXXforDeepNeighbors(vertexCollection, edgeCollection, vertex,
|
||||
options);
|
||||
}
|
||||
else {
|
||||
var x = CPP_NEIGHBORS([vertexCollection], [edgeCollection], vertex, options);
|
||||
return x;
|
||||
// return CPP_NEIGHBORS([vertexCollection], [edgeCollection], vertex,
|
||||
// options);
|
||||
return CPP_NEIGHBORS([vertexCollection], [edgeCollection], vertex,
|
||||
options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue