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-- 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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -155,9 +184,11 @@ void Condition::findIndexForAndNode (AstNode const* node, Variable const* refere
|
|||
AstNode* reduced = node->clone(_ast);
|
||||
if (idx->canServeForConditionNode(node, reference, reduced)) {
|
||||
matching.emplace_back(idx);
|
||||
triagens::basics::Json old(TRI_UNKNOWN_MEM_ZONE, node->toJson(TRI_UNKNOWN_MEM_ZONE, false));
|
||||
triagens::basics::Json opt(TRI_UNKNOWN_MEM_ZONE, reduced->toJson(TRI_UNKNOWN_MEM_ZONE, false));
|
||||
std::cout << old << "\n=>\n" << opt << std::endl;
|
||||
std::cout << "\n===============\n" << std::endl;
|
||||
dumpNode(node, 2);
|
||||
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;
|
||||
|
@ -430,35 +461,8 @@ void Condition::optimize (ExecutionPlan* plan) {
|
|||
/// @brief dump a condition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace triagens {
|
|||
AstNode* reducedNode) const {
|
||||
TRI_ASSERT(internals != nullptr);
|
||||
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,
|
||||
triagens::aql::Variable const* reference,
|
||||
std::unordered_set<std::string>& found) const {
|
||||
triagens::aql::Variable const* reference) const {
|
||||
if (access->type == triagens::aql::NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||
TRI_ASSERT(access->numMembers() == 1);
|
||||
if (access->getMember(0)->getData() != reference) {
|
||||
|
@ -708,7 +707,6 @@ bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
|||
TRI_AttributeNamesToString(field, comp);
|
||||
if (attr == comp) {
|
||||
// This index knows this attribute
|
||||
found.emplace(attr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -720,22 +718,26 @@ bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
|||
bool HashIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
std::unordered_set<std::string> found;
|
||||
size_t removed = 0;
|
||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||
auto op = node->getMember(i);
|
||||
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (accessFitsIndex(op->getMember(0), reference, found) ||
|
||||
accessFitsIndex(op->getMember(1), reference, found)) {
|
||||
if (found.size() == _fields.size()) {
|
||||
if (accessFitsIndex(op->getMember(0), reference) ||
|
||||
accessFitsIndex(op->getMember(1), reference)) {
|
||||
reducedNode->removeMemberUnchecked(i - removed);
|
||||
removed++;
|
||||
if (removed == _fields.size()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (accessFitsIndex(op->getMember(0), reference, found)) {
|
||||
if (found.size() == _fields.size()) {
|
||||
if (accessFitsIndex(op->getMember(0), reference)) {
|
||||
reducedNode->removeMemberUnchecked(i - removed);
|
||||
removed++;
|
||||
if (removed == _fields.size()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,8 +146,7 @@ namespace triagens {
|
|||
int removeMulti (struct TRI_doc_mptr_t const*, bool);
|
||||
|
||||
bool accessFitsIndex (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*,
|
||||
std::unordered_set<std::string>& found) const;
|
||||
triagens::aql::Variable const*) const;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private classes
|
||||
|
|
Loading…
Reference in New Issue