8000 Remove IndexHandle by graetzer · Pull Request #10424 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content

Remove IndexHandle #10424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 14, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Remove IndexHandle
  • Loading branch information
graetzer committed Nov 13, 2019
commit dcbe7a55558cc068b44077b8d35d3f1192a34c0e
5 changes: 2 additions & 3 deletions arangod/Aql/IndexExecutor.cpp
10000
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ IndexIterator::DocumentCallback getCallback(DocumentProducingFunctionContext& co
TRI_ASSERT(!output.isFull());
output.moveValueInto(registerId, input, guard);

auto indexId = index.getIndex()->id();
auto indexId = index->id();
TRI_ASSERT(indexId == outNonMaterializedIndRegs.first);
if (ADB_UNLIKELY(indexId != outNonMaterializedIndRegs.first)) {
return false;
Expand Down Expand Up @@ -232,9 +232,8 @@ IndexExecutorInfos::IndexExecutorInfos(
// count how many attributes in the index are expanded (array index)
// if more than a single attribute, we always need to deduplicate the
// result later on
for (auto const& it : getIndexes()) {
for (auto const& idx : getIndexes()) {
size_t expansions = 0;
auto idx = it.getIndex();
auto const& fields = idx->fields();
for (size_t i = 0; i < fields.size(); ++i) {
if (idx->isAttributeExpanded(i)) {
Expand Down
27 changes: 16 additions & 11 deletions arangod/Aql/IndexNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ void IndexNode::initIndexCoversProjections() {
}

// cannot apply the optimization if we use more than one different index
auto idx = _indexes[0].getIndex();
auto const& idx = _indexes[0];
for (size_t i = 1; i < _indexes.size(); ++i) {
if (_indexes[i].getIndex() != idx) {
if (_indexes[i] != idx) {
// different index used => optimization not possible
return;
}
Expand Down Expand Up @@ -270,8 +270,8 @@ void IndexNode::toVelocyPackHelper(VPackBuilder& builder, unsigned flags,
builder.add(VPackValue("indexes"));
{
VPackArrayBuilder guard(&builder);
for (auto& index : _indexes) {
index.toVelocyPack(builder, Index::makeFlags(Index::Serialize::Estimates));
for (auto const& index : _indexes) {
index->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Estimates));
}
}
builder.add(VPackValue("condition"));
Expand All @@ -290,10 +290,10 @@ void IndexNode::toVelocyPackHelper(VPackBuilder& builder, unsigned flags,
builder.add("indexIdOfVars", VPackValue(_outNonMaterializedIndVars.first));
// container _indexes contains a few items
auto indIt = std::find_if(_indexes.cbegin(), _indexes.cend(), [this](auto const& index) {
return index.getIndex()->id() == _outNonMaterializedIndVars.first;
return index->id() == _outNonMaterializedIndVars.first;
});
TRI_ASSERT(indIt != _indexes.cend());
auto const& fields = indIt->getIndex()->fields();
auto const& fields = (*indIt)->fields();
VPackArrayBuilder arrayScope(&builder, "IndexValuesVars");
for (auto const& indVar : _outNonMaterializedIndVars.second) {
VPackObjectBuilder objectScope(&builder);
Expand All @@ -319,14 +319,19 @@ arangodb::aql::AstNode* IndexNode::makeUnique(arangodb::aql::AstNode* node,
auto ast = _plan->getAst();
auto array = _plan->getAst()->createNodeArray();
array->addMember(node);
bool isSorted = false;
bool isSparse = false;

TRI_ASSERT(trx != nullptr);

// Here it does not matter which index we choose for the isSorted/isSparse
// check, we need them all sorted here.
auto unused = trx->getIndexFeatures(_indexes.at(0), isSorted, isSparse);
if (isSparse || isSorted) {

auto idx = _indexes.at(0);
if (!idx) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
}

if (idx->sparse() || idx->isSorted()) {
// the index is sorted. we need to use SORTED_UNIQUE to get the
// result back in index order
return ast->createNodeFunctionCall(TRI_CHAR_LENGTH_PAIR("SORTED_UNIQUE"), array);
Expand Down Expand Up @@ -586,7 +591,7 @@ CostEstimate IndexNode::estimateCost() const {

if (root != nullptr && root->numMembers() > i) {
arangodb::aql::AstNode const* condition = root->getMember(i);
costs = _indexes[i].getIndex()->supportsFilterCondition(
costs = _indexes[i]->supportsFilterCondition(
std::vector<std::shared_ptr<Index>>(), condition, _outVariable, itemsInCollection);
}

Expand Down
7 changes: 3 additions & 4 deletions arangod/Aql/IndexNodeOptimizerRules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,16 @@ namespace {
// check all node attributes to be in index
for (auto& nodeAttr : node.attrs) {
for (auto& index : indexNode->getIndexes()) {
auto const& ind = index.getIndex();
if (!ind->hasCoveringIterator()) {
if (!index->hasCoveringIterator()) {
continue;
}
auto indexId = ind->id();
auto indexId = index->id();
// use one index only
if (commonIndexId != 0 && commonIndexId != indexId) {
continue;
}
size_t indexFieldNum = 0;
for (auto const& field : ind->fields()) {
for (auto const& field : index->fields()) {
if (arangodb::basics::AttributeName::isIdentical(nodeAttr.attr, field, false)) {
if (commonIndexId == 0) {
commonIndexId = indexId;
Expand Down
16 changes: 8 additions & 8 deletions arangod/Aql/OptimizerRules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3086,10 +3086,10 @@ struct SortToIndexNode final : public WalkerWorker<ExecutionNode> {

auto index = indexes[0];
transaction::Methods* trx = _plan->getAst()->query()->trx();
bool isSorted = false;
bool isSparse = false;
std::vector<std::vector<arangodb::basics::AttributeName>> fields =
trx->getIndexFeatures(index, isSorted, isSparse);
bool isSorted = index->isSorted();
bool isSparse = index->sparse();
std::vector<std::vector<arangodb::basics::AttributeName>> fields = index->fields();

if (indexes.size() != 1) {
// can only use this index node if it uses exactly one index or multiple
// indexes on exactly the same attributes
Expand Down Expand Up @@ -3170,7 +3170,7 @@ struct SortToIndexNode final : public WalkerWorker<ExecutionNode> {
// now check if the index fields are the same as the sort condition
// fields e.g. FILTER c.value1 == 1 && c.value2 == 42 SORT c.value1,
// c.value2
auto i = index.getIndex();
auto const& i = index;
// some special handling for the MMFiles edge index here, which to the
// outside world is an index on attributes _from and _to at the same
// time, but only one can be queried at a time this special handling
Expand Down Expand Up @@ -3413,7 +3413,7 @@ void arangodb::aql::removeFiltersCoveredByIndexRule(Optimizer* opt,
auto newNode =
condition.removeIndexCondition(plan.get(), indexNode->outVariable(),
indexCondition->root(),
indexesUsed[0].getIndex().get());
indexesUsed[0].get());

if (newNode == nullptr) {
// no condition left...
Expand Down Expand Up @@ -3692,15 +3692,15 @@ void arangodb::aql::scatterInClusterRule(Optimizer* opt, std::unique_ptr<Executi
TRI_ASSERT(!allIndexes.empty());

// Using Index for sort only works if all indexes are equal.
auto first = allIndexes[0].getIndex();
auto const& first = allIndexes[0];
// also check if we actually need to bother about the sortedness of the
// result, or if we use the index for filtering only
if (first->isSorted() && idxNode->needsGatherNodeSort()) {
for (auto const& path : first->fieldNames()) {
elements.emplace_back(sortVariable, isSortAscending, path);
}
for (auto const& it : allIndexes) {
if (first != it.getIndex()) {
if (first != it) {
elements.clear();
break;
}
Expand Down < 9E7A /td>
2 changes: 1 addition & 1 deletion arangod/Aql/OptimizerRulesCluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Index* hasSingleIndexHandle(ExecutionNode const* node) {
IndexNode const* indexNode = ExecutionNode::castTo<IndexNode const*>(node);
auto indexHandleVec = indexNode->getIndexes();
if (indexHandleVec.size() == 1) {
return indexHandleVec.front().getIndex().get();
return indexHandleVec.front().get();
}
return nullptr;
}
Expand Down
6 changes: 3 additions & 3 deletions arangod/Graph/BaseOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void BaseOptions::LookupInfo::buildEngineInfo(VPackBuilder& result) const {
// We only run toVelocyPack on Coordinator.
TRI_ASSERT(idxHandles.size() == 1);

idxHandles[0].toVelocyPack(result, Index::makeFlags(Index::Serialize::Basics));
idxHandles[0]->toVelocyPack(result, Index::makeFlags(Index::Serialize::Basics));

if (expression != nullptr) {
result.add(VPackValue("expression"));
Expand All @@ -143,7 +143,7 @@ double BaseOptions::LookupInfo::estimateCost(size_t& nrItems) const {
// If we do not have an index yet we cannot do anything.
// Should NOT be the case
TRI_ASSERT(!idxHandles.empty());
std::shared_ptr<Index> idx = idxHandles[0].getIndex();
std::shared_ptr<Index> const& idx = idxHandles[0];
if (idx->hasSelectivityEstimate()) {
double s = idx->selectivityEstimate();
if (s > 0.0) {
Expand Down Expand Up @@ -335,7 +335,7 @@ void BaseOptions::injectVelocyPackIndexes(VPackBuilder& builder) const {
for (auto const& it : _baseLookupInfos) {
for (auto const& it2 : it.idxHandles) {
builder.openObject();
it2.getIndex()->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics));
it2->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics));
builder.close();
}
}
Expand Down
2 changes: 1 addition & 1 deletion arangod/Graph/ShortestPathOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void ShortestPathOptions::toVelocyPackIndexes(VPackBuilder& builder) const {
builder.add("base", VPackValue(VPackValueType::Array));
for (auto const& it : _baseLookupInfos) {
for (auto const& it2 : it.idxHandles) {
it2.getIndex()->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
it2->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
}
}
builder.close();
Expand Down
4 changes: 2 additions & 2 deletions arangod/Graph/TraverserOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ void TraverserOptions::toVelocyPackIndexes(VPackBuilder& builder) const {
builder.add("base", VPackValue(VPackValueType::Array));
for (auto const& it : _baseLookupInfos) {
for (auto const& it2 : it.idxHandles) {
it2.getIndex()->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
it2->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
}
}
builder.close();
Expand All @@ -323,7 +323,7 @@ void TraverserOptions::toVelocyPackIndexes(VPackBuilder& builder) const {
builder.add(VPackValue(VPackValueType::Array));
for (auto const& it2 : it.second) {
for (auto const& it3 : it2.idxHandles) {
it3.getIndex()->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
it3->toVelocyPack(builder, Index::makeFlags(Index::Serialize::Basics, Index::Serialize::Estimates));
}
}
builder.close();
Expand Down
6 changes: 2 additions & 4 deletions arangod/RocksDBEngine/RocksDBOptimizerRules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ void RocksDBOptimizerRules::reduceExtractionToProjectionRule(
opts.forceProjection = true;
auto inode = new IndexNode(plan.get(), plan->nextId(),
en->collection(), en->outVariable(),
std::vector<transaction::Methods::IndexHandle>{
transaction::Methods::IndexHandle{picked}},
std::vector<transaction::Methods::IndexHandle>{picked},
std::move(condition), opts);
en->CollectionAccessingNode::cloneInto(*inode);
en->DocumentProducingNode::cloneInto(plan.get(), *inode);
Expand Down Expand Up @@ -340,8 +339,7 @@ void RocksDBOptimizerRules::reduceExtractionToProjectionRule(
condition->normalize(plan.get());
auto inode = new IndexNode(plan.get(), plan->nextId(), en->collection(),
en->outVariable(),
std::vector<transaction::Methods::IndexHandle>{
transaction::Methods::IndexHandle{picked}},
std::vector<transaction::Methods::IndexHandle>{picked},
std::move(condition), opts);
plan->registerNode(inode);
plan->replaceNode(n, inode);
Expand Down
75 changes: 17 additions & 58 deletions arangod/Transaction/Methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,23 +262,6 @@ bool transaction::Methods::removeStatusChangeCallback(StatusChangeCallback const
getDataSourceRegistrationCallbacks().clear();
}

/// @brief Get the field names of the used index
std::vector<std::vector<std::string>> transaction::Methods::IndexHandle::fieldNames() const {
return _index->fieldNames();
}

/// @brief IndexHandle getter method
std::shared_ptr<arangodb::Index> transaction::Methods::IndexHandle::getIndex() const {
return _index;
}

/// @brief IndexHandle toVelocyPack method passthrough
void transaction::Methods::IndexHandle::toVelocyPack(
arangodb::velocypack::Builder& builder,
std::underlying_type<Index::Serialize>::type flags) const {
_index->toVelocyPack(builder, flags);
}

TRI_vocbase_t& transaction::Methods::vocbase() const {
return _state->vocbase();
}
Expand Down Expand Up @@ -539,7 +522,7 @@ bool transaction::Methods::sortOrs(arangodb::aql::Ast* ast, arangodb::aql::AstNo
try {
std::string conditionString =
conditionData->first->toString() + " - " +
std::to_string(conditionData->second.getIndex()->id());
std::to_string(conditionData->second->id());
isUnique = seenIndexConditions.emplace(std::move(conditionString)).second;
// we already saw the same combination of index & condition
// don't add it again
Expand Down Expand Up @@ -2740,22 +2723,6 @@ bool transaction::Methods::getBestIndexHandleForFilterCondition(
return false;
}

/// @brief Get the index features:
/// Returns the covered attributes, and sets the first bool value
/// to isSorted and the second bool value to isSparse
std::vector<std::vector<arangodb::basics::AttributeName>> transaction::Methods::getIndexFeatures(
IndexHandle const& indexHandle, bool& isSorted, bool& isSparse) {
auto idx = indexHandle.getIndex();
if (nullptr == idx) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
}

isSorted = idx->isSorted();
isSparse = idx->sparse();
return idx->fields();
}

/// @brief Gets the best fitting index for an AQL sort condition
/// note: the caller must have read-locked the underlying collection when
/// calling this method
Expand Down Expand Up @@ -2833,14 +2800,13 @@ bool transaction::Methods::getIndexForSortCondition(
/// note: the caller must have read-locked the underlying collection when
/// calling this method
std::unique_ptr<IndexIterator> transaction::Methods::indexScanForCondition(
IndexHandle const& indexId, arangodb::aql::AstNode const* condition,
IndexHandle const& idx, arangodb::aql::AstNode const* condition,
arangodb::aql::Variable const* var, IndexIteratorOptions const& opts) {
if (_state->isCoordinator()) {
// The index scan is only available on DBServers and Single Server.
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_ONLY_ON_DBSERVER);
}

auto idx = indexId.getIndex();
if (nullptr == idx) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
Expand Down Expand Up @@ -3089,22 +3055,22 @@ std::vector<std::shared_ptr<Index>> transaction::Methods::indexesForCollectionCo
/// @brief get the index by it's identifier. Will either throw or
/// return a valid index. nullptr is impossible.
transaction::Methods::IndexHandle transaction::Methods::getIndexByIdentifier(
std::string const& collectionName, std::string const& indexHandle) {
if (_state->isCoordinator()) {
if (indexHandle.empty()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
}

if (!arangodb::Index::validateId(indexHandle.c_str())) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_INDEX_HANDLE_BAD);
}

std::shared_ptr<Index> idx = indexForCollectionCoordinator(collectionName, indexHandle);
std::string const& collectionName, std::string const& idxId) {

if (idxId.empty()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
}

if (!arangodb::Index::validateId(idxId.c_str())) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_INDEX_HANDLE_BAD);
}

if (_state->isCoordinator()) {
std::shared_ptr<Index> idx = indexForCollectionCoordinator(collectionName, idxId);
if (idx == nullptr) {
TH 9740 ROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_INDEX_NOT_FOUND,
"Could not find index '" + indexHandle +
"Could not find index '" + idxId +
"' in collection '" + collectionName +
"'.");
}
Expand All @@ -3116,20 +3082,13 @@ transaction::Methods::IndexHandle transaction::Methods::getIndexByIdentifier(
TRI_voc_cid_t cid = addCollectionAtRuntime(collectionName, AccessMode::Type::READ);
std::shared_ptr<LogicalCollection> const& document = trxCollection(cid)->collection();

if (indexHandle.empty()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"The index id cannot be empty.");
}

if (!arangodb::Index::validateId(indexHandle.c_str())) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_INDEX_HANDLE_BAD);
}
TRI_idx_iid_t iid = arangodb::basics::StringUtils::uint64(indexHandle);
TRI_idx_iid_t iid = arangodb::basics::StringUtils::uint64(idxId);
std::shared_ptr<arangodb::Index> idx = document->lookupIndex(iid);

if (idx == nullptr) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_INDEX_NOT_FOUND,
"Could not find index '" + indexHandle +
"Could not find index '" + idxId +
"' in collection '" + collectionName +
"'.");
}
Expand Down
Loading
0