mirror of https://gitee.com/bigwinds/arangodb
slightly less copying
This commit is contained in:
parent
54e12bb972
commit
cb0ff510d6
|
@ -2229,8 +2229,8 @@ AstNode* Ast::nodeFromJson (TRI_json_t const* json) {
|
|||
size_t const n = json->_value._objects._length;
|
||||
|
||||
for (size_t i = 0; i < n; i += 2) {
|
||||
TRI_json_t const* key = static_cast<TRI_json_t const*>(TRI_AddressVector(&json->_value._objects, i));
|
||||
TRI_json_t const* value = static_cast<TRI_json_t const*>(TRI_AddressVector(&json->_value._objects, i + 1));
|
||||
auto key = static_cast<TRI_json_t const*>(TRI_AddressVector(&json->_value._objects, i));
|
||||
auto value = static_cast<TRI_json_t const*>(TRI_AddressVector(&json->_value._objects, i + 1));
|
||||
|
||||
if (! TRI_IsStringJson(key) || value == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unexpected type found in object node");
|
||||
|
|
|
@ -1145,10 +1145,13 @@ void IndexRangeBlock::buildExpressions () {
|
|||
// collect the evaluated bounds here
|
||||
for (size_t k = 0; k < n; k++) {
|
||||
auto const& r = en->_ranges[i][k];
|
||||
|
||||
{
|
||||
// First create a new RangeInfo containing only the constant
|
||||
// low and high bound of r:
|
||||
RangeInfo riConst(r._var, r._attr, r._lowConst, r._highConst, r.is1ValueRangeInfo());
|
||||
collector[k].emplace_back(riConst);
|
||||
collector[k].emplace_back(std::move(riConst));
|
||||
}
|
||||
|
||||
// Now work the actual values of the variable lows and highs into
|
||||
// this constant range:
|
||||
|
@ -1200,7 +1203,7 @@ void IndexRangeBlock::buildExpressions () {
|
|||
true));
|
||||
}
|
||||
|
||||
collector[k] = andCombineRangeInfoVecs(collector[k], riv);
|
||||
collector[k] = std::move(andCombineRangeInfoVecs(collector[k], riv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1253,8 @@ void IndexRangeBlock::buildExpressions () {
|
|||
RangeInfoBound(h.inclusive(), true, b2), // will steal b2's JSON
|
||||
true));
|
||||
}
|
||||
collector[k] = andCombineRangeInfoVecs(collector[k], riv);
|
||||
|
||||
collector[k] = std::move(andCombineRangeInfoVecs(collector[k], riv));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,6 +1274,8 @@ void IndexRangeBlock::buildExpressions () {
|
|||
// otherwise the condition is impossible to fulfill
|
||||
// the elements of the direct product of the collector are and
|
||||
// conditions which should be added to newCondition
|
||||
|
||||
// create cartesian product
|
||||
std::unique_ptr<IndexOrCondition> indexAnds(cartesian(collector));
|
||||
|
||||
if (newCondition == nullptr) {
|
||||
|
@ -1277,12 +1283,12 @@ void IndexRangeBlock::buildExpressions () {
|
|||
}
|
||||
else {
|
||||
for (auto const& indexAnd: *indexAnds) {
|
||||
newCondition->emplace_back(indexAnd);
|
||||
}
|
||||
newCondition->emplace_back(std::move(indexAnd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
freeCondition();
|
||||
|
||||
|
@ -1294,7 +1300,6 @@ void IndexRangeBlock::buildExpressions () {
|
|||
removeOverlapsIndexOr(*_condition);
|
||||
}
|
||||
else {
|
||||
// create at least an empty condition
|
||||
_condition = new IndexOrCondition;
|
||||
_freeCondition = true;
|
||||
}
|
||||
|
@ -1313,20 +1318,17 @@ int IndexRangeBlock::initialize () {
|
|||
_allVariableBoundExpressions.clear();
|
||||
|
||||
// instanciate expressions:
|
||||
auto instanciateExpression = [&] (RangeInfoBound& b) -> void {
|
||||
auto instanciateExpression = [&] (RangeInfoBound const& b) -> void {
|
||||
AstNode const* a = b.getExpressionAst(_engine->getQuery()->ast());
|
||||
// all new AstNodes are registered with the Ast in the Query
|
||||
auto e = new Expression(_engine->getQuery()->ast(), a);
|
||||
try {
|
||||
std::unique_ptr<Expression> e(new Expression(_engine->getQuery()->ast(), a));
|
||||
|
||||
TRI_IF_FAILURE("IndexRangeBlock::initialize") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
_allVariableBoundExpressions.emplace_back(e);
|
||||
}
|
||||
catch (...) {
|
||||
delete e;
|
||||
throw;
|
||||
}
|
||||
|
||||
_allVariableBoundExpressions.emplace_back(e.get());
|
||||
auto expression = e.release();
|
||||
|
||||
// Prepare _inVars and _inRegs:
|
||||
_inVars.emplace_back();
|
||||
|
@ -1334,7 +1336,8 @@ int IndexRangeBlock::initialize () {
|
|||
_inRegs.emplace_back();
|
||||
std::vector<RegisterId>& inRegsCur = _inRegs.back();
|
||||
|
||||
std::unordered_set<Variable*> inVars = e->variables();
|
||||
std::unordered_set<Variable*> inVars = expression->variables();
|
||||
|
||||
for (auto v : inVars) {
|
||||
inVarsCur.emplace_back(v);
|
||||
auto it = getPlanNode()->getRegisterPlan()->varInfo.find(v->id);
|
||||
|
@ -1342,7 +1345,6 @@ int IndexRangeBlock::initialize () {
|
|||
TRI_ASSERT(it->second.registerId < ExecutionNode::MaxRegisterId);
|
||||
inRegsCur.emplace_back(it->second.registerId);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Get the ranges from the node:
|
||||
|
@ -1352,11 +1354,11 @@ int IndexRangeBlock::initialize () {
|
|||
for (size_t i = 0; i < orRanges.size(); i++) {
|
||||
if (! _allBoundsConstant[i]) {
|
||||
try {
|
||||
for (auto r : orRanges[i]) {
|
||||
for (auto l : r._lows) {
|
||||
for (auto const& r : orRanges[i]) {
|
||||
for (auto const& l : r._lows) {
|
||||
instanciateExpression(l);
|
||||
}
|
||||
for (auto h : r._highs) {
|
||||
for (auto const& h : r._highs) {
|
||||
instanciateExpression(h);
|
||||
}
|
||||
}
|
||||
|
@ -1504,13 +1506,17 @@ void IndexRangeBlock::sortConditions () {
|
|||
|
||||
for (size_t s = 0; s < n; s++) {
|
||||
_sortCoords.emplace_back(s);
|
||||
std::vector<size_t> next;
|
||||
|
||||
TRI_IF_FAILURE("IndexRangeBlock::sortConditions") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<size_t> next;
|
||||
next.reserve(numFields);
|
||||
prefix.emplace_back(next);
|
||||
prefix.emplace_back(std::move(next));
|
||||
}
|
||||
|
||||
// prefix[s][t] = position in _condition[s] corresponding to the <t>th index
|
||||
// field
|
||||
for (size_t t = 0; t < numFields; t++) {
|
||||
|
@ -1596,6 +1602,12 @@ std::vector<RangeInfo> IndexRangeBlock::andCombineRangeInfoVecs (std::vector<Ran
|
|||
std::vector<RangeInfo> const& riv2) const {
|
||||
std::vector<RangeInfo> out;
|
||||
|
||||
std::unordered_set<TRI_json_t const*, triagens::basics::JsonHash, triagens::basics::JsonEqual> cache(
|
||||
16,
|
||||
triagens::basics::JsonHash(),
|
||||
triagens::basics::JsonEqual()
|
||||
);
|
||||
|
||||
for (RangeInfo const& ri1: riv1) {
|
||||
for (RangeInfo const& ri2: riv2) {
|
||||
RangeInfo x(ri1.clone());
|
||||
|
@ -1605,10 +1617,21 @@ std::vector<RangeInfo> IndexRangeBlock::andCombineRangeInfoVecs (std::vector<Ran
|
|||
TRI_IF_FAILURE("IndexRangeBlock::andCombineRangeInfoVecs") {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
out.emplace_back(x);
|
||||
|
||||
if (x.is1ValueRangeInfo()) {
|
||||
// de-duplicate
|
||||
if (cache.find(x._lowConst.bound().json()) != cache.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cache.emplace(x._lowConst.bound().json());
|
||||
}
|
||||
|
||||
out.emplace_back(std::move(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -2699,7 +2722,7 @@ CalculationBlock::CalculationBlock (ExecutionEngine* engine,
|
|||
_inRegs(),
|
||||
_outReg(ExecutionNode::MaxRegisterId) {
|
||||
|
||||
std::unordered_set<Variable*> inVars = _expression->variables();
|
||||
std::unordered_set<Variable*> const& inVars = _expression->variables();
|
||||
_inVars.reserve(inVars.size());
|
||||
_inRegs.reserve(inVars.size());
|
||||
|
||||
|
|
|
@ -39,28 +39,6 @@
|
|||
using namespace triagens::aql;
|
||||
using Json = triagens::basics::Json;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hasher for JSON value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct JsonHash {
|
||||
size_t operator() (TRI_json_t const* value) const {
|
||||
return TRI_FastHashJson(value);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief equality comparator for JSON values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct JsonEqual {
|
||||
bool operator() (TRI_json_t const* lhs,
|
||||
TRI_json_t const* rhs) const {
|
||||
int res = TRI_CompareValuesJson(lhs, rhs, false);
|
||||
return (res == 0);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief register warning
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -855,7 +833,11 @@ AqlValue Functions::Unique (triagens::aql::Query* query,
|
|||
TRI_json_t const* valueJson = value.json();
|
||||
size_t const n = valueJson->_value._objects._length;
|
||||
|
||||
std::unordered_set<TRI_json_t const*, JsonHash, JsonEqual> values(512, JsonHash(), JsonEqual());
|
||||
std::unordered_set<TRI_json_t const*, triagens::basics::JsonHash, triagens::basics::JsonEqual> values(
|
||||
512,
|
||||
triagens::basics::JsonHash(),
|
||||
triagens::basics::JsonEqual()
|
||||
);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
auto value = static_cast<TRI_json_t const*>(TRI_AddressVector(&valueJson->_value._objects, i));
|
||||
|
@ -941,7 +923,11 @@ AqlValue Functions::UnionDistinct (triagens::aql::Query* query,
|
|||
triagens::arango::AqlTransaction* trx,
|
||||
TRI_document_collection_t const* collection,
|
||||
AqlValue const parameters) {
|
||||
std::unordered_set<TRI_json_t const*, JsonHash, JsonEqual> values(512, JsonHash(), JsonEqual());
|
||||
std::unordered_set<TRI_json_t const*, triagens::basics::JsonHash, triagens::basics::JsonEqual> values(
|
||||
512,
|
||||
triagens::basics::JsonHash(),
|
||||
triagens::basics::JsonEqual()
|
||||
);
|
||||
|
||||
size_t const n = parameters.arraySize();
|
||||
|
||||
|
@ -993,7 +979,11 @@ AqlValue Functions::Intersection (triagens::aql::Query* query,
|
|||
triagens::arango::AqlTransaction* trx,
|
||||
TRI_document_collection_t const* collection,
|
||||
AqlValue const parameters) {
|
||||
std::unordered_set<TRI_json_t const*, JsonHash, JsonEqual> values(512, JsonHash(), JsonEqual());
|
||||
std::unordered_set<TRI_json_t const*, triagens::basics::JsonHash, triagens::basics::JsonEqual> values(
|
||||
512,
|
||||
triagens::basics::JsonHash(),
|
||||
triagens::basics::JsonEqual()
|
||||
);
|
||||
|
||||
size_t const n = parameters.arraySize();
|
||||
|
||||
|
|
|
@ -239,15 +239,17 @@ void RangeInfo::fuse (RangeInfo const& that) {
|
|||
|
||||
// First sort out the constant low bounds:
|
||||
_lowConst.andCombineLowerBounds(that._lowConst);
|
||||
|
||||
// Simply append the variable ones:
|
||||
for (auto l : that._lows) {
|
||||
for (auto const& l : that._lows) {
|
||||
_lows.emplace_back(l);
|
||||
}
|
||||
|
||||
// Sort out the constant high bounds:
|
||||
_highConst.andCombineUpperBounds(that._highConst);
|
||||
|
||||
// Simply append the variable ones:
|
||||
for (auto h : that._highs) {
|
||||
for (auto const& h : that._highs) {
|
||||
_highs.emplace_back(h);
|
||||
}
|
||||
|
||||
|
@ -307,8 +309,8 @@ RangeInfoMap::RangeInfoMap (RangeInfo const& ri) :
|
|||
|
||||
void RangeInfoMap::insert (std::string const& var,
|
||||
std::string const& name,
|
||||
RangeInfoBound low,
|
||||
RangeInfoBound high,
|
||||
RangeInfoBound const& low,
|
||||
RangeInfoBound const& high,
|
||||
bool equality) {
|
||||
insert(RangeInfo(var, name, low, high, equality));
|
||||
}
|
||||
|
@ -602,10 +604,11 @@ RangeInfoMapVec* triagens::aql::orCombineRangeInfoMapVecs (RangeInfoMapVec* lhs,
|
|||
return lhs;
|
||||
}
|
||||
|
||||
try {
|
||||
// avoid inserting overlapping conditions
|
||||
for (size_t i = 0; i < rhs->size(); i++) {
|
||||
auto rim = new RangeInfoMap();
|
||||
try {
|
||||
std::unique_ptr<RangeInfoMap> rim(new RangeInfoMap());
|
||||
|
||||
for (auto x: (*rhs)[i]->_ranges) {
|
||||
for (auto y: x.second) {
|
||||
RangeInfo ri = y.second.clone();
|
||||
|
@ -613,21 +616,21 @@ RangeInfoMapVec* triagens::aql::orCombineRangeInfoMapVecs (RangeInfoMapVec* lhs,
|
|||
}
|
||||
}
|
||||
if (! rim->empty()) {
|
||||
lhs->emplace_back(rim);
|
||||
}
|
||||
else {
|
||||
delete rim;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
delete rim;
|
||||
throw;
|
||||
lhs->emplace_back(rim.get());
|
||||
rim.release();
|
||||
}
|
||||
}
|
||||
|
||||
delete rhs;
|
||||
return lhs;
|
||||
}
|
||||
catch (...) {
|
||||
// avoid leaking
|
||||
delete lhs;
|
||||
delete rhs;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief andCombineRangeInfoMaps: insert every RangeInfo in the <rhs> in the
|
||||
|
@ -673,7 +676,7 @@ RangeInfoMapVec* triagens::aql::andCombineRangeInfoMapVecs (RangeInfoMapVec* lhs
|
|||
std::unique_ptr<RangeInfoMapVec> rimv(new RangeInfoMapVec()); // must be a new one
|
||||
for (size_t i = 0; i < lhs->size(); i++) {
|
||||
for (size_t j = 0; j < rhs->size(); j++) {
|
||||
rimv->emplace_back(andCombineRangeInfoMaps((*lhs)[i]->clone(), (*rhs)[j]->clone()));
|
||||
rimv->emplace_back(std::move(andCombineRangeInfoMaps((*lhs)[i]->clone(), (*rhs)[j]->clone())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -866,7 +869,7 @@ bool triagens::aql::areDisjointIndexAndConditions (IndexAndCondition const& and1
|
|||
IndexAndCondition const& and2) {
|
||||
for (auto const& ri1: and1) {
|
||||
for (auto const& ri2: and2) {
|
||||
if (ri2._attr == ri1._attr) {
|
||||
if (ri2._var == ri1._var && ri2._attr == ri1._attr) {
|
||||
if (areDisjointRangeInfos(ri1, ri2)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -888,7 +891,7 @@ bool triagens::aql::isContainedIndexAndConditions (IndexAndCondition const& and1
|
|||
bool contained = false;
|
||||
|
||||
for (auto const& ri2: and2) {
|
||||
if (ri2._attr == ri1._attr) {
|
||||
if (ri2._var == ri1._var && ri2._attr == ri1._attr) {
|
||||
if (ContainmentRangeInfos(ri2, ri1) == 1) {
|
||||
contained = true;
|
||||
break;
|
||||
|
@ -1051,7 +1054,7 @@ void triagens::aql::removeOverlapsIndexOr (IndexOrCondition& ioc) {
|
|||
}
|
||||
}
|
||||
|
||||
// remove empty
|
||||
// remove empty bounds
|
||||
ioc.erase(std::remove_if(ioc.begin(), ioc.end(), [] (IndexAndCondition const& item) -> bool {
|
||||
return item.empty();
|
||||
}), ioc.end());
|
||||
|
|
|
@ -751,8 +751,8 @@ namespace triagens {
|
|||
|
||||
void insert (std::string const& var,
|
||||
std::string const& name,
|
||||
RangeInfoBound low,
|
||||
RangeInfoBound high,
|
||||
RangeInfoBound const& low,
|
||||
RangeInfoBound const& high,
|
||||
bool equality);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -164,6 +164,34 @@ uint64_t TRI_HashJsonByAttributes (TRI_json_t const* json,
|
|||
bool docComplete,
|
||||
int* error);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hasher for JSON value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace triagens {
|
||||
namespace basics {
|
||||
|
||||
struct JsonHash {
|
||||
size_t operator() (TRI_json_t const* value) const {
|
||||
return TRI_FastHashJson(value);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief equality comparator for JSON values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct JsonEqual {
|
||||
bool operator() (TRI_json_t const* lhs,
|
||||
TRI_json_t const* rhs) const {
|
||||
int res = TRI_CompareValuesJson(lhs, rhs, false);
|
||||
return (res == 0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue