diff options
author | Matt Broadstone <mbroadst@mongodb.com> | 2023-05-16 10:43:36 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-05-16 12:03:28 +0000 |
commit | d12e38e18857307e369c23dde1873b54666d6ae3 (patch) | |
tree | 25ab82dc1cbc6d1384992c6e40ebf11139aa013d | |
parent | 1c15e29c6014419ae150f80060284c02a10cc486 (diff) | |
download | mongo-d12e38e18857307e369c23dde1873b54666d6ae3.tar.gz |
SERVER-77012 Skip parsing for tenantIds if multitenancy disabled
-rw-r--r-- | src/mongo/db/namespace_string.h | 104 | ||||
-rw-r--r-- | src/mongo/util/namespace_string_util.cpp | 16 |
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); |