1
0
Fork 0

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:
Michael Hackstein 2015-05-25 12:39:44 -07:00
parent b0723dbb75
commit 76c33a577c
4 changed files with 126 additions and 38 deletions

View File

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

View File

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

View File

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

View File

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