summaryrefslogtreecommitdiff
path: root/src/mongo/s/shard_key_pattern.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-03-19 18:49:08 -0400
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2017-03-22 16:29:12 -0400
commitd8b0d028e3895b32b86f3e6878d4bc34dd8c7fc8 (patch)
tree6df8fcd0faecf5ae8e9c88bd779f834d3bfe71f7 /src/mongo/s/shard_key_pattern.cpp
parent7361e94af31142ec018ccad70b0398e3a472eba5 (diff)
downloadmongo-d8b0d028e3895b32b86f3e6878d4bc34dd8c7fc8.tar.gz
SERVER-27681 Remove duplicated ShardKeyPattern functionality from CollectionMetadata
Diffstat (limited to 'src/mongo/s/shard_key_pattern.cpp')
-rw-r--r--src/mongo/s/shard_key_pattern.cpp121
1 files changed, 67 insertions, 54 deletions
diff --git a/src/mongo/s/shard_key_pattern.cpp b/src/mongo/s/shard_key_pattern.cpp
index bce1698ecb3..3518a7e9cc2 100644
--- a/src/mongo/s/shard_key_pattern.cpp
+++ b/src/mongo/s/shard_key_pattern.cpp
@@ -44,33 +44,19 @@
namespace mongo {
-using std::make_pair;
-using std::pair;
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::vector;
using pathsupport::EqualityMatches;
-using mongoutils::str::stream;
const int ShardKeyPattern::kMaxShardKeySizeBytes = 512;
const unsigned int ShardKeyPattern::kMaxFlattenedInCombinations = 4000000;
-Status ShardKeyPattern::checkShardKeySize(const BSONObj& shardKey) {
- if (shardKey.objsize() <= kMaxShardKeySizeBytes)
- return Status::OK();
-
- return Status(ErrorCodes::ShardKeyTooBig,
- stream() << "shard keys must be less than " << kMaxShardKeySizeBytes
- << " bytes, but key "
- << shardKey
- << " is "
- << shardKey.objsize()
- << " bytes");
-}
+namespace {
-static bool isHashedPatternEl(const BSONElement& el) {
+bool isHashedPatternEl(const BSONElement& el) {
return el.type() == String && el.String() == IndexNames::HASHED;
}
@@ -79,26 +65,23 @@ static bool isHashedPatternEl(const BSONElement& el) {
* i) a hashed single field, e.g. { a : "hashed" }, or
* ii) a compound list of ascending, potentially-nested field paths, e.g. { a : 1 , b.c : 1 }
*/
-static std::vector<std::unique_ptr<FieldRef>> parseShardKeyPattern(const BSONObj& keyPattern) {
+std::vector<std::unique_ptr<FieldRef>> parseShardKeyPattern(const BSONObj& keyPattern) {
std::vector<std::unique_ptr<FieldRef>> parsedPaths;
- BSONObjIterator patternIt(keyPattern);
- while (patternIt.more()) {
- BSONElement patternEl = patternIt.next();
- parsedPaths.push_back(stdx::make_unique<FieldRef>(patternEl.fieldNameStringData()));
- const FieldRef& patternPath = *parsedPaths.back();
+ for (const auto& patternEl : keyPattern) {
+ auto newFieldRef(stdx::make_unique<FieldRef>(patternEl.fieldNameStringData()));
// Empty path
- if (patternPath.numParts() == 0)
+ if (newFieldRef->numParts() == 0)
return {};
// Extra "." in path?
- if (patternPath.dottedField() != patternEl.fieldNameStringData())
+ if (newFieldRef->dottedField() != patternEl.fieldNameStringData())
return {};
// Empty parts of the path, ".."?
- for (size_t i = 0; i < patternPath.numParts(); ++i) {
- if (patternPath.getPart(i).size() == 0)
+ for (size_t i = 0; i < newFieldRef->numParts(); ++i) {
+ if (newFieldRef->getPart(i).empty())
return {};
}
@@ -109,18 +92,48 @@ static std::vector<std::unique_ptr<FieldRef>> parseShardKeyPattern(const BSONObj
} else if (patternEl.numberInt() != 1) {
return {};
}
+
+ parsedPaths.emplace_back(std::move(newFieldRef));
}
return parsedPaths;
}
+bool isShardKeyElement(const BSONElement& element, bool allowRegex) {
+ if (element.eoo() || element.type() == Array)
+ return false;
+
+ // TODO: Disallow regex all the time
+ if (!allowRegex && element.type() == RegEx)
+ return false;
+
+ if (element.type() == Object && !element.embeddedObject().okForStorage())
+ return false;
+
+ return true;
+}
+
+} // namespace
+
+Status ShardKeyPattern::checkShardKeySize(const BSONObj& shardKey) {
+ if (shardKey.objsize() <= kMaxShardKeySizeBytes)
+ return Status::OK();
+
+ return {ErrorCodes::ShardKeyTooBig,
+ str::stream() << "shard keys must be less than " << kMaxShardKeySizeBytes
+ << " bytes, but key "
+ << shardKey
+ << " is "
+ << shardKey.objsize()
+ << " bytes"};
+}
+
ShardKeyPattern::ShardKeyPattern(const BSONObj& keyPattern)
: _keyPatternPaths(parseShardKeyPattern(keyPattern)),
_keyPattern(_keyPatternPaths.empty() ? BSONObj() : keyPattern) {}
ShardKeyPattern::ShardKeyPattern(const KeyPattern& keyPattern)
- : _keyPatternPaths(parseShardKeyPattern(keyPattern.toBSON())),
- _keyPattern(_keyPatternPaths.empty() ? KeyPattern(BSONObj()) : keyPattern) {}
+ : ShardKeyPattern(keyPattern.toBSON()) {}
bool ShardKeyPattern::isValid() const {
return !_keyPattern.toBSON().isEmpty();
@@ -134,6 +147,10 @@ const KeyPattern& ShardKeyPattern::getKeyPattern() const {
return _keyPattern;
}
+const std::vector<std::unique_ptr<FieldRef>>& ShardKeyPattern::getKeyPatternFields() const {
+ return _keyPatternPaths;
+}
+
const BSONObj& ShardKeyPattern::toBSON() const {
return _keyPattern.toBSON();
}
@@ -142,30 +159,22 @@ string ShardKeyPattern::toString() const {
return toBSON().toString();
}
-static bool isShardKeyElement(const BSONElement& element, bool allowRegex) {
- // TODO: Disallow regex all the time
- if (element.eoo() || element.type() == Array || (!allowRegex && element.type() == RegEx) ||
- (element.type() == Object && !element.embeddedObject().okForStorage()))
- return false;
- return true;
-}
-
bool ShardKeyPattern::isShardKey(const BSONObj& shardKey) const {
// Shard keys are always of the form: { 'nested.path' : value, 'nested.path2' : value }
if (!isValid())
return false;
- BSONObjIterator patternIt(_keyPattern.toBSON());
- while (patternIt.more()) {
- BSONElement patternEl = patternIt.next();
+ const auto& keyPatternBSON = _keyPattern.toBSON();
+ for (const auto& patternEl : keyPatternBSON) {
BSONElement keyEl = shardKey[patternEl.fieldNameStringData()];
+
if (!isShardKeyElement(keyEl, true))
return false;
}
- return true;
+ return shardKey.nFields() == keyPatternBSON.nFields();
}
BSONObj ShardKeyPattern::normalizeShardKey(const BSONObj& shardKey) const {
@@ -350,18 +359,21 @@ BoundList ShardKeyPattern::flattenBounds(const IndexBounds& indexBounds) const {
return BoundList();
}
}
- // To construct our bounds we will generate intervals based on bounds for
- // the first field, then compound intervals based on constraints for the first
- // 2 fields, then compound intervals for the first 3 fields, etc.
- // As we loop through the fields, we start generating new intervals that will later
- // get extended in another iteration of the loop. We define these partially constructed
- // intervals using pairs of BSONObjBuilders (shared_ptrs, since after one iteration of the
- // loop they still must exist outside their scope).
- typedef vector<pair<shared_ptr<BSONObjBuilder>, shared_ptr<BSONObjBuilder>>> BoundBuilders;
+
+ // To construct our bounds we will generate intervals based on bounds for the first field, then
+ // compound intervals based on constraints for the first 2 fields, then compound intervals for
+ // the first 3 fields, etc.
+ //
+ // As we loop through the fields, we start generating new intervals that will later get extended
+ // in another iteration of the loop. We define these partially constructed intervals using pairs
+ // of BSONObjBuilders (shared_ptrs, since after one iteration of the loop they still must exist
+ // outside their scope).
+ typedef vector<std::pair<std::shared_ptr<BSONObjBuilder>, std::shared_ptr<BSONObjBuilder>>>
+ BoundBuilders;
BoundBuilders builders;
- builders.push_back(make_pair(shared_ptr<BSONObjBuilder>(new BSONObjBuilder()),
- shared_ptr<BSONObjBuilder>(new BSONObjBuilder())));
+ builders.emplace_back(shared_ptr<BSONObjBuilder>(new BSONObjBuilder()),
+ shared_ptr<BSONObjBuilder>(new BSONObjBuilder()));
BSONObjIterator keyIter(_keyPattern.toBSON());
// until equalityOnly is false, we are just dealing with equality (no range or $in queries).
bool equalityOnly = true;
@@ -403,9 +415,8 @@ BoundList ShardKeyPattern::flattenBounds(const IndexBounds& indexBounds) const {
uassert(17439,
"combinatorial limit of $in partitioning of results exceeded",
newBuilders.size() < kMaxFlattenedInCombinations);
- newBuilders.push_back( //
- make_pair(shared_ptr<BSONObjBuilder>(new BSONObjBuilder()),
- shared_ptr<BSONObjBuilder>(new BSONObjBuilder())));
+ newBuilders.emplace_back(shared_ptr<BSONObjBuilder>(new BSONObjBuilder()),
+ shared_ptr<BSONObjBuilder>(new BSONObjBuilder()));
newBuilders.back().first->appendElements(first);
newBuilders.back().second->appendElements(second);
newBuilders.back().first->appendAs(interval->start, fieldName);
@@ -424,9 +435,11 @@ BoundList ShardKeyPattern::flattenBounds(const IndexBounds& indexBounds) const {
}
}
}
+
BoundList ret;
for (BoundBuilders::const_iterator i = builders.begin(); i != builders.end(); ++i)
- ret.push_back(make_pair(i->first->obj(), i->second->obj()));
+ ret.emplace_back(i->first->obj(), i->second->obj());
+
return ret;
}