summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Broadstone <mbroadst@mongodb.com>2023-05-16 10:43:36 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-05-16 12:03:28 +0000
commitd12e38e18857307e369c23dde1873b54666d6ae3 (patch)
tree25ab82dc1cbc6d1384992c6e40ebf11139aa013d
parent1c15e29c6014419ae150f80060284c02a10cc486 (diff)
downloadmongo-d12e38e18857307e369c23dde1873b54666d6ae3.tar.gz
SERVER-77012 Skip parsing for tenantIds if multitenancy disabled
-rw-r--r--src/mongo/db/namespace_string.h104
-rw-r--r--src/mongo/util/namespace_string_util.cpp16
2 files changed, 84 insertions, 36 deletions
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 9a1d433a564..c42362ac632 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -218,7 +218,7 @@ public:
NamespaceString(StringData db,
StringData collectionName,
boost::optional<TenantId> tenantId = boost::none)
- : NamespaceString(DatabaseName(std::move(tenantId), db), collectionName) {}
+ : NamespaceString(std::move(tenantId), db, collectionName) {}
/**
* Constructs a NamespaceString from the string 'ns'. Should only be used when reading a
@@ -833,51 +833,29 @@ private:
* Constructs a NamespaceString from the fully qualified namespace named in "ns" and the
* tenantId. "ns" is NOT expected to contain the tenantId.
*/
- explicit NamespaceString(boost::optional<TenantId> tenantId, StringData ns) {
- uassert(ErrorCodes::InvalidNamespace,
- "namespaces cannot have embedded null characters",
- ns.find('\0') == std::string::npos);
-
- auto dotIndex = ns.find('.');
- uint8_t dbNameSize = dotIndex != std::string::npos ? dotIndex : ns.size();
- uassert(ErrorCodes::InvalidNamespace,
- fmt::format("db name must be at most {} characters, found: {}",
- DatabaseName::kMaxDatabaseNameLength,
- dbNameSize),
- dbNameSize <= DatabaseName::kMaxDatabaseNameLength);
-
- uint8_t details = dbNameSize & kDatabaseNameOffsetEndMask;
- size_t dbStartIndex = kDataOffset;
- if (tenantId) {
- dbStartIndex += OID::kOIDSize;
- details |= kTenantIdMask;
- }
-
- _data.resize(dbStartIndex + ns.size());
- *reinterpret_cast<uint8_t*>(_data.data()) = details;
- if (tenantId) {
- std::memcpy(_data.data() + kDataOffset, tenantId->_oid.view().view(), OID::kOIDSize);
- }
- if (!ns.empty()) {
- std::memcpy(_data.data() + dbStartIndex, ns.rawData(), ns.size());
- }
- }
+ explicit NamespaceString(boost::optional<TenantId> tenantId, StringData ns)
+ : _data(makeData(tenantId, ns)) {}
/**
* Constructs a NamespaceString for the given database and collection names.
* "dbName" must not contain a ".", and "collectionName" must not start with one.
*/
NamespaceString(DatabaseName dbName, StringData collectionName) {
- const auto db = dbName.db();
uassert(ErrorCodes::InvalidNamespace,
"Collection names cannot start with '.': " + collectionName,
collectionName.empty() || collectionName[0] != '.');
uassert(ErrorCodes::InvalidNamespace,
"namespaces cannot have embedded null characters",
- db.find('\0') == std::string::npos &&
- collectionName.find('\0') == std::string::npos);
-
- _data = str::stream() << dbName._data << "." << collectionName;
+ collectionName.find('\0') == std::string::npos);
+
+ _data.resize(dbName._data.size() + 1 + collectionName.size());
+ std::memcpy(_data.data(), dbName._data.data(), dbName._data.size());
+ *reinterpret_cast<uint8_t*>(_data.data() + dbName._data.size()) = '.';
+ if (!collectionName.empty()) {
+ std::memcpy(_data.data() + dbName._data.size() + 1,
+ collectionName.rawData(),
+ collectionName.size());
+ }
}
/**
@@ -886,7 +864,7 @@ private:
* NOT expected to contain a tenantId.
*/
NamespaceString(boost::optional<TenantId> tenantId, StringData db, StringData collectionName)
- : NamespaceString(DatabaseName(std::move(tenantId), db), collectionName) {}
+ : _data(makeData(tenantId, db, collectionName)) {}
std::string toStringWithTenantId() const {
if (_hasTenantId()) {
@@ -908,6 +886,60 @@ private:
return static_cast<uint8_t>(_data.front()) & kDatabaseNameOffsetEndMask;
}
+ std::string makeData(boost::optional<TenantId> tenantId,
+ StringData db,
+ StringData collectionName) {
+ uassert(ErrorCodes::InvalidNamespace,
+ "namespaces cannot have embedded null characters",
+ db.find('\0') == std::string::npos &&
+ collectionName.find('\0') == std::string::npos);
+ uassert(ErrorCodes::InvalidNamespace,
+ fmt::format("Collection names cannot start with '.': {}", collectionName),
+ collectionName.empty() || collectionName[0] != '.');
+ uassert(ErrorCodes::InvalidNamespace,
+ fmt::format("db name must be at most {} characters, found: {}",
+ DatabaseName::kMaxDatabaseNameLength,
+ db.size()),
+ db.size() <= DatabaseName::kMaxDatabaseNameLength);
+
+ uint8_t details = db.size() & kDatabaseNameOffsetEndMask;
+ size_t dbStartIndex = kDataOffset;
+ if (tenantId) {
+ dbStartIndex += OID::kOIDSize;
+ details |= kTenantIdMask;
+ }
+
+ std::string data;
+ data.resize(collectionName.empty() ? dbStartIndex + db.size()
+ : dbStartIndex + db.size() + 1 + collectionName.size());
+ *reinterpret_cast<uint8_t*>(data.data()) = details;
+ if (tenantId) {
+ std::memcpy(data.data() + kDataOffset, tenantId->_oid.view().view(), OID::kOIDSize);
+ }
+
+ if (!db.empty()) {
+ std::memcpy(data.data() + dbStartIndex, db.rawData(), db.size());
+ }
+
+ if (!collectionName.empty()) {
+ *reinterpret_cast<uint8_t*>(data.data() + dbStartIndex + db.size()) = '.';
+ std::memcpy(data.data() + dbStartIndex + db.size() + 1,
+ collectionName.rawData(),
+ collectionName.size());
+ }
+
+ return data;
+ }
+
+ std::string makeData(boost::optional<TenantId> tenantId, StringData ns) {
+ auto dotIndex = ns.find('.');
+ if (dotIndex == std::string::npos) {
+ return makeData(tenantId, ns, {});
+ }
+
+ return makeData(tenantId, ns.substr(0, dotIndex), ns.substr(dotIndex + 1, ns.size()));
+ }
+
// In order to reduce the size of a NamespaceString, we pack all possible namespace data
// into a single std::string with the following in-memory layout:
//
diff --git a/src/mongo/util/namespace_string_util.cpp b/src/mongo/util/namespace_string_util.cpp
index 4350752c444..9d949d405da 100644
--- a/src/mongo/util/namespace_string_util.cpp
+++ b/src/mongo/util/namespace_string_util.cpp
@@ -194,6 +194,10 @@ NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(
NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(
const boost::optional<TenantId>& tenantId, StringData db, StringData coll) {
+ if (!gMultitenancySupport) {
+ return NamespaceString{tenantId, db, coll};
+ }
+
if (coll.empty())
return deserialize(tenantId, db);
@@ -206,6 +210,10 @@ NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(
NamespaceString NamespaceStringUtil::parseNamespaceFromRequest(const DatabaseName& dbName,
StringData coll) {
+ if (!gMultitenancySupport) {
+ return NamespaceString{dbName, coll};
+ }
+
if (coll.empty()) {
return NamespaceString(dbName);
}
@@ -224,6 +232,10 @@ NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(
NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(
const boost::optional<TenantId>& tenantId, StringData db, StringData coll) {
+ if (!gMultitenancySupport) {
+ return NamespaceString{tenantId, db, coll};
+ }
+
if (coll.empty())
return deserialize(tenantId, db);
@@ -236,6 +248,10 @@ NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(
NamespaceString NamespaceStringUtil::parseNamespaceFromDoc(const DatabaseName& dbName,
StringData coll) {
+ if (!gMultitenancySupport) {
+ return NamespaceString{dbName, coll};
+ }
+
if (coll.empty())
return NamespaceString(dbName);