mirror of https://gitee.com/bigwinds/arangodb
speedups
This commit is contained in:
parent
c99cc2968f
commit
7783ed1b33
|
@ -238,7 +238,8 @@ static TRI_json_type_e GetNodeCompareType (AstNode const* node) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
||||
AstNode const* rhs) {
|
||||
AstNode const* rhs,
|
||||
bool compareUtf8) {
|
||||
if (lhs->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||
lhs = ResolveAttribute(lhs);
|
||||
}
|
||||
|
@ -251,6 +252,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
|||
|
||||
if (lType != rType) {
|
||||
int diff = static_cast<int>(lType) - static_cast<int>(rType);
|
||||
|
||||
TRI_ASSERT_EXPENSIVE(diff != 0);
|
||||
|
||||
if (diff < 0) {
|
||||
|
@ -268,6 +270,7 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
|||
}
|
||||
else if (lType == TRI_JSON_BOOLEAN) {
|
||||
int diff = static_cast<int>(lhs->getIntValue() - rhs->getIntValue());
|
||||
|
||||
if (diff != 0) {
|
||||
if (diff < 0) {
|
||||
return -1;
|
||||
|
@ -286,7 +289,10 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
|||
}
|
||||
}
|
||||
else if (lType == TRI_JSON_STRING) {
|
||||
return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue());
|
||||
if (compareUtf8) {
|
||||
return TRI_compare_utf8(lhs->getStringValue(), rhs->getStringValue());
|
||||
}
|
||||
return strcmp(lhs->getStringValue(), rhs->getStringValue());
|
||||
}
|
||||
else if (lType == TRI_JSON_ARRAY) {
|
||||
size_t const numLhs = lhs->numMembers();
|
||||
|
@ -294,7 +300,8 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
|||
size_t const n = ((numLhs > numRhs) ? numRhs : numLhs);
|
||||
|
||||
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) {
|
||||
return res;
|
||||
}
|
||||
|
@ -314,7 +321,9 @@ int triagens::aql::CompareAstNodes (AstNode const* lhs,
|
|||
// for array AstNodes)
|
||||
auto lJson = 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) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, lJson);
|
||||
}
|
||||
|
@ -590,11 +599,12 @@ void AstNode::sort () {
|
|||
|
||||
auto const ptr = members._buffer;
|
||||
auto const end = ptr + members._length;
|
||||
|
||||
std::sort(ptr, end, [] (void const* lhs, void const* rhs) {
|
||||
auto const l = static_cast<AstNode const*>(lhs);
|
||||
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);
|
||||
|
@ -606,6 +616,7 @@ void AstNode::sort () {
|
|||
|
||||
std::string const& AstNode::getTypeString () const {
|
||||
auto it = TypeNames.find(static_cast<int>(type));
|
||||
|
||||
if (it != TypeNames.end()) {
|
||||
return (*it).second;
|
||||
}
|
||||
|
|
|
@ -751,7 +751,7 @@ namespace triagens {
|
|||
|
||||
};
|
||||
|
||||
int CompareAstNodes (AstNode const*, AstNode const*);
|
||||
int CompareAstNodes (AstNode const*, AstNode const*, bool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1059,13 +1059,18 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
|
|||
_hasV8Expression(false) {
|
||||
|
||||
auto trxCollection = _trx->trxCollection(_collection->cid());
|
||||
|
||||
if (trxCollection != nullptr) {
|
||||
_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());
|
||||
for (auto ri: en->_ranges[i]) {
|
||||
|
||||
for (auto const& ri: en->_ranges[i]) {
|
||||
_condition->at(i).emplace_back(ri.clone());
|
||||
}
|
||||
}
|
||||
|
@ -1074,7 +1079,6 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
|
|||
removeOverlapsIndexOr(*_condition);
|
||||
}
|
||||
|
||||
std::vector<std::vector<RangeInfo>> const& orRanges = en->_ranges;
|
||||
TRI_ASSERT(en->_index != nullptr);
|
||||
|
||||
_allBoundsConstant.clear();
|
||||
|
@ -1083,8 +1087,9 @@ IndexRangeBlock::IndexRangeBlock (ExecutionEngine* engine,
|
|||
// Detect, whether all ranges are constant:
|
||||
for (size_t i = 0; i < orRanges.size(); i++) {
|
||||
bool isConstant = true;
|
||||
|
||||
std::vector<RangeInfo> const& attrRanges = orRanges[i];
|
||||
for (auto r : attrRanges) {
|
||||
for (auto const& r : attrRanges) {
|
||||
isConstant &= r.isConstant();
|
||||
}
|
||||
_anyBoundVariable |= ! isConstant;
|
||||
|
|
|
@ -1679,8 +1679,8 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
|
|||
if (enumCollVar != nullptr) {
|
||||
foundSomething = true;
|
||||
|
||||
std::unordered_set<Variable*> varsUsed
|
||||
= Ast::getReferencedVariables(lhs);
|
||||
std::unordered_set<Variable*>&& varsUsed = Ast::getReferencedVariables(lhs);
|
||||
|
||||
if (varsUsed.find(const_cast<Variable*>(enumCollVar))
|
||||
== varsUsed.end()) {
|
||||
// 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++) {
|
||||
RangeInfo ri(enumCollVar->name,
|
||||
attr.substr(0, attr.size() - 1),
|
||||
RangeInfoBound(rhs->getMember(i), true),
|
||||
RangeInfoBound(rhs->getMember(i), true),
|
||||
true);
|
||||
RangeInfoBound(rhs->getMember(i), true));
|
||||
// the following does not seem to be necessary here, but will slow things down
|
||||
// considerably if the array is very big
|
||||
// rimv->differenceRangeInfo(ri);
|
||||
|
@ -1863,9 +1861,7 @@ static RangeInfoMapVec* BuildRangeInfo (ExecutionPlan* plan,
|
|||
else {
|
||||
RangeInfo ri(enumCollVar->name,
|
||||
attr.substr(0, attr.size() - 1),
|
||||
RangeInfoBound(rhs, true),
|
||||
RangeInfoBound(rhs, true),
|
||||
true);
|
||||
RangeInfoBound(rhs, true));
|
||||
rimv->differenceRangeInfo(ri);
|
||||
if (ri.isValid()) {
|
||||
std::unique_ptr<RangeInfoMap> temp(new RangeInfoMap(ri));
|
||||
|
@ -2105,14 +2101,14 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
// results), for example
|
||||
// x.a == 1 || y.c == 2 || x.a == 3
|
||||
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?
|
||||
|
||||
if (! _canThrow) {
|
||||
if (validPos.empty()) { // ranges are not valid . . .
|
||||
auto parents = node->getParents();
|
||||
for (auto x : parents) {
|
||||
for (auto const& x : parents) {
|
||||
auto noRes = new NoResultsNode(_plan, _plan->nextId());
|
||||
_plan->registerNode(noRes);
|
||||
_plan->insertDependency(x, noRes);
|
||||
|
@ -2127,8 +2123,7 @@ class FilterToEnumCollFinder : public WalkerWorker<ExecutionNode> {
|
|||
|
||||
// note: prefixes are only used for skiplist indexes
|
||||
// for all other index types, the prefix value will always be 0
|
||||
node->getIndexesForIndexRangeNode(
|
||||
_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
|
||||
node->getIndexesForIndexRangeNode(_rangeInfoMapVec->attributes(var->name), idxs, prefixes);
|
||||
// make one new plan for every index in <idxs> that replaces the
|
||||
// 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
|
||||
// better
|
||||
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))) {
|
||||
return (isInclusiveBound(type) ? true : false);
|
||||
|
|
|
@ -427,7 +427,7 @@ void RangeInfoMap::attributes (std::unordered_set<std::string>& set,
|
|||
std::unordered_map<std::string, RangeInfo> const* map = find(var);
|
||||
|
||||
if (map != nullptr) {
|
||||
for (auto x: *map) {
|
||||
for (auto const& x: *map) {
|
||||
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> 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)) {
|
||||
valid.emplace_back(i);
|
||||
}
|
||||
|
|
|
@ -373,8 +373,8 @@ namespace triagens {
|
|||
|
||||
RangeInfo (std::string const& var,
|
||||
std::string const& attr,
|
||||
RangeInfoBound low,
|
||||
RangeInfoBound high,
|
||||
RangeInfoBound const& low,
|
||||
RangeInfoBound const& high,
|
||||
bool equality)
|
||||
: _var(var),
|
||||
_attr(attr),
|
||||
|
@ -414,6 +414,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,
|
||||
std::string const& attr)
|
||||
|
|
Loading…
Reference in New Issue