summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreyas Kalyan <shreyas.kalyan@mongodb.com>2023-04-06 12:39:14 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-10 11:10:42 +0000
commitee6071a0f36b7d2ffb70afe83b9b0cb9364e2ec7 (patch)
treefc294ea6487d0e1a5785db1f3248e65c0bf7990c
parentc6e5701933a98b4fe91c2409c212fcce2d3d34f0 (diff)
downloadmongo-ee6071a0f36b7d2ffb70afe83b9b0cb9364e2ec7.tar.gz
SERVER-75171 Use the GetQueryableEncryptionCountInfo command in compaction
-rw-r--r--jstests/auth/lib/commands_lib.js2
-rw-r--r--jstests/sharding/database_versioning_all_commands.js2
-rw-r--r--src/mongo/crypto/fle_crypto.cpp61
-rw-r--r--src/mongo/crypto/fle_crypto.h4
-rw-r--r--src/mongo/crypto/fle_crypto_test.cpp4
-rw-r--r--src/mongo/crypto/fle_crypto_types.h16
-rw-r--r--src/mongo/db/commands/fle2_compact.cpp81
-rw-r--r--src/mongo/db/commands/fle2_get_count_info_command.cpp53
-rw-r--r--src/mongo/db/commands/fle2_get_count_info_command.idl28
-rw-r--r--src/mongo/db/fle_crud.cpp54
-rw-r--r--src/mongo/db/fle_crud.h26
-rw-r--r--src/mongo/db/fle_crud_mongod.cpp28
-rw-r--r--src/mongo/db/fle_crud_test.cpp4
13 files changed, 244 insertions, 119 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index 2ce51bfd6a0..de2782a5ac2 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -4744,7 +4744,7 @@ export const authCommandsLib = {
tokens: [
{tokens: [{"s": BinData(0, "lUBO7Mov5Sb+c/D4cJ9whhhw/+PZFLCk/AQU2+BpumQ=")}]},
],
- "forInsert": true,
+ "queryType": "insert",
},
skipTest: (conn) => {
return !TestData.setParameters.featureFlagFLE2ProtocolVersion2;
diff --git a/jstests/sharding/database_versioning_all_commands.js b/jstests/sharding/database_versioning_all_commands.js
index 8e22f3281a1..7e031d1e990 100644
--- a/jstests/sharding/database_versioning_all_commands.js
+++ b/jstests/sharding/database_versioning_all_commands.js
@@ -521,7 +521,7 @@ let testCases = {
[{"s": BinData(0, "lUBO7Mov5Sb+c/D4cJ9whhhw/+PZFLCk/AQU2+BpumQ=")}]
},
],
- "forInsert": true
+ "queryType": "insert"
};
}
}
diff --git a/src/mongo/crypto/fle_crypto.cpp b/src/mongo/crypto/fle_crypto.cpp
index c98541c5877..a30e9951b73 100644
--- a/src/mongo/crypto/fle_crypto.cpp
+++ b/src/mongo/crypto/fle_crypto.cpp
@@ -1806,6 +1806,61 @@ BSONObj runStateMachineForDecryption(mongocrypt_ctx_t* ctx, FLEKeyVault* keyVaul
return result;
}
+FLEEdgeCountInfo getEdgeCountInfoForCompact(const FLEStateCollectionReader& reader,
+ ConstDataRange tag,
+ const boost::optional<PrfBlock>& edc) {
+
+ auto escToken = EDCServerPayloadInfo::getESCToken(tag);
+
+ auto tagToken = FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedTagToken(escToken);
+ auto valueToken = FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedValueToken(escToken);
+
+ auto positions = ESCCollection::emuBinaryV2(reader, tagToken, valueToken);
+
+ // Handle case where cpos is none. This means that no new non-anchors have been inserted
+ // since since the last compact/cleanup.
+ // This could happen if a previous compact inserted an anchor, but the temp ECOC drop
+ // was interrupted. On restart, the compaction will run emuBinaryV2 again, but since the
+ // anchor was already inserted for this value, it may return null cpos if there have been no
+ // new insertions for that value since the first compact attempt.
+ if (!positions.cpos.has_value()) {
+ // No new non-anchors since the last compact/cleanup.
+ // There must be at least one anchor.
+ uassert(7293602,
+ "An ESC anchor document is expected but none is found",
+ !positions.apos.has_value() || positions.apos.value() > 0);
+ // the anchor with the latest cpos already exists so no more work needed
+
+ return FLEEdgeCountInfo(
+ 0, tagToken, positions.cpos, positions.apos, reader.getStats(), boost::none);
+ }
+
+ uint64_t nextAnchorPos = 0;
+
+ if (!positions.apos.has_value()) {
+ auto r_esc = reader.getById(ESCCollection::generateNullAnchorId(tagToken));
+
+ uassert(7293601, "ESC null anchor document not found", !r_esc.isEmpty());
+
+ auto nullAnchorDoc =
+ uassertStatusOK(ESCCollection::decryptAnchorDocument(valueToken, r_esc));
+ nextAnchorPos = nullAnchorDoc.position + 1;
+ } else {
+ nextAnchorPos = positions.apos.value() + 1;
+ }
+
+ return FLEEdgeCountInfo(
+ nextAnchorPos,
+ tagToken,
+ positions.cpos,
+ positions.apos,
+ reader.getStats(),
+ edc.map([](const PrfBlock& prf) {
+ return FLETokenFromCDR<FLETokenType::EDCDerivedFromDataTokenAndContentionFactorToken>(
+ prf);
+ }));
+}
+
FLEEdgeCountInfo getEdgeCountInfo(const FLEStateCollectionReader& reader,
ConstDataRange tag,
FLETagQueryInterface::TagQueryType type,
@@ -2716,7 +2771,11 @@ std::vector<std::vector<FLEEdgeCountInfo>> ESCCollection::getTags(
countInfos.reserve(tokens.size());
for (const auto& token : tokens) {
- countInfos.push_back(getEdgeCountInfo(reader, token.esc, type, token.edc));
+ if (type == FLETagQueryInterface::TagQueryType::kCompact) {
+ countInfos.push_back(getEdgeCountInfoForCompact(reader, token.esc, token.edc));
+ } else {
+ countInfos.push_back(getEdgeCountInfo(reader, token.esc, type, token.edc));
+ }
}
countInfoSets.emplace_back(countInfos);
diff --git a/src/mongo/crypto/fle_crypto.h b/src/mongo/crypto/fle_crypto.h
index 7b49241fd54..24ac7425bae 100644
--- a/src/mongo/crypto/fle_crypto.h
+++ b/src/mongo/crypto/fle_crypto.h
@@ -331,7 +331,7 @@ struct ESCDocument {
*/
class FLETagQueryInterface {
public:
- enum class TagQueryType { kInsert, kQuery };
+ enum class TagQueryType { kInsert, kQuery, kCompact };
virtual ~FLETagQueryInterface();
@@ -386,6 +386,8 @@ public:
virtual bool existsById(PrfBlock block) const {
return !getById(block).isEmpty();
}
+
+ virtual ECStats getStats() const = 0;
};
class ESCCollection {
diff --git a/src/mongo/crypto/fle_crypto_test.cpp b/src/mongo/crypto/fle_crypto_test.cpp
index 15acde90f69..94fff514108 100644
--- a/src/mongo/crypto/fle_crypto_test.cpp
+++ b/src/mongo/crypto/fle_crypto_test.cpp
@@ -606,6 +606,10 @@ public:
return _docs.size();
}
+ ECStats getStats() const override {
+ return ECStats();
+ }
+
void setOverrideCount(int64_t count) {
_overrideCount = count;
}
diff --git a/src/mongo/crypto/fle_crypto_types.h b/src/mongo/crypto/fle_crypto_types.h
index 5affa1a6122..12bb268b294 100644
--- a/src/mongo/crypto/fle_crypto_types.h
+++ b/src/mongo/crypto/fle_crypto_types.h
@@ -35,6 +35,7 @@
#include "mongo/base/secure_allocator.h"
#include "mongo/crypto/aead_encryption.h"
+#include "mongo/crypto/fle_stats_gen.h"
#include "mongo/util/uuid.h"
namespace mongo {
@@ -261,11 +262,26 @@ struct FLEEdgeCountInfo {
boost::optional<EDCDerivedFromDataTokenAndContentionFactorToken> edcParam)
: count(c), tagToken(t), edc(edcParam) {}
+ FLEEdgeCountInfo(uint64_t c,
+ ESCTwiceDerivedTagToken t,
+ boost::optional<uint64_t> cpos,
+ boost::optional<uint64_t> apos,
+ boost::optional<ECStats> stats,
+ boost::optional<EDCDerivedFromDataTokenAndContentionFactorToken> edcParam)
+ : count(c), tagToken(t), cpos(cpos), apos(apos), stats(stats), edc(edcParam) {}
+
+
// May reflect a value suitable for insert or query.
uint64_t count;
ESCTwiceDerivedTagToken tagToken;
+ boost::optional<uint64_t> cpos;
+
+ boost::optional<uint64_t> apos;
+
+ boost::optional<ECStats> stats;
+
boost::optional<EDCDerivedFromDataTokenAndContentionFactorToken> edc;
};
diff --git a/src/mongo/db/commands/fle2_compact.cpp b/src/mongo/db/commands/fle2_compact.cpp
index f637e1c8dc8..162103af76f 100644
--- a/src/mongo/db/commands/fle2_compact.cpp
+++ b/src/mongo/db/commands/fle2_compact.cpp
@@ -105,34 +105,6 @@ void CompactStatsCounter<ECOCStats>::add(const ECOCStats& other) {
addDeletes(other.getDeleted());
}
-/**
- * Implementation of FLEStateCollectionReader for txn_api::TransactionClient
- */
-template <typename StatsType>
-class TxnCollectionReaderForCompact : public FLEStateCollectionReader {
-public:
- TxnCollectionReaderForCompact(FLEQueryInterface* queryImpl,
- const NamespaceString& nss,
- StatsType* stats)
- : _queryImpl(queryImpl), _nss(nss), _stats(stats) {}
-
- uint64_t getDocumentCount() const override {
- return _queryImpl->countDocuments(_nss);
- }
-
- BSONObj getById(PrfBlock block) const override {
- auto doc = BSON("v" << BSONBinData(block.data(), block.size(), BinDataGeneral));
- BSONElement element = doc.firstElement();
- auto result = _queryImpl->getById(_nss, element);
- _stats.addReads(1);
- return result;
- }
-
-private:
- FLEQueryInterface* _queryImpl;
- const NamespaceString& _nss;
- mutable CompactStatsCounter<StatsType> _stats;
-};
} // namespace
@@ -209,47 +181,38 @@ void compactOneFieldValuePairV2(FLEQueryInterface* queryImpl,
const ECOCCompactionDocumentV2& ecocDoc,
const NamespaceString& escNss,
ECStats* escStats) {
- auto escTagToken = FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedTagToken(ecocDoc.esc);
auto escValueToken =
FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedValueToken(ecocDoc.esc);
- CompactStatsCounter<ECStats> stats(escStats);
- TxnCollectionReaderForCompact reader(queryImpl, escNss, escStats);
-
- auto positions = ESCCollection::emuBinaryV2(reader, escTagToken, escValueToken);
-
- // Handle case where cpos is none. This means that no new non-anchors have been inserted
- // since since the last compact/cleanup.
- // This could happen if a previous compact inserted an anchor, but the temp ECOC drop
- // was interrupted. On restart, the compaction will run emuBinaryV2 again, but since the
- // anchor was already inserted for this value, it may return null cpos if there have been no
- // new insertions for that value since the first compact attempt.
- if (!positions.cpos.has_value()) {
- // No new non-anchors since the last compact/cleanup.
- // There must be at least one anchor.
- uassert(7293602,
- "An ESC anchor document is expected but none is found",
- !positions.apos.has_value() || positions.apos.value() > 0);
- // the anchor with the latest cpos already exists so no more work needed
- return;
+ std::vector<std::vector<FLEEdgePrfBlock>> tags;
+ {
+ FLEEdgePrfBlock edgeSet{ecocDoc.esc.data, boost::none};
+ tags.push_back({edgeSet});
}
- uint64_t nextAnchorPos = 0;
+ auto countInfoSets =
+ queryImpl->getTags(escNss, tags, FLEQueryInterface::TagQueryType::kCompact);
- if (!positions.apos.has_value()) {
- auto r_esc = reader.getById(ESCCollection::generateNullAnchorId(escTagToken));
+ uassert(7517100,
+ "CountInfoSets cannot be empty and must have one value.",
+ countInfoSets.size() == 1 && countInfoSets[0].size() == 1);
- uassert(7293601, "ESC null anchor document not found", !r_esc.isEmpty());
+ auto& val = countInfoSets[0][0];
+ CompactStatsCounter<ECStats> stats(escStats);
+
+ auto& tagToken = val.tagToken;
+ auto cpos = val.cpos;
- auto nullAnchorDoc =
- uassertStatusOK(ESCCollection::decryptAnchorDocument(escValueToken, r_esc));
- nextAnchorPos = nullAnchorDoc.position + 1;
- } else {
- nextAnchorPos = positions.apos.value() + 1;
+ uassert(
+ 7517103, "Stats cannot be empty for compacting a field value pair.", val.stats.has_value());
+ stats.add(val.stats.get());
+
+ if (!val.cpos) {
+ return;
}
- auto anchorDoc = ESCCollection::generateAnchorDocument(
- escTagToken, escValueToken, nextAnchorPos, positions.cpos.value());
+ auto anchorDoc =
+ ESCCollection::generateAnchorDocument(tagToken, escValueToken, val.count, cpos.value());
StmtId stmtId = kUninitializedStmtId;
if (MONGO_unlikely(fleCompactHangBeforeESCAnchorInsert.shouldFail())) {
diff --git a/src/mongo/db/commands/fle2_get_count_info_command.cpp b/src/mongo/db/commands/fle2_get_count_info_command.cpp
index fe5b82fe9b3..b1dd29fd4dd 100644
--- a/src/mongo/db/commands/fle2_get_count_info_command.cpp
+++ b/src/mongo/db/commands/fle2_get_count_info_command.cpp
@@ -70,6 +70,29 @@ std::vector<std::vector<FLEEdgePrfBlock>> toNestedTokens(
return nestedBlocks;
}
+QECountInfoReplyTokens tokenFromCountInfo(const FLEEdgeCountInfo& countInfo) {
+ QECountInfoReplyTokens token(FLEUtil::vectorFromCDR(countInfo.tagToken.toCDR()),
+ countInfo.count);
+
+ if (countInfo.edc) {
+ token.setEDCDerivedFromDataTokenAndContentionFactorToken(countInfo.edc.value().toCDR());
+ }
+
+ if (countInfo.cpos) {
+ token.setCpos(countInfo.cpos.get());
+ }
+
+ if (countInfo.apos) {
+ token.setApos(countInfo.apos.get());
+ }
+
+ if (countInfo.stats) {
+ token.setStats(countInfo.stats.get());
+ }
+
+ return token;
+}
+
std::vector<QECountInfoReplyTokenSet> toGetTagRequestTupleSet(
const std::vector<std::vector<FLEEdgeCountInfo>>& countInfoSets) {
@@ -82,14 +105,7 @@ std::vector<QECountInfoReplyTokenSet> toGetTagRequestTupleSet(
tokens.reserve(countInfos.size());
for (auto& countInfo : countInfos) {
- tokens.emplace_back(FLEUtil::vectorFromCDR(countInfo.tagToken.toCDR()),
- countInfo.count);
-
- if (countInfo.edc.has_value()) {
- auto& replyTuple = tokens.back();
- replyTuple.setEDCDerivedFromDataTokenAndContentionFactorToken(
- countInfo.edc.value().toCDR());
- }
+ tokens.emplace_back(tokenFromCountInfo(countInfo));
}
nestedBlocks.emplace_back(std::move(tokens));
@@ -98,6 +114,19 @@ std::vector<QECountInfoReplyTokenSet> toGetTagRequestTupleSet(
return nestedBlocks;
}
+FLEQueryInterface::TagQueryType queryTypeTranslation(QECountInfoQueryTypeEnum type) {
+ switch (type) {
+ case QECountInfoQueryTypeEnum::Insert:
+ return FLEQueryInterface::TagQueryType::kInsert;
+ case QECountInfoQueryTypeEnum::Query:
+ return FLEQueryInterface::TagQueryType::kQuery;
+ case QECountInfoQueryTypeEnum::Compact:
+ return FLEQueryInterface::TagQueryType::kCompact;
+ default:
+ uasserted(7517102, "Invalid QECountInfoQueryTypeEnum value.");
+ }
+}
+
QECountInfosReply getTagsLocal(OperationContext* opCtx,
const GetQueryableEncryptionCountInfo& request) {
@@ -105,12 +134,8 @@ QECountInfosReply getTagsLocal(OperationContext* opCtx,
auto nestedTokens = toNestedTokens(request.getTokens());
- auto countInfoSets =
- getTagsFromStorage(opCtx,
- request.getNamespace(),
- nestedTokens,
- request.getForInsert() ? FLETagQueryInterface::TagQueryType::kInsert
- : FLETagQueryInterface::TagQueryType::kQuery);
+ auto countInfoSets = getTagsFromStorage(
+ opCtx, request.getNamespace(), nestedTokens, queryTypeTranslation(request.getQueryType()));
QECountInfosReply reply;
reply.setCounts(toGetTagRequestTupleSet(countInfoSets));
diff --git a/src/mongo/db/commands/fle2_get_count_info_command.idl b/src/mongo/db/commands/fle2_get_count_info_command.idl
index 93a1a6df499..8717fa9e32f 100644
--- a/src/mongo/db/commands/fle2_get_count_info_command.idl
+++ b/src/mongo/db/commands/fle2_get_count_info_command.idl
@@ -31,6 +31,7 @@ global:
imports:
- "mongo/db/basic_types.idl"
+ - "mongo/crypto/fle_stats.idl"
structs:
QECountInfoReplyTokens:
@@ -50,6 +51,18 @@ structs:
type: bindata_generic
cpp_name: EDCDerivedFromDataTokenAndContentionFactorToken
optional: true
+ cpos:
+ description: "cpos argument returned from emuBinary"
+ type: long
+ optional: true
+ apos:
+ description: "cpos argument returned from emuBinary"
+ type: long
+ optional: true
+ stats:
+ description: "stats returned for compaction algorithm"
+ type: ECStats
+ optional: true
QECountInfoReplyTokenSet:
description: "Array of tokens sets"
@@ -87,6 +100,14 @@ structs:
fields:
counts: array<QECountInfoReplyTokenSet>
+enums:
+ QECountInfoQueryType:
+ description: "query types"
+ type: string
+ values:
+ Insert: "insert"
+ Query: "query"
+ Compact: "compact"
commands:
getQueryableEncryptionCountInfo:
@@ -100,6 +121,7 @@ commands:
tokens:
description: "Array of tokens to fetch"
type: array<QECountInfoRequestTokenSet>
- forInsert:
- description: Whether to return a count for insert or query
- type: bool
+ queryType:
+ description: "Purpose of command, either for insert, query, or compact"
+ type: QECountInfoQueryType
+
diff --git a/src/mongo/db/fle_crud.cpp b/src/mongo/db/fle_crud.cpp
index db64687f09f..0868141218c 100644
--- a/src/mongo/db/fle_crud.cpp
+++ b/src/mongo/db/fle_crud.cpp
@@ -186,6 +186,30 @@ std::vector<QECountInfoRequestTokenSet> toTagSets(
return nestedBlocks;
}
+FLEEdgeCountInfo convertTokensToEdgeCount(const QECountInfoReplyTokens& token) {
+
+ boost::optional<EDCDerivedFromDataTokenAndContentionFactorToken> edc;
+ if (token.getEDCDerivedFromDataTokenAndContentionFactorToken()) {
+ edc = FLETokenFromCDR<FLETokenType::EDCDerivedFromDataTokenAndContentionFactorToken>(
+ token.getEDCDerivedFromDataTokenAndContentionFactorToken().value());
+ }
+
+ boost::optional<uint64_t> cpos;
+ if (token.getCpos()) {
+ cpos = token.getCpos();
+ }
+
+ boost::optional<uint64_t> apos;
+ if (token.getApos()) {
+ apos = token.getApos();
+ }
+
+ auto esc =
+ FLETokenFromCDR<FLETokenType::ESCTwiceDerivedTagToken>(token.getESCTwiceDerivedTagToken());
+
+ return FLEEdgeCountInfo(token.getCount(), esc, cpos, apos, token.getStats(), edc);
+}
+
std::vector<std::vector<FLEEdgeCountInfo>> toEdgeCounts(
const std::vector<QECountInfoReplyTokenSet>& tupleSet) {
@@ -200,16 +224,7 @@ std::vector<std::vector<FLEEdgeCountInfo>> toEdgeCounts(
blocks.reserve(tuples.size());
for (auto& tuple : tuples) {
- blocks.emplace_back(tuple.getCount(),
- FLETokenFromCDR<FLETokenType::ESCTwiceDerivedTagToken>(
- tuple.getESCTwiceDerivedTagToken()));
- auto& p = blocks.back();
-
- if (tuple.getEDCDerivedFromDataTokenAndContentionFactorToken().has_value()) {
- p.edc =
- FLETokenFromCDR<FLETokenType::EDCDerivedFromDataTokenAndContentionFactorToken>(
- tuple.getEDCDerivedFromDataTokenAndContentionFactorToken().value());
- }
+ blocks.emplace_back(convertTokensToEdgeCount(tuple));
}
nestedBlocks.emplace_back(std::move(blocks));
@@ -1467,6 +1482,19 @@ uint64_t FLEQueryInterfaceImpl::countDocuments(const NamespaceString& nss) {
return static_cast<uint64_t>(signedDocCount);
}
+QECountInfoQueryTypeEnum queryTypeTranslation(FLEQueryInterface::TagQueryType type) {
+ switch (type) {
+ case FLEQueryInterface::TagQueryType::kInsert:
+ return QECountInfoQueryTypeEnum::Insert;
+ case FLEQueryInterface::TagQueryType::kQuery:
+ return QECountInfoQueryTypeEnum::Query;
+ case FLEQueryInterface::TagQueryType::kCompact:
+ return QECountInfoQueryTypeEnum::Compact;
+ default:
+ uasserted(7517101, "Invalid TagQueryType value.");
+ }
+}
+
std::vector<std::vector<FLEEdgeCountInfo>> FLEQueryInterfaceImpl::getTags(
const NamespaceString& nss,
const std::vector<std::vector<FLEEdgePrfBlock>>& tokensSets,
@@ -1480,7 +1508,7 @@ std::vector<std::vector<FLEEdgeCountInfo>> FLEQueryInterfaceImpl::getTags(
}
getCountsCmd.setTokens(toTagSets(tokensSets));
- getCountsCmd.setForInsert(type == FLEQueryInterface::TagQueryType::kInsert);
+ getCountsCmd.setQueryType(queryTypeTranslation(type));
auto response = _txnClient.runCommandSync(nss.db(), getCountsCmd.toBSON({}));
@@ -1756,7 +1784,7 @@ uint64_t FLETagNoTXNQuery::countDocuments(const NamespaceString& nss) {
std::vector<std::vector<FLEEdgeCountInfo>> FLETagNoTXNQuery::getTags(
const NamespaceString& nss,
const std::vector<std::vector<FLEEdgePrfBlock>>& tokensSets,
- TagQueryType type) {
+ FLEQueryInterface::TagQueryType type) {
invariant(!_opCtx->inMultiDocumentTransaction());
@@ -1775,7 +1803,7 @@ std::vector<std::vector<FLEEdgeCountInfo>> FLETagNoTXNQuery::getTags(
}
getCountsCmd.setTokens(toTagSets(tokensSets));
- getCountsCmd.setForInsert(type == FLEQueryInterface::TagQueryType::kInsert);
+ getCountsCmd.setQueryType(queryTypeTranslation(type));
DBDirectClient directClient(opCtx.get());
diff --git a/src/mongo/db/fle_crud.h b/src/mongo/db/fle_crud.h
index 30c30c90cb2..a2c5fe051a7 100644
--- a/src/mongo/db/fle_crud.h
+++ b/src/mongo/db/fle_crud.h
@@ -378,32 +378,6 @@ private:
};
/**
- * Implementation of FLEStateCollectionReader for txn_api::TransactionClient
- *
- * Document count is cached since we only need it once per esc or ecc collection.
- */
-class TxnCollectionReader : public FLEStateCollectionReader {
-public:
- TxnCollectionReader(uint64_t count, FLETagQueryInterface* queryImpl, const NamespaceString& nss)
- : _count(count), _queryImpl(queryImpl), _nss(nss) {}
-
- uint64_t getDocumentCount() const override {
- return _count;
- }
-
- BSONObj getById(PrfBlock block) const override {
- auto doc = BSON("v" << BSONBinData(block.data(), block.size(), BinDataGeneral));
- BSONElement element = doc.firstElement();
- return _queryImpl->getById(_nss, element);
- }
-
-private:
- uint64_t _count;
- FLETagQueryInterface* _queryImpl;
- NamespaceString _nss;
-};
-
-/**
* Creates a new SyncTransactionWithRetries object that runs a transaction on the
* sharding fixed task executor.
*/
diff --git a/src/mongo/db/fle_crud_mongod.cpp b/src/mongo/db/fle_crud_mongod.cpp
index 19650224271..a13e25c6685 100644
--- a/src/mongo/db/fle_crud_mongod.cpp
+++ b/src/mongo/db/fle_crud_mongod.cpp
@@ -27,6 +27,7 @@
* it in the license file.
*/
+#include "mongo/base/status.h"
#include "mongo/db/fle_crud.h"
#include <string>
@@ -169,6 +170,10 @@ public:
return BSONObj();
}
+
+ ECStats getStats() const override {
+ return ECStats();
+ }
};
@@ -189,8 +194,17 @@ public:
return _count;
}
+ void incrementRead() const {
+ _stats.setRead(_stats.getRead() + 1);
+ }
+
+ ECStats getStats() const override {
+ return _stats;
+ }
+
BSONObj getById(PrfBlock block) const override {
auto record = getRecordById(block);
+
if (record.has_value()) {
return record->data.releaseToBson();
}
@@ -211,6 +225,7 @@ private:
builder.appendBinData(BSONBinData(block.data(), block.size(), BinDataType::BinDataGeneral));
auto recordId = RecordId(builder.getBuffer(), builder.getSize());
+ incrementRead();
return _cursor->seekExact(recordId);
}
@@ -219,6 +234,7 @@ private:
const uint64_t _count;
const NamespaceStringOrUUID& _nssOrUUID;
SeekableRecordCursor* _cursor;
+ mutable ECStats _stats;
};
/**
@@ -246,8 +262,17 @@ public:
return _count;
}
+ void incrementRead() const {
+ _stats.setRead(_stats.getRead() + 1);
+ }
+
+ ECStats getStats() const override {
+ return _stats;
+ }
+
BSONObj getById(PrfBlock block) const override {
auto record = getRecordById(block);
+
if (record.has_value()) {
return record->data.releaseToBson();
}
@@ -270,6 +295,8 @@ private:
kb.appendBinData(BSONBinData(block.data(), block.size(), BinDataGeneral));
KeyString::Value id(kb.getValueCopy());
+ incrementRead();
+
auto ksEntry = _indexCursor->seekForKeyString(id);
if (!ksEntry) {
return boost::none;
@@ -299,6 +326,7 @@ private:
SortedDataInterface* _sdi;
SortedDataInterface::Cursor* _indexCursor;
SeekableRecordCursor* _cursor;
+ mutable ECStats _stats;
};
const auto kIdIndexName = "_id_"_sd;
diff --git a/src/mongo/db/fle_crud_test.cpp b/src/mongo/db/fle_crud_test.cpp
index 65739ebba8d..e025da89572 100644
--- a/src/mongo/db/fle_crud_test.cpp
+++ b/src/mongo/db/fle_crud_test.cpp
@@ -745,6 +745,10 @@ public:
return _queryImpl.getById(_coll, doc.firstElement());
}
+ ECStats getStats() const override {
+ return ECStats();
+ }
+
private:
NamespaceString _coll;
FLEQueryInterfaceMock& _queryImpl;