1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into readcache

This commit is contained in:
jsteemann 2016-07-14 10:13:43 +02:00
commit ccf3b206bd
8 changed files with 181 additions and 19 deletions

View File

@ -42,8 +42,8 @@ key/value object with extra options for the query.
@RESTSTRUCT{fullCount,JSF_post_api_cursor_opts,boolean,optional,} @RESTSTRUCT{fullCount,JSF_post_api_cursor_opts,boolean,optional,}
if set to *true* and the query contains a *LIMIT* clause, then the if set to *true* and the query contains a *LIMIT* clause, then the
result will contain an extra attribute *extra* with a sub-attribute *fullCount*. result will a sub-attribute *fullCount* in the *extra.stats* sub-attribute.
This sub-attribute will contain the number of documents in the result before the The *fullCount* sub-attribute will contain the number of documents in the result before the
last LIMIT in the query was applied. It can be used to count the number of documents that last LIMIT in the query was applied. It can be used to count the number of documents that
match certain filter criteria, but only return a subset of them, in one go. match certain filter criteria, but only return a subset of them, in one go.
It is thus similar to MySQL's *SQL_CALC_FOUND_ROWS* hint. Note that setting the option It is thus similar to MySQL's *SQL_CALC_FOUND_ROWS* hint. Note that setting the option

View File

@ -343,11 +343,14 @@ int LimitBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
if (_engine->_stats.fullCount == -1) { if (_engine->_stats.fullCount == -1) {
_engine->_stats.fullCount = 0; _engine->_stats.fullCount = 0;
} }
_engine->_stats.fullCount += static_cast<int64_t>(_offset);
} }
if (_offset > 0) { if (_offset > 0) {
ExecutionBlock::_dependencies[0]->skip(_offset); size_t numActuallySkipped = 0;
ExecutionBlock::_dependencies[0]->skip(_offset, numActuallySkipped);
if (_fullCount) {
_engine->_stats.fullCount += static_cast<int64_t>(numActuallySkipped);
}
} }
_state = 1; _state = 1;
_count = 0; _count = 0;

View File

