1
0
Fork 0
This commit is contained in:
Jan Steemann 2015-04-29 17:42:33 +02:00
parent c99cc2968f
commit 7783ed1b33
6 changed files with 63 additions and 28 deletions

View File

@ -238,7 +238,8 @@ static TRI_json_type_e GetNodeCompareType (AstNode const* node) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int triagens::aql::CompareAstNodes (AstNode const* lhs, int triagens::aql::CompareAstNodes (AstNode const* lhs,
AstNode const* rhs) { AstNode const* rhs,
bool compareUtf8) {
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) { if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
lhs = ResolveAttribute(lhs); lhs = ResolveAttribute(lhs);
} }
@ -251,6 +252,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
if (lType != rType) { if (lType != rType) {
int diff = static_cast<int>(lType) - static_cast<int>(rType); int diff = static_cast<int>(lType) - static_cast<int>(rType);
TRI_ASSERT_EXPENSIVE(diff != 0); TRI_ASSERT_EXPENSIVE(diff != 0);
if (diff < 0) { if (diff < 0) {
@ -268,6 +270,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
} }
else if (lType == TRI_JSON_BOOLEAN) { else if (lType == TRI_JSON_BOOLEAN) {
int diff = static_cast<int>(lhs->getIntValue() - rhs->getIntValue()); int diff = static_cast<int>(lhs->getIntValue() - rhs->getIntValue());
if (diff != 0) { if (diff != 0) {
if (diff < 0) { if (diff < 0) {
return -1; return -1;
@ -286,15 +289,19 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
} }
} }
else if (lType == TRI_JSON_STRING) { else if (lType == TRI_JSON_STRING) {
if (compareUtf8) {
return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue()); return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue());
} }
return strcmp(lhs->getStringValue(), rhs->getStringValue());
}
else if (lType == TRI_JSON_ARRAY) { else if (lType == TRI_JSON_ARRAY) {
size_t const numLhs = lhs->numMembers(); size_t const numLhs = lhs->numMembers();
size_t const numRhs = rhs->numMembers(); size_t const numRhs = rhs->numMembers();
size_t const n = ((numLhs > numRhs) ? numRhs : numLhs); size_t const n = ((numLhs > numRhs) ? numRhs : numLhs);
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
int res = triagens::aql::CompareAstNodes(lhs->getMember(i), rhs->getMember(i)); int res = triagens::aql::CompareAstNodes(lhs->getMember(i), rhs->getMember(i), compareUtf8);
if (res != 0) { if (res != 0) {
return res; return res;
} }
@ -314,7 +321,9 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
// for array AstNodes) // for array AstNodes)
auto lJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE); auto lJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE);
auto rJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE); auto rJson = lhs->toJsonValue(TRI_UNKNOWN_MEM_ZONE);
int res = TRI_CompareValuesJson(lJson, rJson, true);
int res = TRI_CompareValuesJson(lJson, rJson, compareUtf8);
if (lJson != nullptr) { if (lJson != nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, lJson); TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, lJson);
} }
@ -590,11 +599,12 @@ void AstNode::sort () {
auto const ptr = members._buffer; auto const ptr = members._buffer;
auto const end = ptr + members._length; auto const end = ptr + members._length;
std::sort(ptr, end, [] (void const* lhs, void const* rhs) { std::sort(ptr, end, [] (void const* lhs, void const* rhs) {
auto const l = static_cast<AstNode const*>(lhs); auto const l = static_cast<AstNode const*>(lhs);
auto const r = static_cast<AstNode const*>(rhs); auto const r = static_cast<AstNode const*>(rhs);
return (triagens::aql::CompareAstNodes(l, r) < 0); return (triagens::aql::CompareAstNodes(l, r, false) < 0);
}); });
setFlag(DETERMINED_SORTED, VALUE_SORTED); setFlag(DETERMINED_SORTED, VALUE_SORTED);
@ -606,6 +616,7 @@ void AstNode::sort () {
std::string const& AstNode::getTypeString () const { std::string const& AstNode::getTypeString () const {
auto it = TypeNames.find(static_cast<int>(type)); auto it = TypeNames.find(static_cast<int>(type));
if (it != TypeNames.end()) { if (it != TypeNames.end()) {
return (*it).second; return (*it).second;
} }

View File

@ -751,7 +751,7 @@ namespace triagens {
}; };
int CompareAstNodes (AstNode const*, AstNode const*); int CompareAstNodes (AstNode const*, AstNode const*, bool);
} }
} }

