mirror of https://gitee.com/bigwinds/arangodb
Allowed the hashIndex to modify the DNF and-block node. It now successfully removes all entries it can be responsible for
This commit is contained in:
parent
614902ee99
commit
eae6394f22
|
@ -80,6 +80,35 @@ void ConditionPart::dump () const {
|
||||||
// --SECTION-- class Condition
|
// --SECTION-- class Condition
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- static helper function
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
static void dumpNode (AstNode const* node, int indent) {
|
||||||
|
if (node == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < indent * 2; ++i) {
|
||||||
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << node->getTypeString();
|
||||||
|
if (node->type == NODE_TYPE_VALUE) {
|
||||||
|
std::cout << " (value " << triagens::basics::JsonHelper::toString(node->toJsonValue(TRI_UNKNOWN_MEM_ZONE)) << ")";
|
||||||
|
}
|
||||||
|
else if (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
|
std::cout << " (attribute " << node->getStringValue() << ")";
|
||||||
|
}
|
||||||
|
else if (node->type == NODE_TYPE_REFERENCE) {
|
||||||
|
std::cout << " (name " << node->getStringValue() << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n";
|
||||||
|
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||||
|
dumpNode(node->getMember(i), indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- constructors / destructors
|
// --SECTION-- constructors / destructors
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -155,9 +184,11 @@ void Condition::findIndexForAndNode (AstNode const* node, Variable const* refere
|
||||||
AstNode* reduced = node->clone(_ast);
|
AstNode* reduced = node->clone(_ast);
|
||||||
if (idx->canServeForConditionNode(node, reference, reduced)) {
|
if (idx->canServeForConditionNode(node, reference, reduced)) {
|
||||||
matching.emplace_back(idx);
|
matching.emplace_back(idx);
|
||||||
triagens::basics::Json old(TRI_UNKNOWN_MEM_ZONE, node->toJson(TRI_UNKNOWN_MEM_ZONE, false));
|
std::cout << "\n===============\n" << std::endl;
|
||||||
triagens::basics::Json opt(TRI_UNKNOWN_MEM_ZONE, reduced->toJson(TRI_UNKNOWN_MEM_ZONE, false));
|
dumpNode(node, 2);
|
||||||
std::cout << old << "\n=>\n" << opt << std::endl;
|
std::cout << "\n=>\n" << std::endl;
|
||||||
|
dumpNode(reduced, 2);
|
||||||
|
std::cout << "\n===============\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "We can use indexes for var: " << reference->name << " in collection " << colNode->collection()->getName() << ":" << std::endl;
|
std::cout << "We can use indexes for var: " << reference->name << " in collection " << colNode->collection()->getName() << ":" << std::endl;
|
||||||
|
@ -430,35 +461,8 @@ void Condition::optimize (ExecutionPlan* plan) {
|
||||||
/// @brief dump a condition
|
/// @brief dump a condition
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
void Condition::dump () const {
|
void Condition::dump () const {
|
||||||
std::function<void(AstNode const*, int)> dumpNode;
|
|
||||||
|
|
||||||
dumpNode = [&dumpNode] (AstNode const* node, int indent) {
|
|
||||||
if (node == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < indent * 2; ++i) {
|
|
||||||
std::cout << " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << node->getTypeString();
|
|
||||||
if (node->type == NODE_TYPE_VALUE) {
|
|
||||||
std::cout << " (value " << triagens::basics::JsonHelper::toString(node->toJsonValue(TRI_UNKNOWN_MEM_ZONE)) << ")";
|
|
||||||
}
|
|
||||||
else if (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
|
|
||||||
std::cout << " (attribute " << node->getStringValue() << ")";
|
|
||||||
}
|
|
||||||
else if (node->type == NODE_TYPE_REFERENCE) {
|
|
||||||
std::cout << " (name " << node->getStringValue() << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "\n";
|
|
||||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
|
||||||
dumpNode(node->getMember(i), indent + 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
dumpNode(_root, 0);
|
dumpNode(_root, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ namespace triagens {
|
||||||
AstNode* reducedNode) const {
|
AstNode* reducedNode) const {
|
||||||
TRI_ASSERT(internals != nullptr);
|
TRI_ASSERT(internals != nullptr);
|
||||||
auto internals = getInternals();
|
auto internals = getInternals();
|
||||||
return internals->canServeForConditionNode(node, reference, nullptr);
|
return internals->canServeForConditionNode(node, reference, reducedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -693,8 +693,7 @@ int HashIndex::removeMulti (TRI_doc_mptr_t const* doc, bool isRollback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
||||||
triagens::aql::Variable const* reference,
|
triagens::aql::Variable const* reference) const {
|
||||||
std::unordered_set<std::string>& found) const {
|
|
||||||
if (access->type == triagens::aql::NODE_TYPE_ATTRIBUTE_ACCESS) {
|
if (access->type == triagens::aql::NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||||
TRI_ASSERT(access->numMembers() == 1);
|
TRI_ASSERT(access->numMembers() == 1);
|
||||||
if (access->getMember(0)->getData() != reference) {
|
if (access->getMember(0)->getData() != reference) {
|
||||||
|
@ -708,7 +707,6 @@ bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
||||||
TRI_AttributeNamesToString(field, comp);
|
TRI_AttributeNamesToString(field, comp);
|
||||||
if (attr == comp) {
|
if (attr == comp) {
|
||||||
// This index knows this attribute
|
// This index knows this attribute
|
||||||
found.emplace(attr);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,22 +718,26 @@ bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
||||||
bool HashIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
bool HashIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||||
triagens::aql::Variable const* reference,
|
triagens::aql::Variable const* reference,
|
||||||
triagens::aql::AstNode* reducedNode) const {
|
triagens::aql::AstNode* reducedNode) const {
|
||||||
std::unordered_set<std::string> found;
|
size_t removed = 0;
|
||||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||||
auto op = node->getMember(i);
|
auto op = node->getMember(i);
|
||||||
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
|
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
|
||||||
TRI_ASSERT(op->numMembers() == 2);
|
TRI_ASSERT(op->numMembers() == 2);
|
||||||
if (accessFitsIndex(op->getMember(0), reference, found) ||
|
if (accessFitsIndex(op->getMember(0), reference) ||
|
||||||
accessFitsIndex(op->getMember(1), reference, found)) {
|
accessFitsIndex(op->getMember(1), reference)) {
|
||||||
if (found.size() == _fields.size()) {
|
reducedNode->removeMemberUnchecked(i - removed);
|
||||||
|
removed++;
|
||||||
|
if (removed == _fields.size()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
|
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
|
||||||
TRI_ASSERT(op->numMembers() == 2);
|
TRI_ASSERT(op->numMembers() == 2);
|
||||||
if (accessFitsIndex(op->getMember(0), reference, found)) {
|
if (accessFitsIndex(op->getMember(0), reference)) {
|
||||||
if (found.size() == _fields.size()) {
|
reducedNode->removeMemberUnchecked(i - removed);
|
||||||
|
removed++;
|
||||||
|
if (removed == _fields.size()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,7 @@ namespace triagens {
|
||||||
int removeMulti (struct TRI_doc_mptr_t const*, bool);
|
int removeMulti (struct TRI_doc_mptr_t const*, bool);
|
||||||
|
|
||||||
bool accessFitsIndex (triagens::aql::AstNode const*,
|
bool accessFitsIndex (triagens::aql::AstNode const*,
|
||||||
triagens::aql::Variable const*,
|
triagens::aql::Variable const*) const;
|
||||||
std::unordered_set<std::string>& found) const;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private classes
|
// --SECTION-- private classes
|
||||||
|
|
Loading…
Reference in New Issue