@ -284,7 +284,7 @@ size_t ExecutionBlock::skipSome(size_t atLeast, size_t atMost) {
// skip exactly <number> outputs, returns <true> if _done after // skip exactly <number> outputs, returns <true> if _done after
// skipping, and <false> otherwise . . . // skipping, and <false> otherwise . . .
bool ExecutionBlock::skip(size_t number) { bool ExecutionBlock::skip(size_t number, size_t& numActuallySkipped) {
DEBUG_BEGIN_BLOCK(); DEBUG_BEGIN_BLOCK();
size_t skipped = skipSome(number, number); size_t skipped = skipSome(number, number);
size_t nr = skipped; size_t nr = skipped;
@ -292,6 +292,7 @@ bool ExecutionBlock::skip(size_t number) {
nr = skipSome(number - skipped, number - skipped); nr = skipSome(number - skipped, number - skipped);
skipped += nr; skipped += nr;
} }
numActuallySkipped = skipped;
if (nr == 0) { if (nr == 0) {
return true; return true;
} }
@ -345,7 +346,8 @@ int ExecutionBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping,
while (skipped < atLeast) { while (skipped < atLeast) {
if (_buffer.empty()) { if (_buffer.empty()) {
if (skipping) { if (skipping) {
_dependencies[0]->skip(atLeast - skipped); size_t numActuallySkipped = 0;
_dependencies[0]->skip(atLeast - skipped, numActuallySkipped);
skipped = atLeast; skipped = atLeast;
freeCollector(); freeCollector();
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;

View File

@ -156,7 +156,7 @@ class ExecutionBlock {
// skip exactly <number> outputs, returns <true> if _done after // skip exactly <number> outputs, returns <true> if _done after
// skipping, and <false> otherwise . . . // skipping, and <false> otherwise . . .
bool skip(size_t number); bool skip(size_t number, size_t& numActuallySkipped);
virtual bool hasMore(); virtual bool hasMore();

View File

@ -111,7 +111,9 @@ class ExecutionEngine {
AqlItemBlock* getOne() { return _root->getSome(1, 1); } AqlItemBlock* getOne() { return _root->getSome(1, 1); }
/// @brief skip /// @brief skip
bool skip(size_t number) { return _root->skip(number); } bool skip(size_t number, size_t& actuallySkipped) {
return _root->skip(number, actuallySkipped);
}
/// @brief hasMore /// @brief hasMore
inline bool hasMore() const { return _root->hasMore(); } inline bool hasMore() const { return _root->hasMore(); }

View File

@ -783,7 +783,8 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
try { try {
bool exhausted; bool exhausted;
if (shardId.empty()) { if (shardId.empty()) {
exhausted = query->engine()->skip(number); size_t numActuallySkipped = 0;
exhausted = query->engine()->skip(number, numActuallySkipped);
} else { } else {
auto block = auto block =
static_cast<BlockWithClients*>(query->engine()->root()); static_cast<BlockWithClients*>(query->engine()->root());

View File

@ -25,6 +25,9 @@
'click #downloadPNG': 'downloadSVG' 'click #downloadPNG': 'downloadSVG'
}, },
cursorX: 0,
cursorY: 0,
initSigma: function () { initSigma: function () {
// init sigma // init sigma
try { try {
@ -70,7 +73,10 @@
$('#content').append( $('#content').append(
'<div id="calculatingGraph" style="position: absolute; left: 25px; top: 130px;">' + '<div id="calculatingGraph" style="position: absolute; left: 25px; top: 130px;">' +
'<i class="fa fa-circle-o-notch fa-spin" style="margin-right: 10px;"></i>' + '<i class="fa fa-circle-o-notch fa-spin" style="margin-right: 10px;"></i>' +
'<span id="calcText">Fetching graph data. Please wait ... </span></div>' '<span id="calcText">Fetching graph data. Please wait ... </span></br></br></br>' +
'<span style="font-weight: 100; opacity: 0.6; font-size: 9pt;">If it`s taking too much time to draw the graph, please go to: </br>' +
'<a href="' + window.location.href + '/settings">' + window.location.href + '/settings </a></br> and adjust your settings.' +
'It is possible that the graph is too big to be handled by the browser.</span></div>'
); );
var continueFetchGraph = function () { var continueFetchGraph = function () {
@ -158,23 +164,78 @@
}); });
} }
// clear events
var c = document.getElementsByClassName('sigma-mouse')[0];
c.removeEventListener('mousemove', self.drawLine.bind(this), false);
// clear info div // clear info div
}, },
trackCursorPosition: function (e) {
this.cursorX = e.x;
this.cursorY = e.y;
},
createContextMenu: function (e) { createContextMenu: function (e) {
var x = e.data.captor.clientX; var self = this;
var y = e.data.captor.clientX; var x = self.cursorX - 50;
console.log('Context menu'); var y = self.cursorY - 50;
console.log(x); console.log(e);
console.log(y);
this.clearOldContextMenu(); this.clearOldContextMenu();
var generateMenu = function (e) {
var hotaru = ['#364C4A', '#497C7F', '#92C5C0', '#858168', '#CCBCA5'];
var Wheelnav = wheelnav;
var wheel = new Wheelnav('nodeContextMenu');
wheel.maxPercent = 1.0;
wheel.wheelRadius = 50;
wheel.clockwise = false;
wheel.colors = hotaru;
wheel.multiSelect = true;
wheel.clickModeRotate = false;
wheel.slicePathFunction = slicePath().DonutSlice;
wheel.createWheel([icon.plus, icon.trash]);
wheel.navItems[0].selected = false;
wheel.navItems[0].hovered = false;
// add menu events
// function 0: edit
wheel.navItems[0].navigateFunction = function (e) {
self.clearOldContextMenu();
};
// function 1: delete
wheel.navItems[1].navigateFunction = function (e) {
self.clearOldContextMenu();
};
// deselect active default entry
wheel.navItems[0].selected = false;
wheel.navItems[0].hovered = false;
};
$('#nodeContextMenu').css('position', 'fixed');
$('#nodeContextMenu').css('left', x);
$('#nodeContextMenu').css('top', y);
$('#nodeContextMenu').width(100);
$('#nodeContextMenu').height(100);
generateMenu(e);
}, },
createNodeContextMenu: function (nodeId, e) { createNodeContextMenu: function (nodeId, e) {
var self = this; var self = this;
var x = e.data.node['renderer1:x']; // var x = e.data.node['renderer1:x'];
var y = e.data.node['renderer1:y']; // var y = e.data.node['renderer1:y'];
// better to use x,y from top, but sometimes values are not correct ...
console.log(e);
var x = e.data.captor.clientX - 52;
var y = e.data.captor.clientY - 52;
console.log(e.data);
this.clearOldContextMenu(); this.clearOldContextMenu();
@ -233,8 +294,8 @@
wheel.navItems[0].hovered = false; wheel.navItems[0].hovered = false;
}; };
$('#nodeContextMenu').css('left', x + 115); $('#nodeContextMenu').css('left', x);
$('#nodeContextMenu').css('top', y + 72); $('#nodeContextMenu').css('top', y);
$('#nodeContextMenu').width(100); $('#nodeContextMenu').width(100);
$('#nodeContextMenu').height(100); $('#nodeContextMenu').height(100);
@ -498,6 +559,11 @@
} }
console.log(dragListener); console.log(dragListener);
// add listener to keep track of cursor position
var c = document.getElementsByClassName('sigma-mouse')[0];
c.addEventListener('mousemove', self.trackCursorPosition.bind(this), false);
// clear up info div
$('#calculatingGraph').remove(); $('#calculatingGraph').remove();
} }

View File

@ -104,6 +104,94 @@ function optimizerFullcountTestSuite () {
assertEqual(2, result.stats.fullCount); assertEqual(2, result.stats.fullCount);
assertEqual(1, result.json.length); assertEqual(1, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection LIMIT 100 RETURN doc", null, { fullCount: true });
assertEqual(3, result.stats.fullCount);
assertEqual(3, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit2 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection LIMIT 1, 100 RETURN doc", null, { fullCount: true });
assertEqual(3, result.stats.fullCount);
assertEqual(2, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit3 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection LIMIT 2, 100 RETURN doc", null, { fullCount: true });
assertEqual(3, result.stats.fullCount);
assertEqual(1, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit4 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection LIMIT 3, 100 RETURN doc", null, { fullCount: true });
assertEqual(3, result.stats.fullCount);
assertEqual(0, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit5 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection LIMIT 10000, 100 RETURN doc", null, { fullCount: true });
assertEqual(3, result.stats.fullCount);
assertEqual(0, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit6 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection FILTER 'bar' IN doc.values LIMIT 1, 10 RETURN doc", null, { fullCount: true });
assertEqual(2, result.stats.fullCount);
assertEqual(1, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit7 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection FILTER 'bar' IN doc.values LIMIT 10, 10 RETURN doc", null, { fullCount: true });
assertEqual(2, result.stats.fullCount);
assertEqual(0, result.json.length);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test with fullcount
////////////////////////////////////////////////////////////////////////////////
testHigherLimit8 : function () {
var result = AQL_EXECUTE("FOR doc IN UnitTestsCollection FILTER 'bar' IN doc.values LIMIT 1000, 1 RETURN doc", null, { fullCount: true });
assertEqual(2, result.stats.fullCount);
assertEqual(0, result.json.length);
} }
}; };