1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Lucas Dohmen 2013-01-14 02:36:40 +01:00
commit ef8bb55165
9 changed files with 456 additions and 104 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -311,6 +311,7 @@ void ArangoServer::buildApplicationServer () {
additional[ApplicationServer::OPTIONS_HIDDEN]
("no-upgrade", "skip a database upgrade")
("show-markers", "show offset and sizes of markers")
;
#ifdef TRI_ENABLE_MRUBY
@ -608,6 +609,22 @@ int ArangoServer::startupServer () {
TRI_InitialiseStatistics();
// .............................................................................
// show markers
// .............................................................................
if (_applicationServer->programOptions().has("show-markers")) {
LOGGER_INFO << "sizeof(TRI_df_marker_t): " << sizeof(TRI_df_marker_t);
LOGGER_INFO << "sizeof(TRI_df_header_marker_t): " << sizeof(TRI_df_header_marker_t);
LOGGER_INFO << "sizeof(TRI_df_footer_marker_t): " << sizeof(TRI_df_footer_marker_t);
LOGGER_INFO << "sizeof(TRI_df_document_marker_t): " << sizeof(TRI_df_document_marker_t);
LOGGER_INFO << "sizeof(TRI_df_skip_marker_t): " << sizeof(TRI_df_skip_marker_t);
LOGGER_INFO << "sizeof(TRI_doc_document_key_marker_s): " << sizeof(TRI_doc_document_key_marker_s);
LOGGER_INFO << "sizeof(TRI_doc_edge_key_marker_s): " << sizeof(TRI_doc_edge_key_marker_s);
LOGGER_INFO << "sizeof(TRI_doc_deletion_key_marker_s): " << sizeof(TRI_doc_deletion_key_marker_s);
}
// .............................................................................
// start the main event loop
// .............................................................................
@ -617,7 +634,6 @@ int ArangoServer::startupServer () {
LOGGER_INFO << "ArangoDB (version " << TRIAGENS_VERSION << ") is ready for business";
LOGGER_INFO << "Have Fun!";
_applicationServer->wait();

View File

@ -85,10 +85,6 @@ ArangoStatement.prototype.bind = function (key, value) {
this._bindVars = key;
}
else if (typeof(key) === "string") {
if (this._bindVars[key] !== undefined) {
throw "redeclaration of bind parameter";
}
this._bindVars[key] = value;
}
else if (typeof(key) === "number") {
@ -98,10 +94,6 @@ ArangoStatement.prototype.bind = function (key, value) {
throw "invalid bind parameter declaration";
}
if (this._bindVars[strKey] !== undefined) {
throw "redeclaration of bind parameter";
}
this._bindVars[strKey] = value;
}
else {

View File

@ -2250,7 +2250,7 @@ function ArangoDatabase (connection) {
return this[name];
}
return undefined;
return null;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -466,8 +466,8 @@ function CollectionOutboundExpander (config, vertex, path) {
outEdges.forEach(function (edge) {
try {
var vertex = internal.db._document(edge._to);
connections.push({ edge: edge, vertex: vertex });
var v = internal.db._document(edge._to);
connections.push({ edge: edge, vertex: v });
}
catch (e) {
// continue even in the face of non-existing documents
@ -491,8 +491,8 @@ function CollectionInboundExpander (config, vertex, path) {
inEdges.forEach(function (edge) {
try {
var vertex = internal.db._document(edge._from);
connections.push({ edge: edge, vertex: vertex });
var v = internal.db._document(edge._from);
connections.push({ edge: edge, vertex: v });
}
catch (e) {
// continue even in the face of non-existing documents
@ -516,8 +516,8 @@ function CollectionAnyExpander (config, vertex, path) {
edges.forEach(function (edge) {
try {
var vertex = internal.db._document(edge._from);
connections.push({ edge: edge, vertex: vertex });
var v = internal.db._document(edge._from === vertex._id ? edge._to : edge._from);
connections.push({ edge: edge, vertex: v });
}
catch (e) {
// continue even in the face of non-existing documents
@ -528,24 +528,72 @@ function CollectionAnyExpander (config, vertex, path) {
}
///////////////////////////////////////////////////////////////////////////////////////////
/// @brief default expander that expands all edges labeled with one label in config.labels
/// @brief default expander that expands all outbound edges labeled with one label in config.labels
///////////////////////////////////////////////////////////////////////////////////////////
var ExpandEdgesWithLabels = function (config, vertex, path) {
function ExpandOutEdgesWithLabels (config, vertex, path) {
var result = [ ];
if (!Array.isArray(config.labels)) {
config.labels = [config.labels];
}
var edgesList = edges[vertex._id];
var edgesList = config.datasource.getOutEdges(vertex._id);
if (edgesList != undefined) {
for (i = 0; i < edgesList.length; ++i) {
if (!!~config.labels.indexOf(edgesList[i].label)) {
result.push({ edge: edgesList[i], vertex: vertices[edgesList[i]._to] });
result.push({ edge: edgesList[i], vertex: config.datasource.vertices[edgesList[i]._to] });
}
}
}
return result;
};
}
///////////////////////////////////////////////////////////////////////////////////////////
/// @brief default expander that expands all inbound edges labeled with one label in config.labels
///////////////////////////////////////////////////////////////////////////////////////////
function ExpandInEdgesWithLabels (config, vertex, path) {
var result = [ ];
if (!Array.isArray(config.labels)) {
config.labels = [config.labels];
}
var edgesList = config.datasource.getInEdges(vertex._id);
if (edgesList != undefined) {
for (i = 0; i < edgesList.length; ++i) {
if (!!~config.labels.indexOf(edgesList[i].label)) {
result.push({ edge: edgesList[i], vertex: config.datasource.vertices[edgesList[i]._from] });
}
}
}
return result;
}
///////////////////////////////////////////////////////////////////////////////////////////
/// @brief default expander that expands all edges labeled with one label in config.labels
///////////////////////////////////////////////////////////////////////////////////////////
function ExpandEdgesWithLabels (config, vertex, path) {
var result = [ ];
if (!Array.isArray(config.labels)) {
config.labels = [config.labels];
}
var edgesList = config.datasource.getInEdges(vertex._id);
if (edgesList != undefined) {
for (i = 0; i < edgesList.length; ++i) {
if (!!~config.labels.indexOf(edgesList[i].label)) {
result.push({ edge: edgesList[i], vertex: config.datasource.vertices[edgesList[i]._from] });
}
}
}
edgesList = config.datasource.getOutEdges(vertex._id);
if (edgesList != undefined) {
for (i = 0; i < edgesList.length; ++i) {
if (!!~config.labels.indexOf(edgesList[i].label)) {
result.push({ edge: edgesList[i], vertex: config.datasource.vertices[edgesList[i]._to] });
}
}
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief default visitor that just tracks every visit
@ -732,6 +780,8 @@ exports.TrackingVisitor = TrackingVisitor;
exports.MinDepthFilter = MinDepthFilter;
exports.MaxDepthFilter = MaxDepthFilter;
exports.ExpandEdgesWithLabels = ExpandEdgesWithLabels;
exports.ExpandInEdgesWithLabels = ExpandInEdgesWithLabels;
exports.ExpandOutEdgesWithLabels = ExpandOutEdgesWithLabels;
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -69,9 +69,23 @@ function CollectionDocumentSuiteErrorHandling () {
/// @brief bad handle
////////////////////////////////////////////////////////////////////////////////
testErrorHandlingBadHandle : function () {
testErrorHandlingBadHandleDatabase : function () {
try {
collection.document(" 123456");
internal.db._document("123456");
fail();
}
catch (err) {
assertEqual(ERRORS.ERROR_ARANGO_DOCUMENT_HANDLE_BAD.code, err.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief bad handle
////////////////////////////////////////////////////////////////////////////////
testErrorHandlingBadHandleCollection : function () {
try {
collection.document("");
fail();
}
catch (err) {
@ -85,7 +99,7 @@ function CollectionDocumentSuiteErrorHandling () {
testErrorHandlingBadHandleReplace : function () {
try {
collection.replace("123456 ", {});
internal.db._replace("123456 ", {});
fail();
}
catch (err) {

View File

@ -50,6 +50,161 @@ function GraphTreeTraversalSuite () {
//var vertices;
//var edges;
var datasourceWorld;
var datasourcePeople;
var setUpSourceWorld = function () {
var vertices = { };
var inEdges = { };
var outEdges = { };
[ "World", "Nothing",
"Europe", "Asia", "America", "Australia", "Antarctica", "Africa", "Blackhole",
"DE", "FR", "GB", "IE", "CN", "JP", "TW", "US", "MX", "AU", "EG", "ZA", "AN",
"London", "Paris", "Lyon", "Cologne", "Dusseldorf", "Beijing", "Shanghai", "Tokyo", "Kyoto", "Taipeh", "Perth", "Sydney"
].forEach(function (item) {
var key = item;
var vertex = {
_id : "vertices/" + key,
_key : key,
name : item
};
vertices[vertex._id] = vertex;
});
var connect = function (from, to) {
var key = from + "x" + to;
var edge = {
_id : "edges/" + key,
_key : key,
_from : "vertices/" + from,
_to : "vertices/" + to,
what : from + "->" + to,
};
if (outEdges[edge._from] == undefined) {
outEdges[edge._from] = [ ];
}
outEdges[edge._from].push(edge);
if (inEdges[edge._to] == undefined) {
inEdges[edge._to] = [ ];
}
inEdges[edge._to].push(edge);
};
connect("World", "Europe");
connect("World", "Asia");
connect("World", "America");
connect("World", "Australia");
connect("World", "Africa");
connect("World", "Antarctica");
connect("Europe", "DE");
connect("Europe", "FR");
connect("Europe", "GB");
connect("Europe", "IE");
connect("Asia", "CN");
connect("Asia", "JP");
connect("Asia", "TW");
connect("America", "US");
connect("America", "MX");
connect("Australia", "AU");
connect("Antarctica", "AN");
datasourceWorld = {
inEdges: inEdges,
outEdges: outEdges,
vertices: vertices,
getAllEdges: function (vertexId) {
return this.inEdges[vertexId].concat(outEdges[vertex_id]);
},
getInEdges: function (vertexId) {
return this.inEdges[vertexId];
},
getOutEdges: function (vertexId) {
return this.outEdges[vertexId];
}
};
};
var setUpSourcePeople = function () {
var vertices = { };
var inEdges = { };
var outEdges = { };
["Alice",
"Bob",
"Charly",
"Diana",
"Eric",
"Frank"].forEach( function (person){
var key = person;
var vertex = {
_id : "vertices/" + key,
_key : key,
name : person
};
vertices[vertex._id] = vertex;
});
var connect = function (from, to, label) {
var key = from + "x" + to;
var edge = {
_id : "edges/" + key,
_key : key,
_from : "vertices/" + from,
_to : "vertices/" + to,
what : from + "->" + to,
label : label
};
if (outEdges[edge._from] == undefined) {
outEdges[edge._from] = [ ];
}
if (inEdges[edge._to] == undefined) {
inEdges[edge._to] = [ ];
}
outEdges[edge._from].push(edge);
inEdges[edge._to].push(edge);
};
var connectBoth = function (first, second, label) {
connect(first, second, label);
connect(second, first, label);
};
connectBoth("Alice", "Bob", "likes");
connect("Alice", "Diana", "hates");
connectBoth("Alice", "Eric", "hates");
connect("Bob", "Charly", "likes");
connectBoth("Charly", "Diana", "hates");
connect("Diana", "Alice", "likes");
connect("Diana", "Eric", "likes");
connect("Alice", "Frank", "l");
connect("Frank", "Bob", "likes");
// SetUp Data source
datasourcePeople = {
inEdges: inEdges,
outEdges: outEdges,
vertices: vertices,
getAllEdges: function (vertex_id) {
return inEdges[vertex_id].concat(outEdges[vertex_id]);
},
getInEdges: function (vertex_id) {
return inEdges[vertex_id];
},
getOutEdges: function (vertex_id) {
return outEdges[vertex_id]
}
};
};
var visitor = traversal.TrackingVisitor;
@ -130,80 +285,8 @@ function GraphTreeTraversalSuite () {
////////////////////////////////////////////////////////////////////////////////
setUp : function () {
var worldVertices = { };
var worldInEdges = { };
var worldOutEdges = { };
[ "World", "Nothing",
"Europe", "Asia", "America", "Australia", "Antarctica", "Africa", "Blackhole",
"DE", "FR", "GB", "IE", "CN", "JP", "TW", "US", "MX", "AU", "EG", "ZA", "AN",
"London", "Paris", "Lyon", "Cologne", "Dusseldorf", "Beijing", "Shanghai", "Tokyo", "Kyoto", "Taipeh", "Perth", "Sydney"
].forEach(function (item) {
var key = item;
var vertex = {
_id : "vertices/" + key,
_key : key,
name : item
};
worldVertices[vertex._id] = vertex;
});
var connect = function (from, to, inlist, outlist) {
var key = from + "x" + to;
var edge = {
_id : "edges/" + key,
_key : key,
_from : "vertices/" + from,
_to : "vertices/" + to,
what : from + "->" + to
};
if (outlist[edge._from] == undefined) {
outlist[edge._from] = [ ];
}
outlist[edge._from].push(edge);
if (inlist[edge._to] == undefined) {
inlist[edge._to] = [ ];
}
inlist[edge._to].push(edge);
};
connect("World", "Europe", worldInEdges, worldOutEdges);
connect("World", "Asia", worldInEdges, worldOutEdges);
connect("World", "America", worldInEdges, worldOutEdges);
connect("World", "Australia", worldInEdges, worldOutEdges);
connect("World", "Africa", worldInEdges, worldOutEdges);
connect("World", "Antarctica", worldInEdges, worldOutEdges);
connect("Europe", "DE", worldInEdges, worldOutEdges);
connect("Europe", "FR", worldInEdges, worldOutEdges);
connect("Europe", "GB", worldInEdges, worldOutEdges);
connect("Europe", "IE", worldInEdges, worldOutEdges);
connect("Asia", "CN", worldInEdges, worldOutEdges);
connect("Asia", "JP", worldInEdges, worldOutEdges);
connect("Asia", "TW", worldInEdges, worldOutEdges);
connect("America", "US", worldInEdges, worldOutEdges);
connect("America", "MX", worldInEdges, worldOutEdges);
connect("Australia", "AU", worldInEdges, worldOutEdges);
connect("Antarctica", "AN", worldInEdges, worldOutEdges);
datasourceWorld = {
inEdges: worldInEdges,
outEdges: worldOutEdges,
vertices: worldVertices,
getAllEdges: function (vertexId) {
return this.inEdges[vertexId].concat(outEdges[vertex_id]);
},
getInEdges: function (vertexId) {
return this.inEdges[vertexId];
},
getOutEdges: function (vertexId) {
return this.outEdges[vertexId];
}
};
setUpSourceWorld();
setUpSourcePeople();
},
////////////////////////////////////////////////////////////////////////////////
@ -1095,11 +1178,127 @@ function GraphTreeTraversalSuite () {
assertEqual(expectedPaths, getVisitedPaths(result.visited.paths));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test if all edges with one label are followed
////////////////////////////////////////////////////////////////////////////////
testFollowEdgesWithLabels : function () {
var config = {
uniqueness: {
vertices: traversal.Traverser.UNIQUE_GLOBAL,
edges: traversal.Traverser.UNIQUE_NONE
},
labels: "likes",
visitor: visitor,
expander: traversal.ExpandEdgesWithLabels,
edgeLabels: ["likes", "hates"]
}
datasource: datasourcePeople
};
var result = getResult();
var traverser = new traversal.Traverser(config);
traverser.traverse(result, config.datasource.vertices["vertices/Alice"]);
var expectedVisits = [
"vertices/Alice",
"vertices/Bob",
"vertices/Frank",
"vertices/Charly",
"vertices/Diana",
"vertices/Eric",
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
var expectedPaths = [
[ "vertices/Alice"],
[ "vertices/Alice", "vertices/Bob" ],
[ "vertices/Alice", "vertices/Bob", "vertices/Frank" ],
[ "vertices/Alice", "vertices/Bob", "vertices/Charly" ],
[ "vertices/Alice", "vertices/Diana" ],
[ "vertices/Alice", "vertices/Diana", "vertices/Eric" ]
];
assertEqual(expectedPaths, getVisitedPaths(result.visited.paths));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test if all and only inbound edges with one label are followed
////////////////////////////////////////////////////////////////////////////////
testFollowInEdgesWithLabels : function () {
var config = {
uniqueness: {
vertices: traversal.Traverser.UNIQUE_GLOBAL,
edges: traversal.Traverser.UNIQUE_NONE
},
labels: "likes",
visitor: visitor,
expander: traversal.ExpandInEdgesWithLabels,
datasource: datasourcePeople
};
var result = getResult();
var traverser = new traversal.Traverser(config);
traverser.traverse(result, config.datasource.vertices["vertices/Alice"]);
var expectedVisits = [
"vertices/Alice",
"vertices/Bob",
"vertices/Frank",
"vertices/Diana"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
var expectedPaths = [
[ "vertices/Alice"],
[ "vertices/Alice", "vertices/Bob" ],
[ "vertices/Alice", "vertices/Bob", "vertices/Frank" ],
[ "vertices/Alice", "vertices/Diana" ]
];
assertEqual(expectedPaths, getVisitedPaths(result.visited.paths));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test if all and only outbound edges with one label are followed
////////////////////////////////////////////////////////////////////////////////
testFollowOutEdgesWithLabels : function () {
var config = {
uniqueness: {
vertices: traversal.Traverser.UNIQUE_GLOBAL,
edges: traversal.Traverser.UNIQUE_NONE
},
labels: "likes",
visitor: visitor,
expander: traversal.ExpandOutEdgesWithLabels,
datasource: datasourcePeople
};
var result = getResult();
var traverser = new traversal.Traverser(config);
traverser.traverse(result, config.datasource.vertices["vertices/Alice"]);
var expectedVisits = [
"vertices/Alice",
"vertices/Bob",
"vertices/Charly"
];
assertEqual(expectedVisits, getIds(result.visited.vertices));
var expectedPaths = [
[ "vertices/Alice"],
[ "vertices/Alice", "vertices/Bob" ],
[ "vertices/Alice", "vertices/Bob", "vertices/Charly" ]
];
assertEqual(expectedPaths, getVisitedPaths(result.visited.paths));
}
};
}

View File

@ -2364,7 +2364,7 @@ function AHUACATL_GRAPH_TRAVERSE () {
trackPaths: params.paths || false,
visitor: AHUACATL_TRAVERSE_VISITOR,
maxDepth: params.maxDepth,
filter: params.maxDepth != undefined ? traversal.MaxDepthFilter : VisitAllFilter,
filter: params.maxDepth != undefined ? traversal.MaxDepthFilter : traversal.VisitAllFilter,
uniqueness: {
vertices: validate(params.uniqueness && params.uniqueness.vertices, {
'none': traversal.Traverser.UNIQUE_NONE,
@ -2384,6 +2384,10 @@ function AHUACATL_GRAPH_TRAVERSE () {
})
};
if (params._sort) {
config.sort = function (l, r) { return l._key < r._key ? -1 : 1 };
}
var result = [ ];
var traverser = new traversal.Traverser(config);
traverser.traverse(result, vertexCollection.document(startVertex));

View File

@ -331,20 +331,97 @@ function ahuacatlQueryTraverseTestSuite () {
},
////////////////////////////////////////////////////////////////////////////////
/// @brief tear down
/// @brief test max-depth filtering
////////////////////////////////////////////////////////////////////////////////
testTraversalDepthFirst : function () {
testTraversalDepthFirstMax1 : function () {
var config = {
strategy: "depthfirst",
order: "preorder",
itemOrder: "forward",
maxDepth: 2
maxDepth: 2,
_sort: true
};
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
assertEqual([ "A", "B", "C", "D", "C" ], actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test max-depth filtering
////////////////////////////////////////////////////////////////////////////////
testTraversalDepthFirstMax2 : function () {
var config = {
strategy: "depthfirst",
order: "preorder",
itemOrder: "forward",
maxDepth: 3,
_sort: true
};
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
assertEqual([ "A", "B", "C", "A", "D", "C", "A" ], actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test max-depth filtering
////////////////////////////////////////////////////////////////////////////////
testTraversalDepthFirstUniqueGlobal : function () {
var config = {
strategy: "depthfirst",
order: "preorder",
itemOrder: "forward",
uniqueness: {
vertices: "global"
},
_sort: true
};
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
assertEqual([ "A", "B", "C", "D" ], actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test max-depth filtering
////////////////////////////////////////////////////////////////////////////////
testTraversalDepthFirstUniquePath : function () {
var config = {
strategy: "depthfirst",
order: "preorder",
itemOrder: "forward",
uniqueness: {
vertices: "path"
},
_sort: true
};
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'outbound', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
assertEqual([ "A", "B", "C", "D", "C" ], actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test max-depth filtering
////////////////////////////////////////////////////////////////////////////////
testTraversalDepthFirstAny : function () {
var config = {
strategy: "depthfirst",
order: "preorder",
itemOrder: "forward",
maxDepth: 2,
_sort: true
};
var actual = executeQuery("FOR p IN TRAVERSE(@@v, @@e, '" + vn + "/A', 'any', " + JSON.stringify(config) + ") RETURN p.vertex._key", { "@v" : vn, "@e" : en }).getRows();
assertEqual([ "A", "B", "A", "C", "D", "A", "C", "C", "B", "A", "D" ], actual);
}
};