View File

@ -1059,13 +1059,18 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
_hasV8Expression(false) { _hasV8Expression(false) {
auto trxCollection = _trx->trxCollection(_collection->cid()); auto trxCollection = _trx->trxCollection(_collection->cid());
if (trxCollection != nullptr) { if (trxCollection != nullptr) {
_trx->orderBarrier(trxCollection); _trx->orderBarrier(trxCollection);
} }
for (size_t i = 0; i < en->_ranges.size(); i++) { std::vector<std::vector<RangeInfo>> const& orRanges = en->_ranges;
size_t const n = orRanges.size();
for (size_t i = 0; i < n; i++) {
_condition->emplace_back(IndexAndCondition()); _condition->emplace_back(IndexAndCondition());
for (auto ri: en->_ranges[i]) {
for (auto const& ri: en->_ranges[i]) {
_condition->at(i).emplace_back(ri.clone()); _condition->at(i).emplace_back(ri.clone());
} }
} }
@ -1074,7 +1079,6 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
removeOverlapsIndexOr(*_condition); removeOverlapsIndexOr(*_condition);
} }
std::vector<std::vector<RangeInfo>> const& orRanges = en->_ranges;
TRI_ASSERT(en->_index != nullptr); TRI_ASSERT(en->_index != nullptr);
_allBoundsConstant.clear(); _allBoundsConstant.clear();
@ -1083,8 +1087,9 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
// Detect, whether all ranges are constant: // Detect, whether all ranges are constant:
for (size_t i = 0; i < orRanges.size(); i++) { for (size_t i = 0; i < orRanges.size(); i++) {
bool isConstant = true; bool isConstant = true;
std::vector<RangeInfo> const& attrRanges = orRanges[i]; std::vector<RangeInfo> const& attrRanges = orRanges[i];
for (auto r : attrRanges) { for (auto const& r : attrRanges) {
isConstant &= r.isConstant(); isConstant &= r.isConstant();
} }
_anyBoundVariable |= ! isConstant; _anyBoundVariable |= ! isConstant;

View File

@ -1679,8 +1679,8 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
if (enumCollVar != nullptr) { if (enumCollVar != nullptr) {
foundSomething = true; foundSomething = true;
std::unordered_set<Variable*> varsUsed std::unordered_set<Variable*>&& varsUsed = Ast::getReferencedVariables(lhs);
= Ast::getReferencedVariables(lhs);
if (varsUsed.find(const_cast<Variable*>(enumCollVar)) if (varsUsed.find(const_cast<Variable*>(enumCollVar))
== varsUsed.end()) { == varsUsed.end()) {
// Found a multiple attribute access of a variable and an // Found a multiple attribute access of a variable and an
@ -1847,9 +1847,7 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
RangeInfo ri(enumCollVar->name, RangeInfo ri(enumCollVar->name,
attr.substr(0, attr.size() - 1), attr.substr(0, attr.size() - 1),
RangeInfoBound(rhs->getMember(i), true), RangeInfoBound(rhs->getMember(i), true));
RangeInfoBound(rhs->getMember(i), true),
true);
// the following does not seem to be necessary here, but will slow things down // the following does not seem to be necessary here, but will slow things down
// considerably if the array is very big // considerably if the array is very big
// rimv->differenceRangeInfo(ri); // rimv->differenceRangeInfo(ri);
@ -1863,9 +1861,7 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
else { else {
RangeInfo ri(enumCollVar->name, RangeInfo ri(enumCollVar->name,
attr.substr(0, attr.size() - 1), attr.substr(0, attr.size() - 1),
RangeInfoBound(rhs, true), RangeInfoBound(rhs, true));
RangeInfoBound(rhs, true),
true);
rimv->differenceRangeInfo(ri); rimv->differenceRangeInfo(ri);
if (ri.isValid()) { if (ri.isValid()) {
std::unique_ptr<RangeInfoMap> temp(new RangeInfoMap(ri)); std::unique_ptr<RangeInfoMap> temp(new RangeInfoMap(ri));
@ -2105,14 +2101,14 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
// results), for example // results), for example
// x.a == 1 || y.c == 2 || x.a == 3 // x.a == 1 || y.c == 2 || x.a == 3
if (_rangeInfoMapVec->isMapped(var->name)) { if (_rangeInfoMapVec->isMapped(var->name)) {
std::vector<size_t> const validPos = _rangeInfoMapVec->validPositions(var->name); std::vector<size_t>&& validPos = _rangeInfoMapVec->validPositions(var->name);
// are any of the RangeInfoMaps in the vector valid? // are any of the RangeInfoMaps in the vector valid?
if (! _canThrow) { if (! _canThrow) {
if (validPos.empty()) { // ranges are not valid . . . if (validPos.empty()) { // ranges are not valid . . .
auto parents = node->getParents(); auto parents = node->getParents();
for (auto x : parents) { for (auto const& x : parents) {
auto noRes = new NoResultsNode(_plan, _plan->nextId()); auto noRes = new NoResultsNode(_plan, _plan->nextId());
_plan->registerNode(noRes); _plan->registerNode(noRes);
_plan->insertDependency(x, noRes); _plan->insertDependency(x, noRes);
@ -2127,8 +2123,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
// note: prefixes are only used for skiplist indexes // note: prefixes are only used for skiplist indexes
// for all other index types, the prefix value will always be 0 // for all other index types, the prefix value will always be 0
node->getIndexesForIndexRangeNode( node->getIndexesForIndexRangeNode(_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
// make one new plan for every index in <idxs> that replaces the // make one new plan for every index in <idxs> that replaces the
// enumerate collection node with a IndexRangeNode ... // enumerate collection node with a IndexRangeNode ...
@ -4347,7 +4342,7 @@ struct RemoveRedundantOr {
// returns false if the existing value is better and true if the input value is // returns false if the existing value is better and true if the input value is
// better // better
bool compareBounds (AstNodeType type, AstNode const* value, int lowhigh) { bool compareBounds (AstNodeType type, AstNode const* value, int lowhigh) {
int cmp = CompareAstNodes(bestValue, value); int cmp = CompareAstNodes(bestValue, value, true);
if (cmp == 0 && (isInclusiveBound(comparison) != isInclusiveBound(type))) { if (cmp == 0 && (isInclusiveBound(comparison) != isInclusiveBound(type))) {
return (isInclusiveBound(type) ? true : false); return (isInclusiveBound(type) ? true : false);

View File

@ -427,7 +427,7 @@ void RangeInfoMap::attributes (std::unordered_set<std::string>& set,
std::unordered_map<std::string, RangeInfo> const* map = find(var); std::unordered_map<std::string, RangeInfo> const* map = find(var);
if (map != nullptr) { if (map != nullptr) {
for (auto x: *map) { for (auto const& x: *map) {
set.emplace(x.first); set.emplace(x.first);
} }
} }
@ -527,7 +527,9 @@ bool RangeInfoMapVec::isMapped (std::string const& var) const {
std::vector<size_t> RangeInfoMapVec::validPositions (std::string const& var) const { std::vector<size_t> RangeInfoMapVec::validPositions (std::string const& var) const {
std::vector<size_t> valid; std::vector<size_t> valid;
for (size_t i = 0; i < _rangeInfoMapVec.size(); i++) { size_t const n = _rangeInfoMapVec.size();
for (size_t i = 0; i < n; i++) {
if (_rangeInfoMapVec[i]->isValid(var)) { if (_rangeInfoMapVec[i]->isValid(var)) {
valid.emplace_back(i); valid.emplace_back(i);
} }

View File

@ -373,8 +373,8 @@ namespace triagens {
RangeInfo (std::string const& var, RangeInfo (std::string const& var,
std::string const& attr, std::string const& attr,
RangeInfoBound low, RangeInfoBound const& low,
RangeInfoBound high, RangeInfoBound const& high,
bool equality) bool equality)
: _var(var), : _var(var),
_attr(attr), _attr(attr),
@ -415,6 +415,28 @@ namespace triagens {
} }
} }
RangeInfo (std::string const& var,
std::string const& attr,
RangeInfoBound const& bound)
: _var(var),
_attr(attr),
_valid(true),
_defined(true),
_equality(true) {
// must be an equality here!
TRI_ASSERT(bound.inclusive());
if (bound.isConstant()) {
_lowConst.assign(bound);
_highConst.assign(bound);
}
else {
_lows.emplace_back(bound);
_highs.emplace_back(bound);
}
}
RangeInfo (std::string const& var, RangeInfo (std::string const& var,
std::string const& attr) std::string const& attr)
: _var(var), : _var(var),