1
0
Fork 0

Merge branch 'cppTrav' of ssh://github.com/arangodb/arangodb into cppTrav

This commit is contained in:
Max Neunhoeffer 2015-04-30 23:10:24 -07:00
commit cb9fa2a342
11 changed files with 434 additions and 157 deletions

View File

@ -45,22 +45,75 @@ using namespace std;
using namespace triagens::basics;
using namespace triagens::arango;
struct WeightInfo {
string keyWeight;
double defaultWeight;
bool usesWeight;
////////////////////////////////////////////////////////////////////////////////
/// @brief callback to weight an edge
////////////////////////////////////////////////////////////////////////////////
WeightInfo(
typedef function<double(TRI_doc_mptr_copy_t& edge)> WeightCalculatorFunction;
////////////////////////////////////////////////////////////////////////////////
/// @brief Define edge weight by the number of hops.
/// Respectively 1 for any edge.
////////////////////////////////////////////////////////////////////////////////
class HopWeightCalculator {
public:
HopWeightCalculator() {};
////////////////////////////////////////////////////////////////////////////////
/// @brief Callable weight calculator for edge
////////////////////////////////////////////////////////////////////////////////
double operator() (TRI_doc_mptr_copy_t& edge) {
return 1;
};
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Define edge weight by ony special attribute.
/// Respectively 1 for any edge.
////////////////////////////////////////////////////////////////////////////////
class AttributeWeightCalculator {
TRI_shape_pid_t _shape_pid;
double _defaultWeight;
TRI_shaper_t* _shaper;
public:
AttributeWeightCalculator(
string keyWeight,
double defaultWeight
) :
keyWeight(keyWeight), defaultWeight(defaultWeight), usesWeight(true)
double defaultWeight,
TRI_shaper_t* shaper
) : _defaultWeight(defaultWeight),
_shaper(shaper)
{
_shape_pid = _shaper->lookupAttributePathByName(_shaper, keyWeight.c_str());
};
WeightInfo() : usesWeight(false) {
////////////////////////////////////////////////////////////////////////////////
/// @brief Callable weight calculator for edge
////////////////////////////////////////////////////////////////////////////////
double operator() (TRI_doc_mptr_copy_t& edge) {
if (_shape_pid == 0) {
return _defaultWeight;
}
TRI_shape_sid_t sid;
TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER(sid, edge.getDataPtr());
TRI_shape_access_t const* accessor = TRI_FindAccessorVocShaper(_shaper, sid, _shape_pid);
TRI_shaped_json_t shapedJson;
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, edge.getDataPtr());
TRI_shaped_json_t resultJson;
TRI_ExecuteShapeAccessor(accessor, &shapedJson, &resultJson);
if (resultJson._sid != TRI_SHAPE_NUMBER) {
return _defaultWeight;
}
TRI_json_t* json = TRI_JsonShapedJson(_shaper, &resultJson);
if (json == nullptr) {
return _defaultWeight;
}
double realResult = json->_value._number;
TRI_FreeJson(_shaper->_memoryZone, json);
return realResult ;
};
};
class SimpleEdgeExpander {
@ -90,33 +143,20 @@ class SimpleEdgeExpander {
CollectionNameResolver* resolver;
////////////////////////////////////////////////////////////////////////////////
/// @brief this is the information required to compute weight by a given
/// attribute. It contains an indicator if weight should be used.
/// Also it includes a default weight and the name of the weight
/// attribute.
/// @brief the weight calculation function
////////////////////////////////////////////////////////////////////////////////
WeightInfo weightInfo;
WeightCalculatorFunction weighter;
public:
SimpleEdgeExpander(TRI_edge_direction_e direction,
TRI_document_collection_t* edgeCollection,
string edgeCollectionName,
CollectionNameResolver* resolver)
: direction(direction), edgeCollection(edgeCollection),
resolver(resolver)
{
edgeIdPrefix = edgeCollectionName + "/";
};
SimpleEdgeExpander(TRI_edge_direction_e direction,
TRI_document_collection_t* edgeCollection,
string edgeCollectionName,
CollectionNameResolver* resolver,
WeightInfo weightInfo)
WeightCalculatorFunction weighter)
: direction(direction), edgeCollection(edgeCollection),
resolver(resolver), weightInfo(weightInfo)
resolver(resolver), weighter(weighter)
{
edgeIdPrefix = edgeCollectionName + "/";
};
@ -170,17 +210,16 @@ class SimpleEdgeExpander {
unordered_map<Traverser::VertexId, size_t> candidates;
Traverser::VertexId from;
Traverser::VertexId to;
if (weightInfo.usesWeight) {
for (size_t j = 0; j < edges.size(); ++j) {
from = extractFromId(edges[j]);
to = extractToId(edges[j]);
double currentWeight = weightInfo.defaultWeight;
if (from != source) {
auto cand = candidates.find(from);
double currentWeight = weighter(edges[j]);
auto inserter = [&](Traverser::VertexId s, Traverser::VertexId t) {
auto cand = candidates.find(t);
if (cand == candidates.end()) {
// Add weight
result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
candidates.emplace(from, result.size() - 1);
result.emplace_back(t, s, currentWeight, extractEdgeId(edges[j]));
candidates.emplace(t, result.size() - 1);
} else {
// Compare weight
auto oldWeight = result[cand->second].weight();
@ -188,40 +227,12 @@ class SimpleEdgeExpander {
result[cand->second].setWeight(currentWeight);
}
}
}
else if (to != source) {
auto cand = candidates.find(to);
if (cand == candidates.end()) {
// Add weight
result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
candidates.emplace(to, result.size() - 1);
} else {
auto oldWeight = result[cand->second].weight();
if (currentWeight < oldWeight) {
result[cand->second].setWeight(currentWeight);
}
}
}
}
}
else {
for (size_t j = 0; j < edges.size(); ++j) {
from = extractFromId(edges[j]);
to = extractToId(edges[j]);
};
if (from != source) {
auto cand = candidates.find(from);
if (cand == candidates.end()) {
result.emplace_back(from, to, 1, extractEdgeId(edges[j]));
candidates.emplace(from, result.size()-1);
}
inserter(to, from);
}
else if (to != source) {
auto cand = candidates.find(to);
if (cand == candidates.end()) {
result.emplace_back(to, from, 1, extractEdgeId(edges[j]));
candidates.emplace(to, result.size()-1);
}
}
inserter(from, to);
}
}
}
@ -283,7 +294,7 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
vector<string> writeCollections;
double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
bool embed = false;
bool embed = true;
bool waitForSync = false;
// get the vertex collection
@ -409,15 +420,16 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
unique_ptr<SimpleEdgeExpander> forwardExpander;
unique_ptr<SimpleEdgeExpander> backwardExpander;
WeightCalculatorFunction weighter;
if (useWeight) {
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName,
&resolver1, WeightInfo(weightAttribute, defaultWeight)));
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName,
&resolver2, WeightInfo(weightAttribute, defaultWeight)));
weighter = AttributeWeightCalculator(
weightAttribute, defaultWeight, ecol->getShaper()
);
} else {
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1));
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2));
weighter = HopWeightCalculator();
}
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1, weighter));
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2, weighter));
Traverser traverser(*forwardExpander, *backwardExpander, bidirectional);

