1
0
Fork 0

for equality-only comparisons evaluate dynamic expressions just once and not twice

This commit is contained in:
Jan Steemann 2015-05-01 01:40:07 +02:00
parent 3f9dbb4220
commit 28e062ca91
2 changed files with 107 additions and 68 deletions

View File

@ -1115,6 +1115,11 @@ IndexRangeBlock::~IndexRangeBlock () {
delete _edgeIndexIterator;
}
bool IndexRangeBlock::useHighBounds () const {
auto en = static_cast<IndexRangeNode const*>(getPlanNode());
return (en->_index->type == TRI_IDX_TYPE_SKIPLIST_INDEX);
}
bool IndexRangeBlock::hasV8Expression () const {
for (auto expression : _allVariableBoundExpressions) {
TRI_ASSERT(expression != nullptr);
@ -1127,7 +1132,7 @@ bool IndexRangeBlock::hasV8Expression () const {
}
void IndexRangeBlock::buildExpressions () {
auto en = static_cast<IndexRangeNode const*>(getPlanNode());
bool const useHighBounds = this->useHighBounds();
size_t posInExpressions = 0;
@ -1135,6 +1140,7 @@ void IndexRangeBlock::buildExpressions () {
// the current incoming item:
AqlItemBlock* cur = _buffer.front();
auto en = static_cast<IndexRangeNode const*>(getPlanNode());
std::unique_ptr<IndexOrCondition> newCondition;
for (size_t i = 0; i < en->_ranges.size(); i++) {
@ -1177,7 +1183,9 @@ void IndexRangeBlock::buildExpressions () {
}
if (! bound.isArray()) {
if (useHighBounds) {
auto b(bound.copy());
RangeInfo ri(r._var,
r._attr,
RangeInfoBound(l.inclusive(), true, b), // will steal b's JSON
@ -1188,6 +1196,21 @@ void IndexRangeBlock::buildExpressions () {
collector[k][j].fuse(ri);
}
}
else {
auto b1(bound.copy()); // first instance of bound
auto b2(bound.copy()); // second instance of same bound
RangeInfo ri(r._var,
r._attr,
RangeInfoBound(l.inclusive(), true, b1), // will steal b1's JSON
RangeInfoBound(l.inclusive(), true, b2), // will steal b2's JSON
false);
for (size_t j = 0; j < collector[k].size(); j++) {
collector[k][j].fuse(ri);
}
}
}
else {
std::vector<RangeInfo> riv;
riv.reserve(bound.size());
@ -1207,6 +1230,7 @@ void IndexRangeBlock::buildExpressions () {
}
}
if (useHighBounds) {
for (auto const& h : r._highs) {
Expression* e = _allVariableBoundExpressions[posInExpressions];
TRI_ASSERT(e != nullptr);
@ -1257,7 +1281,7 @@ void IndexRangeBlock::buildExpressions () {
collector[k] = std::move(andCombineRangeInfoVecs(collector[k], riv));
}
}
}
}
@ -1320,6 +1344,9 @@ int IndexRangeBlock::initialize () {
// instanciate expressions:
auto instanciateExpression = [&] (RangeInfoBound const& b) -> void {
AstNode const* a = b.getExpressionAst(_engine->getQuery()->ast());
Expression* expression = nullptr;
{
// all new AstNodes are registered with the Ast in the Query
std::unique_ptr<Expression> e(new Expression(_engine->getQuery()->ast(), a));
@ -1328,7 +1355,8 @@ int IndexRangeBlock::initialize () {
}
_allVariableBoundExpressions.emplace_back(e.get());
auto expression = e.release();
expression = e.release();
}
// Prepare _inVars and _inRegs:
_inVars.emplace_back();
@ -1336,7 +1364,7 @@ int IndexRangeBlock::initialize () {
_inRegs.emplace_back();
std::vector<RegisterId>& inRegsCur = _inRegs.back();
std::unordered_set<Variable*> inVars = expression->variables();
std::unordered_set<Variable*>&& inVars = expression->variables();
for (auto v : inVars) {
inVarsCur.emplace_back(v);
@ -1358,10 +1386,13 @@ int IndexRangeBlock::initialize () {
for (auto const& l : r._lows) {
instanciateExpression(l);
}
if (useHighBounds()) {
for (auto const& h : r._highs) {
instanciateExpression(h);
}
}
}
TRI_IF_FAILURE("IndexRangeBlock::initializeExpressions") {
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
}
@ -2158,7 +2189,7 @@ bool IndexRangeBlock::setupHashIndexSearchValue (IndexAndCondition const& range)
TRI_ASSERT(pid != 0);
char const* name = TRI_AttributeNameShapePid(shaper, pid);
std::string const lookFor = std::string(name);
std::string const lookFor(name);
for (auto x : range) {
if (x._attr == lookFor) { //found attribute

View File

@ -612,6 +612,14 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the high bound values should be taken into account
/// they can be ignored for indexes that only support equality conditions,
/// i.e. primary index, edge index and hash index
////////////////////////////////////////////////////////////////////////////////
bool useHighBounds () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not one of the bounds expressions requires V8
////////////////////////////////////////////////////////////////////////////////