mirror of https://gitee.com/bigwinds/arangodb
Added a modifyable AST node to the index can serve and block functionality of all indicies. However non of them uses it yet
This commit is contained in:
parent
a891d8653b
commit
aefc0edae0
|
@ -563,7 +563,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief remove a memmer from the node
|
||||
/// @brief remove a member from the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void removeMemberUnchecked (size_t i) {
|
||||
|
|
|
@ -152,17 +152,24 @@ void Condition::findIndexForAndNode (AstNode const* node, Variable const* refere
|
|||
std::vector<Index*> indexes = colNode->collection()->getIndexes();
|
||||
std::vector<Index*> matching;
|
||||
for (auto& idx : indexes) {
|
||||
if (idx->canServeForConditionNode(node, reference)) {
|
||||
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 << "We can use indexes for var: " << reference->name << " in collection " << colNode->collection()->getName() << ":" << std::endl;
|
||||
for (auto& idx : matching) {
|
||||
std::cout << idx->toJson() << std::endl;
|
||||
/*
|
||||
std::cout << "Type" << idx->type;
|
||||
if (idx->hasSelectivityEstimate()) {
|
||||
std::cout << " Estimate: " << idx->selectivityEstimate();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
*/
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
|
|
@ -161,10 +161,12 @@ namespace triagens {
|
|||
internals = idx;
|
||||
}
|
||||
|
||||
bool canServeForConditionNode (AstNode const* node, Variable const* reference) const {
|
||||
bool canServeForConditionNode (AstNode const* node,
|
||||
Variable const* reference,
|
||||
AstNode* reducedNode) const {
|
||||
TRI_ASSERT(internals != nullptr);
|
||||
auto internals = getInternals();
|
||||
return internals->canServeForConditionNode(node, reference);
|
||||
return internals->canServeForConditionNode(node, reference, nullptr);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -557,7 +557,9 @@ static bool accessFitsIndex (triagens::aql::AstNode const* access, triagens::aql
|
|||
return false;
|
||||
}
|
||||
|
||||
bool EdgeIndex::canServeForConditionNode (triagens::aql::AstNode const* node, triagens::aql::Variable const* reference) const {
|
||||
bool EdgeIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||
auto op = node->getMember(i);
|
||||
if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ) {
|
||||
|
|
|
@ -128,7 +128,8 @@ namespace triagens {
|
|||
}
|
||||
|
||||
bool canServeForConditionNode (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*) const;
|
||||
triagens::aql::Variable const*,
|
||||
triagens::aql::AstNode*) const override;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
|
|
@ -718,7 +718,8 @@ bool HashIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
|||
}
|
||||
|
||||
bool HashIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference) const {
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
std::unordered_set<std::string> found;
|
||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||
auto op = node->getMember(i);
|
||||
|
|
|
@ -121,8 +121,8 @@ namespace triagens {
|
|||
|
||||
|
||||
bool canServeForConditionNode (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*) const;
|
||||
|
||||
triagens::aql::Variable const*,
|
||||
triagens::aql::AstNode*) const override;
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -428,7 +428,9 @@ bool Index::hasBatchInsert () const {
|
|||
/// @brief default implementation for canServeForConditionNode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Index::canServeForConditionNode (triagens::aql::AstNode const* node, triagens::aql::Variable const* reference) const {
|
||||
bool Index::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -291,7 +291,9 @@ namespace triagens {
|
|||
|
||||
virtual bool hasBatchInsert () const;
|
||||
|
||||
virtual bool canServeForConditionNode (triagens::aql::AstNode const*, triagens::aql::Variable const*) const;
|
||||
virtual bool canServeForConditionNode (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*,
|
||||
triagens::aql::AstNode*) const;
|
||||
|
||||
friend std::ostream& operator<< (std::ostream&, Index const*);
|
||||
friend std::ostream& operator<< (std::ostream&, Index const&);
|
||||
|
|
|
@ -288,19 +288,25 @@ static bool accessFitsIndex (triagens::aql::AstNode const* access, triagens::aql
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PrimaryIndex::canServeForConditionNode (triagens::aql::AstNode const* node, triagens::aql::Variable const* reference) const {
|
||||
bool PrimaryIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
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) ||
|
||||
accessFitsIndex(op->getMember(1), reference)) {
|
||||
// This index can at most cover one item
|
||||
reducedNode->removeMemberUnchecked(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (op->type == triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN) {
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (accessFitsIndex(op->getMember(0), reference)) {
|
||||
// This index can at most cover one item
|
||||
reducedNode->removeMemberUnchecked(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,7 +160,9 @@ namespace triagens {
|
|||
|
||||
void invokeOnAllElements (std::function<void(TRI_doc_mptr_t*)>);
|
||||
|
||||
bool canServeForConditionNode (triagens::aql::AstNode const*, triagens::aql::Variable const*) const;
|
||||
bool canServeForConditionNode (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*,
|
||||
triagens::aql::AstNode*) const override;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "SkiplistIndex.h"
|
||||
#include "Basics/logging.h"
|
||||
#include "Aql/AstNode.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
#include "VocBase/transaction.h"
|
||||
#include "VocBase/VocShaper.h"
|
||||
|
@ -879,6 +880,88 @@ int SkiplistIndex::ElementElementComparator::operator() (TRI_index_element_t con
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool SkiplistIndex::accessFitsIndex (triagens::aql::AstNode const* access,
|
||||
triagens::aql::Variable const* reference,
|
||||
std::unordered_set<std::string>& found) const {
|
||||
if (access->type == triagens::aql::NODE_TYPE_ATTRIBUTE_ACCESS) {
|
||||
TRI_ASSERT(access->numMembers() == 1);
|
||||
if (access->getMember(0)->getData() != reference) {
|
||||
// This access is not referencing this collection
|
||||
return false;
|
||||
}
|
||||
// We have to check if this attribute string is used
|
||||
std::string attr(access->getStringValue());
|
||||
for (auto& field : _fields) {
|
||||
std::string comp;
|
||||
TRI_AttributeNamesToString(field, comp);
|
||||
if (attr == comp) {
|
||||
// This index knows this attribute
|
||||
found.emplace(attr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool SkiplistIndex::canServeForConditionNode (triagens::aql::AstNode const* node,
|
||||
triagens::aql::Variable const* reference,
|
||||
triagens::aql::AstNode* reducedNode) const {
|
||||
std::unordered_set<std::string> foundEq;
|
||||
std::unordered_set<std::string> foundRange;
|
||||
for (size_t i = 0; i < node->numMembers(); ++i) {
|
||||
auto op = node->getMember(i);
|
||||
switch (op->type) {
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_EQ:
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (! accessFitsIndex(op->getMember(0), reference, foundEq)) {
|
||||
accessFitsIndex(op->getMember(1), reference, foundEq);
|
||||
}
|
||||
break;
|
||||
/* Deactivated right now. Needs changes outside of this code
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_IN:
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (accessFitsIndex(op->getMember(0), reference, found)) {
|
||||
if (found.size() == _fields.size()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_LT:
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_LE:
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_GT:
|
||||
case triagens::aql::NODE_TYPE_OPERATOR_BINARY_GE:
|
||||
TRI_ASSERT(op->numMembers() == 2);
|
||||
if (accessFitsIndex(op->getMember(0), reference, foundRange)) {
|
||||
accessFitsIndex(op->getMember(1), reference, foundRange);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool canBeUsed = false;
|
||||
for (auto& field : _fields) {
|
||||
std::string f;
|
||||
TRI_AttributeNamesToString(field, f);
|
||||
if (foundEq.find(f) != foundEq.end()) {
|
||||
// We can increase the value of this estimate
|
||||
// and we can use this index for sure
|
||||
canBeUsed = true;
|
||||
continue;
|
||||
}
|
||||
if (foundRange.find(f) != foundRange.end()) {
|
||||
// f is not used in equality check but as a bound
|
||||
// We can only use the index up to this value
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return canBeUsed;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -254,6 +254,10 @@ namespace triagens {
|
|||
|
||||
SkiplistIterator* lookup (TRI_index_operator_t*, bool);
|
||||
|
||||
bool canServeForConditionNode (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*,
|
||||
triagens::aql::AstNode* reducedNode) const override;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -267,6 +271,10 @@ namespace triagens {
|
|||
int _CmpKeyElm (TRI_skiplist_index_key_t const* leftKey,
|
||||
TRI_index_element_t const* rightElement);
|
||||
|
||||
bool accessFitsIndex (triagens::aql::AstNode const*,
|
||||
triagens::aql::Variable const*,
|
||||
std::unordered_set<std::string>&) const;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue