1
0
Fork 0

slightly less copying

This commit is contained in:
Jan Steemann 2015-04-30 16:50:08 +02:00
parent 54e12bb972
commit cb0ff510d6
6 changed files with 128 additions and 84 deletions

View File

@ -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");

View File

@ -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());

View File

@ -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();

View File

@ -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;
}
//avoid inserting overlapping conditions
for (size_t i = 0; i < rhs->size(); i++) {
auto rim = new RangeInfoMap();
try {
// avoid inserting overlapping conditions
for (size_t i = 0; i < rhs->size(); i++) {
std::unique_ptr<RangeInfoMap> rim(new RangeInfoMap());
for (auto x: (*rhs)[i]->_ranges) {
for (auto y: x.second) {
RangeInfo ri = y.second.clone();
@ -613,20 +616,20 @@ 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;
}
}
////////////////////////////////////////////////////////////////////////////////
@ -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());

View File

@ -734,7 +734,7 @@ namespace triagens {
auto it = map->find(attr);
if (it == map->end()){
if (it == map->end()) {
return nullptr;
}
@ -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);
////////////////////////////////////////////////////////////////////////////////

View File

@ -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
// -----------------------------------------------------------------------------