From 87567c3c2a55c156175d77113bdb2e9de3225600 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 30 Jul 2017 14:24:25 +0200 Subject: [PATCH] fixed issue #2876 (#2896) --- CHANGELOG | 2 ++ arangod/MMFiles/MMFilesSkiplistIndex.cpp | 26 +++++++++++++++------ arangod/RocksDBEngine/RocksDBVPackIndex.cpp | 26 +++++++++++++++++++-- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 53ff78c999..6aaadb462c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ devel ----- +* fixed issue #2876: wrong skiplist index usage in edge collection + * fixed issue #2868: cname missing from logger-follow results in rocksdb * fixed issue #2889: Traversal query using incorrect collection id diff --git a/arangod/MMFiles/MMFilesSkiplistIndex.cpp b/arangod/MMFiles/MMFilesSkiplistIndex.cpp index 84dfcc2abd..a221b033d3 100644 --- a/arangod/MMFiles/MMFilesSkiplistIndex.cpp +++ b/arangod/MMFiles/MMFilesSkiplistIndex.cpp @@ -1281,6 +1281,7 @@ bool MMFilesSkiplistIndex::supportsFilterCondition( arangodb::aql::AstNode const* node, arangodb::aql::Variable const* reference, size_t itemsInIndex, size_t& estimatedItems, double& estimatedCost) const { + std::unordered_map> found; std::unordered_set nonNullAttributes; size_t values = 0; @@ -1349,12 +1350,19 @@ bool MMFilesSkiplistIndex::supportsFilterCondition( if (attributesCoveredByEquality == _fields.size() && (unique() || implicitlyUnique())) { // index is unique and condition covers all attributes by equality - if (estimatedItems >= values) { - // reduce costs due to uniqueness - estimatedItems = values; - estimatedCost = static_cast(estimatedItems); + if (itemsInIndex == 0) { + estimatedItems = 0; + estimatedCost = 0.0; + return true; } - // cost is already low... now slightly prioritize the unique index + + if (estimatedItems >= values) { + TRI_ASSERT(itemsInIndex > 0); + + estimatedItems = values; + estimatedCost = (std::max)(static_cast(1), std::log2(static_cast(itemsInIndex)) * values); + } + // cost is already low... now slightly prioritize unique indexes estimatedCost *= 0.995 - 0.05 * (_fields.size() - 1); return true; } @@ -1367,11 +1375,15 @@ bool MMFilesSkiplistIndex::supportsFilterCondition( // sparse indexes are contained in Index::canUseConditionPart) estimatedItems = static_cast((std::max)( static_cast(estimatedCost * values), static_cast(1))); - estimatedCost *= static_cast(values); + if (itemsInIndex == 0) { + estimatedCost = 0.0; + } else { + estimatedCost = (std::max)(static_cast(1), std::log2(static_cast(itemsInIndex)) * values); + } return true; } - // no condition + // index does not help for this condition estimatedItems = itemsInIndex; estimatedCost = static_cast(estimatedItems); return false; diff --git a/arangod/RocksDBEngine/RocksDBVPackIndex.cpp b/arangod/RocksDBEngine/RocksDBVPackIndex.cpp index 078b4fecd8..9827eca572 100644 --- a/arangod/RocksDBEngine/RocksDBVPackIndex.cpp +++ b/arangod/RocksDBEngine/RocksDBVPackIndex.cpp @@ -977,8 +977,22 @@ bool RocksDBVPackIndex::supportsFilterCondition( if (attributesCoveredByEquality == _fields.size() && unique()) { // index is unique and condition covers all attributes by equality + if (itemsInIndex == 0) { + estimatedItems = 0; + estimatedCost = 0.0; + return true; + } estimatedItems = values; estimatedCost = 0.995 * values; + if (values > 0) { + if (useCache()) { + estimatedCost = static_cast(estimatedItems * values); + } else { + estimatedCost = (std::max)(static_cast(1), std::log2(static_cast(itemsInIndex)) * values); + } + } + // cost is already low... now slightly prioritize unique indexes + estimatedCost *= 0.995 - 0.05 * (_fields.size() - 1); return true; } @@ -1000,11 +1014,19 @@ bool RocksDBVPackIndex::supportsFilterCondition( estimatedItems = static_cast(1.0 / estimate); } } - estimatedCost = static_cast(estimatedItems); + if (itemsInIndex == 0) { + estimatedCost = 0.0; + } else { + if (useCache()) { + estimatedCost = static_cast(estimatedItems * values); + } else { + estimatedCost = (std::max)(static_cast(1), std::log2(static_cast(itemsInIndex)) * values); + } + } return true; } - // no condition + // index does not help for this condition estimatedItems = itemsInIndex; estimatedCost = static_cast(estimatedItems); return false;