View File

@ -2806,7 +2806,7 @@ void TRI_InitV8VocBridge (v8::Isolate* isolate,
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_SLEEP"), JS_QuerySleepAql, true);
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_IS_KILLED"), JS_QueryIsKilledAql, true);
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_SHORTEST_PATH"), JS_QueryShortestPath, true);
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("CPP_SHORTEST_PATH"), JS_QueryShortestPath, true);

View File

@ -4328,8 +4328,8 @@ div.resizecontainer {
width: 2258px; } }
div.centralRow {
margin-top: 65px;
margin-bottom: 65px; }
margin-top: 40px;
margin-bottom: 40px; }
div.centralContent {
background-color: rgba(0, 0, 0, 0.0675);

View File

@ -7,7 +7,8 @@
window.Airports = Backbone.Collection.extend({
initialize: function() {
initialize: function(options) {
this.collectionName = options.collectionName;
},
getAirports: function(callback) {
@ -35,6 +36,50 @@
});
},
getShortestFlight: function(from, to, callback) {
$.ajax({
type: "POST",
url: "/_api/cursor",
data: JSON.stringify({
query: "RETURN SHORTEST_PATH(@@airports,@@flights,@start,@dest,'outbound',{})",
bindVars: {
"@flights": this.collectionName,
"@airports": "airports",
"start": "airports/" + from,
"dest": "airports/" + to
}
}),
contentType: "application/json",
processData: false,
success: function (data) {
callback(data.result[0]);
},
error: function (data) {
}
});
},
getFlightDistribution: function(callback) {
$.ajax({
type: "POST",
url: "/_api/cursor",
data: JSON.stringify({
query: "FOR f IN @@flights COLLECT dest = f._to " +
"WITH COUNT INTO n SORT n RETURN {Dest: SPLIT(dest, '/')[1], count: n}",
bindVars: {
"@flights": this.collectionName
}
}),
contentType: "application/json",
processData: false,
success: function (data) {
callback(data.result);
},
error: function (data) {
}
});
},
getFlightsForAirport: function(airport, callback) {
var self = this;
@ -42,9 +87,12 @@
type: "POST",
url: "/_api/cursor",
data: JSON.stringify({
query: "for f in flights12 filter f.Origin == @airport COLLECT dest = f.Dest " +
"WITH COUNT INTO n SORT n RETURN {Dest: dest, count: n}",
bindVars: {"airport": airport}
query: "for f in @@flights filter f._from == @airport COLLECT dest = f._to " +
"WITH COUNT INTO n SORT n RETURN {Dest: SPLIT(dest, '/')[1], count: n}",
bindVars: {
"airport": "airports/" + airport,
"@flights": this.collectionName
}
}),
contentType: "application/json",
processData: false,

View File

@ -26,13 +26,18 @@
"userManagement": "userManagement",
"userProfile": "userProfile",
"logs": "logs",
"demo": "demo"
"demo": "demo",
"demo/:collection": "demo"
},
demo: function () {
demo: function (collection) {
if (!collection) {
collection = "flights";
}
if (!this.demoView) {
this.demoView = new window.DemoView({});
this.demoView = new window.DemoView({
collectionName: collection
});
}
this.demoView.render();

View File

@ -5,6 +5,7 @@
</div>
<div class="search-field">
<input type="text" id="demoSearchInput" class="search-input" placeholder="Search..."><img id="demoSearchSubmit" class="search-submit-icon">
<!--<div id="searchResults" class="demo-dropdown-menu"><ul></ul></div>-->
</div>
<div class="styled-select">
<select id="flightQuerySelect" class="query-select" style="margin-top: 5px; height: 25px">

View File

@ -35,22 +35,25 @@
*/
lineColors: [
'rgb(255,255,229)',
'rgb(255,247,188)',
'rgb(254,227,145)',
'rgb(254,196,79)',
'rgb(254,153,41)',
'rgb(236,112,20)',
'rgb(204,76,2)',
'rgb(153,52,4)',
'rgb(102,37,6)'
'rgb(255,255,229)'
/*
- 'rgb(255,255,229)',
- 'rgb(255,247,188)',
- 'rgb(254,227,145)',
- 'rgb(254,196,79)',
- 'rgb(254,153,41)',
- 'rgb(236,112,20)',
- 'rgb(204,76,2)',
- 'rgb(153,52,4)',
- 'rgb(102,37,6)'
*/
],
airportColor: "#222222",
airportHighlightColor: "#FF4E4E",
airportHoverColor: "#ff8f35",
airportScale: 0.5,
airportScale: 0.7,
airportHighligthScale: 0.95,
imageData: [],
@ -73,19 +76,32 @@
},
{
name: "All Flights from CWA"
},
{
name: "Flight distribution"
}
],
el: '#content',
initialize: function () {
this.airportCollection = new window.Airports();
window.HASS = this; // <--- BITTE ?!? ;) <-- zu viel Kontakt mit Jan
initialize: function (options) {
var collectionName = options.collectionName;
this.airportCollection = new window.Airports({
collectionName: collectionName
});
},
events: {
"change #flightQuerySelect" : "runSelectedQuery",
"keyup #demoSearchInput" : "searchInput"
// "click #searchResults ul li": "selectAirport"
},
selectAirport: function (e) {
this.showAirportBalloon(e.currentTarget.id);
$("#searchResults").slideUp(function() {
$("#searchResults ul").html("");
});
},
template: templateEngine.createTemplate("demoView.ejs"),
@ -152,7 +168,7 @@
var self = this, airports = this.index.search($(e.currentTarget).val());
self.resetDataHighlighting();
self.removeFlightLines(false);
self.removeFlightLines(true);
_.each(airports, function(airport) {
self.setAirportColor(airport.ref, self.airportHighlightColor, false);
@ -164,16 +180,32 @@
//self.zoomToAirport(airports[0].ref);
self.showAirportBalloon(airports[0].ref); // <-- only works with single map object, not multiple :(
}
//if (airports.length <= 10) {
//}
/*
if (airports.length < 6 && airports.length > 1) {
self.insertAirportSelection(airports);
} else {
$("#searchResults").slideUp();
}
*/
self.map.validateData();
},
insertAirportSelection: function (list) {
return;
/*
$("#searchResults ul").html("");
var i = 0;
for (i = 0; i < list.length; ++i) {
$("#searchResults ul").append("<li id='" + list[i].ref + "'>" + list[i].ref + "</li>");
}
$("#searchResults").slideDown();
*/
},
runSelectedQuery: function() {
this.resetDataHighlighting();
this.removeFlightLines(true);
var currentQueryPos = $( "#flightQuerySelect option:selected" ).attr('position');
if (currentQueryPos === "0") {
this.loadAirportData("SFO");
@ -190,6 +222,10 @@
if (currentQueryPos === "4") {
this.loadAirportData("CWA");
}
if (currentQueryPos === "5") {
delete this.startPoint;
this.loadFlightDistData();
}
},
calculateAirportSize: function(airport, airports) {
@ -239,7 +275,70 @@
},
loadFlightDistData: function() {
var self = this;
var timer = new Date();
this.airportCollection.getFlightDistribution(function(list) {
var timeTaken = new Date() - timer;
self.removeFlightLines(false);
var allFlights = 0;
var i = 0;
self.resetDataHighlighting();
var least = list[0].count^3;
var best = list[list.length - 1].count^3;
var m = 2.625 /(best - least);
var distribute = function(x) {
return m * x - m * least;
};
for (i = 0; i < list.length; ++i) {
var to = list[i].Dest;
var count = list[i].count^3;
self.setAirportColor(to, self.airportHighlightColor);
var toSize = distribute(count);
toSize += 0.625;
self.setAirportSize(to, toSize);
if (i > list.length - 6) {
// Top 10 Color
self.setAirportColor(to,'rgb(153,52,4)');
}
}
if ($("#demo-mapdiv-info").length === 0) {
$("#demo-mapdiv").append("<div id='demo-mapdiv-info'></div>");
}
var tempHTML = "";
tempHTML = "<b>Aggregation</b> - Flight distribution<br>" +
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
"Number destinations: <b>" + list.length + "</b><br>" +
"Number flights: <b>" + allFlights + "</b><br>" +
"Top 5:<br>";
for (i = (list.length - 1); i > Math.max(list.length - 6, 0); --i) {
var airportData = self.airportCollection.findWhere({_key: list[i].Dest});
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
if (i > (list.length - 5)) {
tempHTML += "<br>";
}
}
$("#demo-mapdiv-info").html(tempHTML);
self.map.validateData();
});
},
loadAirportData: function(airport) {
$("#flightQuerySelect :nth-child(1)").prop("selected", true);
var self = this;
var timer = new Date();
@ -256,13 +355,25 @@
self.resetDataHighlighting();
var least = list[0].count^3;
var best = list[list.length - 1].count^3;
var m = 2.625 /(best - least);
var distribute = function(x) {
return m * x - m * least;
};
for (i = 0; i < list.length; ++i) {
var count = list[i].count^3;
var toSize = distribute(count);
toSize += 0.625;
self.addFlightLine(
airport,
list[i].Dest,
list[i].count,
self.calculateFlightColor(list.length, i),
self.calculateFlightWidth(list.length, i)
self.calculateFlightWidth(list.length, i),
toSize,
(i > list.length - 6)
);
allFlights += list[i].count;
}
@ -272,15 +383,15 @@
}
var tempHTML = "";
tempHTML = "<b>" + airportData.get("Name") + "</b> - " + airport + "<br>" +
"Query needed: <b>" + (timeTaken/1000) + "sec" + "</b><br>" +
tempHTML = "<b>" + airportData.get("Name").substr(0,25) + "</b> - " + airport + "<br>" +
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
"Number destinations: <b>" + list.length + "</b><br>" +
"Number flights: <b>" + allFlights + "</b><br>" +
"Top 5:<br>";
for (i = (list.length - 1); i > Math.max(list.length - 6, 0); --i) {
for (i = (list.length - 1); i >= Math.max(list.length - 5, 0); --i) {
airportData = self.airportCollection.findWhere({_key: list[i].Dest});
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
tempHTML += airportData.get("Name").substr(0, 25) + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
if (i > (list.length - 5)) {
tempHTML += "<br>";
}
@ -296,12 +407,11 @@
//var intervallWidth = length/2;
// return Math.floor(pos/intervallWidth) + 2;
//TODO: no custom width for lines wanted?
return 1.5;
return 2;
},
calculateFlightColor: function(length, pos) {
var intervallColor = length/this.lineColors.length;
return this.lineColors[Math.floor(pos/intervallColor)];
return this.lineColors[0];
},
zoomToAirport: function (id) {
@ -309,6 +419,7 @@
},
showAirportBalloon: function (id) {
this.map.allowMultipleDescriptionWindows = true;
var mapObject = this.map.getObjectById(id);
this.map.rollOverMapObject(mapObject);
},
@ -354,6 +465,7 @@
airport.color = self.airportColor;
airport.scale = self.airportScale;
});
$("#demo-mapdiv-info").html("");
},
prepareData: function (data) {
@ -368,7 +480,7 @@
svgPath: self.MAPtarget,
color: self.airportColor,
scale: self.airportScale,
selectedScale: 2.5,
selectedScale: 1,
title: airport.City + " [" + airport._key + "]<br>" + airport.Name,
rollOverColor: self.airportHoverColor,
selectable: true
@ -389,6 +501,8 @@
},
createFlightEntry: function(from, to, weight, lineColor, lineWidth) {
if (this.keyToLongLat.hasOwnProperty(from)
&& this.keyToLongLat.hasOwnProperty(to)) {
return {
longitudes: [
this.keyToLongLat[from].lon,
@ -402,6 +516,44 @@
color: lineColor,
thickness: lineWidth
};
}
return undefined;
},
loadShortestPath: function(from, to) {
var self = this;
var timer = new Date();
this.airportCollection.getShortestFlight(from, to, function(list) {
var timeTaken = new Date() - timer;
if (!list.vertices) {
alert("Sorry there is no flight");
}
var vertices = list.vertices;
for (var i = 0; i < vertices.length - 1; ++i) {
var from = vertices[i].split("/")[1];
var to = vertices[i+1].split("/")[1];
self.addFlightLine(from, to, 1,
self.calculateFlightColor(vertices.length, i),
self.calculateFlightWidth(vertices.length, i),
2,
true,
false
);
}
var tempHTML = "";
tempHTML = "<b>Path</b> - Shortest Flight<br>" +
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
"Number switches: <b>" + (vertices.length - 2) + "</b><br>" +
"Number flights: <b>" + list.edges.length + "</b><br>" +
"Airports:<br>";
for (i = 0; i < vertices.length; ++i) {
var airportData = self.airportCollection.findWhere({_key: vertices[i].split("/")[1]});
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + "<br>";
}
$("#demo-mapdiv-info").html(tempHTML);
self.map.validateData();
});
},
renderMap: function() {
@ -422,9 +574,17 @@
images: self.imageData,
getAreasFromMap: true
},
clickMapObject: function(mapObject) {
//console.log(mapObject);
clickMapObject: function(mapObject, event) {
if (mapObject.id !== undefined && mapObject.id.length === 3) {
if (event.shiftKey && self.hasOwnProperty("startPoint")) {
self.resetDataHighlighting();
self.removeFlightLines(true);
self.loadShortestPath(self.startPoint, mapObject.id);
} else {
self.startPoint = mapObject.id;
self.loadAirportData(mapObject.id);
}
}
},
balloon: {
adjustBorderColor: true,
@ -468,21 +628,19 @@
});
},
addFlightLine: function(from, to, count, lineColor, lineWidth, shouldRender) {
//console.log("Adding", from, to, count, lineColor, lineWidth);
this.lines.push(this.createFlightEntry(from, to, count, lineColor, lineWidth));
addFlightLine: function(from, to, count, lineColor, lineWidth, toSize, highlight, shouldRender) {
var f = this.createFlightEntry(from, to, count, lineColor, lineWidth);
if (f !== undefined) {
this.lines.push(f);
}
this.setAirportColor(from, "#FFFFFF");
this.setAirportColor(to, this.airportHighlightColor);
this.setAirportSize(from, 1.5);
var toSize = count * 0.001;
if (toSize <= 0.25) {
toSize = 0.25;
}
this.setAirportSize(to, toSize);
if (highlight) {
this.setAirportColor(to, 'rgb(153,52,4)');
}
}
});

View File

@ -0,0 +1,42 @@
div.demo-dropdown-menu {
@extend %clickable;
@include border-radius(0 0 5px 5px);
background-color: $c-bar-bg;
margin-bottom: 5px;
margin-left: 5px;
position: absolute;
top: 32px;
width: 222px;
z-index: 100;
}
#flightQuerySelect.query-select {
height: 25px;
margin-top: 6px;
font-size: 13px;
line-height: 1.1em;
}
#demo-mapdiv {
position: relative;
}
#demo-mapdiv-info {
position: absolute;
right: 20px;
width: 225px;
height: 150px;
bottom: 20px;
border: 1.5px solid #222;
border-radius: 4px;
background-color: rgba(255,255,255, 0.75);
padding: 6px 6px 3px 6px;
font-size: 11px;
line-height: 1.3em;
}
.amcharts-balloon-div {
line-height: 1.1em;
}

View File

@ -504,8 +504,8 @@ div.resizecontainer {
div.centralRow {
margin: {
top: 65px;
bottom: 65px;
top: 40px;
bottom: 40px;
}
}

View File

@ -87,4 +87,4 @@
@import 'uploadfile';
// Demo
//@import 'demo';
@import 'demo';

View File

@ -5598,6 +5598,17 @@ function AQL_SHORTEST_PATH (vertexCollection,
params) {
'use strict';
if (typeof startVertex === "string" && typeof endVertex === "string") {
var opts = {
direction: direction
};
if (params.hasOwnProperty("distance") && params.hasOwnProperty("defaultDistance")) {
opts.distance = params.distance;
opts.defaultDistance = params.defaultDistance;
}
return CPP_SHORTEST_PATH(vertexCollection, edgeCollection, startVertex, endVertex, opts);
}
params = SHORTEST_PATH_PARAMS(params);
return TRAVERSAL_FUNC("SHORTEST_PATH",