diff options
author | Benety Goh <benety@mongodb.com> | 2016-10-14 11:31:19 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2016-10-17 15:01:57 -0400 |
commit | 43583fddef7ac89222f9cdfa14bb1452c740e8c7 (patch) | |
tree | 10a7b1547c89da531a4ac8775385641035ad9f0d /src | |
parent | 01fb78506f2a93702b1f0c14767cd3d5a2a420f2 (diff) | |
download | mongo-43583fddef7ac89222f9cdfa14bb1452c740e8c7.tar.gz |
SERVER-26631 replaced StorageInterface::findOne/deleteOne with findDocuments/deleteDocuments
This commit updates the repl::StorageInterface interface but introduces no functional change.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/repl/oplog_buffer_collection.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface.h | 39 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.cpp | 66 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl.h | 28 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_impl_test.cpp | 555 | ||||
-rw-r--r-- | src/mongo/db/repl/storage_interface_mock.h | 85 |
6 files changed, 446 insertions, 335 deletions
diff --git a/src/mongo/db/repl/oplog_buffer_collection.cpp b/src/mongo/db/repl/oplog_buffer_collection.cpp index 736c91fc05b..6e1be76806b 100644 --- a/src/mongo/db/repl/oplog_buffer_collection.cpp +++ b/src/mongo/db/repl/oplog_buffer_collection.cpp @@ -251,15 +251,17 @@ bool OplogBufferCollection::_peekOneSide_inlock(OperationContext* txn, boundInclusion = BoundInclusion::kIncludeEndKeyOnly; } - auto result = - _storageInterface->findOne(txn, _nss, kIdIdxName, scanDirection, startKey, boundInclusion); + auto result = _storageInterface->findDocuments( + txn, _nss, kIdIdxName, scanDirection, startKey, boundInclusion, 1U); if (!result.isOK()) { if (result != ErrorCodes::CollectionIsEmpty) { fassert(40163, result.getStatus()); } return false; } - *value = extractEmbeddedOplogDocument(result.getValue()).getOwned(); + auto&& docs = result.getValue(); + invariant(!docs.empty()); + *value = extractEmbeddedOplogDocument(docs.front()).getOwned(); return true; } diff --git a/src/mongo/db/repl/storage_interface.h b/src/mongo/db/repl/storage_interface.h index a65c7b2b0f3..ae4f6f7eabf 100644 --- a/src/mongo/db/repl/storage_interface.h +++ b/src/mongo/db/repl/storage_interface.h @@ -30,6 +30,7 @@ #pragma once #include <boost/optional.hpp> +#include <cstddef> #include <iosfwd> #include <string> @@ -225,8 +226,10 @@ public: virtual Status isAdminDbValid(OperationContext* txn) = 0; /** - * Finds the first document returned by a collection or index scan on the collection in the - * requested direction. + * Finds at most "limit" documents returned by a collection or index scan on the collection in + * the requested direction. + * The documents returned will be copied and buffered. No cursors on the underlying collection + * will be kept open once this function returns. * If "indexName" is boost::none, a collection scan is used to locate the document. * Index scan options: * If "startKey" is not empty, the index scan will start from the given key (instead of @@ -239,24 +242,28 @@ public: kForward = 1, kBackward = -1, }; - virtual StatusWith<BSONObj> findOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) = 0; + virtual StatusWith<std::vector<BSONObj>> findDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) = 0; /** - * Deletes the first document returned by a collection or index scan on the collection in the - * requested direction. Returns deleted document on success. + * Deletes at most "limit" documents returned by a collection or index scan on the collection in + * the requested direction. Returns deleted documents on success. + * The documents returned will be copied and buffered. No cursors on the underlying collection + * will be kept open once this function returns. * If "indexName" is null, a collection scan is used to locate the document. */ - virtual StatusWith<BSONObj> deleteOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) = 0; + virtual StatusWith<std::vector<BSONObj>> deleteDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) = 0; }; } // namespace repl diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp index c36497609d0..2ccb8006282 100644 --- a/src/mongo/db/repl/storage_interface_impl.cpp +++ b/src/mongo/db/repl/storage_interface_impl.cpp @@ -451,16 +451,20 @@ DeleteStageParams makeDeleteStageParamsForDeleteOne() { } /** - * Shared implementation between findOne and deleteOne. + * Shared implementation between findDocuments and deleteDocuments. */ enum class FindDeleteMode { kFind, kDelete }; -StatusWith<BSONObj> _findOrDeleteOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - StorageInterface::ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion, - FindDeleteMode mode) { +StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments( + OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + StorageInterface::ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit, + FindDeleteMode mode) { + invariant(limit == 1U); + auto isFind = mode == FindDeleteMode::kFind; auto opStr = isFind ? "StorageInterfaceImpl::findOne" : "StorageInterfaceImpl::deleteOne"; @@ -553,7 +557,9 @@ StatusWith<BSONObj> _findOrDeleteOne(OperationContext* txn, str::stream() << "Collection is empty, ns: " << nss.ns()}; } invariant(PlanExecutor::ADVANCED == state); - return doc.getOwned(); + std::vector<BSONObj> docs; + docs.push_back(doc.getOwned()); + return docs; } MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, opStr, nss.ns()); MONGO_UNREACHABLE; @@ -561,24 +567,34 @@ StatusWith<BSONObj> _findOrDeleteOne(OperationContext* txn, } // namespace -StatusWith<BSONObj> StorageInterfaceImpl::findOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) { - return _findOrDeleteOne( - txn, nss, indexName, scanDirection, startKey, boundInclusion, FindDeleteMode::kFind); +StatusWith<std::vector<BSONObj>> StorageInterfaceImpl::findDocuments( + OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) { + return _findOrDeleteDocuments( + txn, nss, indexName, scanDirection, startKey, boundInclusion, limit, FindDeleteMode::kFind); } -StatusWith<BSONObj> StorageInterfaceImpl::deleteOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) { - return _findOrDeleteOne( - txn, nss, indexName, scanDirection, startKey, boundInclusion, FindDeleteMode::kDelete); +StatusWith<std::vector<BSONObj>> StorageInterfaceImpl::deleteDocuments( + OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) { + return _findOrDeleteDocuments(txn, + nss, + indexName, + scanDirection, + startKey, + boundInclusion, + limit, + FindDeleteMode::kDelete); } Status StorageInterfaceImpl::isAdminDbValid(OperationContext* txn) { diff --git a/src/mongo/db/repl/storage_interface_impl.h b/src/mongo/db/repl/storage_interface_impl.h index 8ddc2be0902..9edd37b44c8 100644 --- a/src/mongo/db/repl/storage_interface_impl.h +++ b/src/mongo/db/repl/storage_interface_impl.h @@ -104,19 +104,21 @@ public: Status dropCollection(OperationContext* txn, const NamespaceString& nss) override; - StatusWith<BSONObj> findOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) override; - - StatusWith<BSONObj> deleteOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) override; + StatusWith<std::vector<BSONObj>> findDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) override; + + StatusWith<std::vector<BSONObj>> deleteDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) override; Status isAdminDbValid(OperationContext* txn) override; diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp index ddac652c7ef..3382f803ebb 100644 --- a/src/mongo/db/repl/storage_interface_impl_test.cpp +++ b/src/mongo/db/repl/storage_interface_impl_test.cpp @@ -165,7 +165,6 @@ int64_t getIndexKeyCount(OperationContext* txn, IndexCatalog* cat, IndexDescript return numKeys; } - class StorageInterfaceImplTest : public ServiceContextMongoDTest { protected: Client* getClient() const { @@ -588,37 +587,44 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, DropCollectionWorksWithMissingColl ASSERT_FALSE(AutoGetDb(txn, nss.db(), MODE_IS).getDb()); } -TEST_F(StorageInterfaceImplWithReplCoordTest, FindOneReturnsInvalidNamespaceIfCollectionIsMissing) { +TEST_F(StorageInterfaceImplWithReplCoordTest, + FindDocumentsReturnsInvalidNamespaceIfCollectionIsMissing) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, - storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } -TEST_F(StorageInterfaceImplWithReplCoordTest, FindOneReturnsIndexNotFoundIfIndexIsMissing) { +TEST_F(StorageInterfaceImplWithReplCoordTest, FindDocumentsReturnsIndexNotFoundIfIndexIsMissing) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "nonexistent"_sd; ASSERT_OK(storage.createCollection(txn, nss, CollectionOptions())); ASSERT_EQUALS(ErrorCodes::IndexNotFound, - storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneReturnsIndexOptionsConflictIfIndexIsAPartialIndex) { + FindDocumentsReturnsIndexOptionsConflictIfIndexIsAPartialIndex) { auto txn = getOperationContext(); StorageInterfaceImpl storage; storage.startup(); @@ -636,27 +642,34 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, ASSERT_OK(loader->commit()); auto indexName = "x_1"_sd; ASSERT_EQUALS(ErrorCodes::IndexOptionsConflict, - storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } -TEST_F(StorageInterfaceImplWithReplCoordTest, FindOneReturnsCollectionIsEmptyIfCollectionIsEmpty) { +TEST_F(StorageInterfaceImplWithReplCoordTest, + FindDocumentsReturnsCollectionIsEmptyIfCollectionIsEmpty) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; ASSERT_OK(storage.createCollection(txn, nss, CollectionOptions())); ASSERT_EQUALS(ErrorCodes::CollectionIsEmpty, - storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } /** @@ -675,8 +688,17 @@ void _assertDocumentsInCollectionEquals(OperationContext* txn, ASSERT_EQUALS(ErrorCodes::CollectionIsEmpty, iter->next().getStatus()); } +/** + * Returns first BSONObj from a StatusWith<std::vector<BSONObj>>. + */ +BSONObj _assetGetFront(const StatusWith<std::vector<BSONObj>>& statusWithDocs) { + auto&& docs = statusWithDocs.getValue(); + ASSERT_FALSE(docs.empty()); + return docs.front(); +} + TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneReturnsDocumentWithLowestKeyValueIfScanDirectionIsForward) { + FindDocumentsReturnsDocumentWithLowestKeyValueIfScanDirectionIsForward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -691,73 +713,88 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, BSON("_id" << 4)})); // startKey not provided - ASSERT_BSONOBJ_EQ(BSON("_id" << 0), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 0), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // startKey provided; include start key - ASSERT_BSONOBJ_EQ(BSON("_id" << 0), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 0), - BoundInclusion::kIncludeStartKeyOnly))); - ASSERT_BSONOBJ_EQ(BSON("_id" << 1), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kIncludeStartKeyOnly))); - - ASSERT_BSONOBJ_EQ(BSON("_id" << 1), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 0.5), - BoundInclusion::kIncludeStartKeyOnly))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 0), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 0), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 1), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); + + ASSERT_BSONOBJ_EQ( + BSON("_id" << 1), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 0.5), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // startKey provided; include both start and end keys - ASSERT_BSONOBJ_EQ(BSON("_id" << 1), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kIncludeStartKeyOnly))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 1), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // startKey provided; exclude start key - ASSERT_BSONOBJ_EQ(BSON("_id" << 2), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kIncludeEndKeyOnly))); - - ASSERT_BSONOBJ_EQ(BSON("_id" << 2), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 1.5), - BoundInclusion::kIncludeEndKeyOnly))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 2), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kIncludeEndKeyOnly, + 1U))); + + ASSERT_BSONOBJ_EQ( + BSON("_id" << 2), + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 1.5), + BoundInclusion::kIncludeEndKeyOnly, + 1U))); // startKey provided; exclude both start and end keys ASSERT_BSONOBJ_EQ( BSON("_id" << 2), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kExcludeBothStartAndEndKeys))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kExcludeBothStartAndEndKeys, + 1U))); _assertDocumentsInCollectionEquals( txn, @@ -766,7 +803,7 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneReturnsDocumentWithHighestKeyValueIfScanDirectionIsBackward) { + FindDocumentsReturnsDocumentWithHighestKeyValueIfScanDirectionIsBackward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -783,60 +820,66 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey not provided ASSERT_BSONOBJ_EQ( BSON("_id" << 4), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // startKey provided; include start key ASSERT_BSONOBJ_EQ( BSON("_id" << 4), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 4), - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 4), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); ASSERT_BSONOBJ_EQ( BSON("_id" << 3), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 3), - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 3), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // startKey provided; include both start and end keys ASSERT_BSONOBJ_EQ( BSON("_id" << 4), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 4), - BoundInclusion::kIncludeBothStartAndEndKeys))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 4), + BoundInclusion::kIncludeBothStartAndEndKeys, + 1U))); // startKey provided; exclude start key ASSERT_BSONOBJ_EQ( BSON("_id" << 2), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 3), - BoundInclusion::kIncludeEndKeyOnly))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 3), + BoundInclusion::kIncludeEndKeyOnly, + 1U))); // startKey provided; exclude both start and end keys ASSERT_BSONOBJ_EQ( BSON("_id" << 2), - unittest::assertGet(storage.findOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 3), - BoundInclusion::kExcludeBothStartAndEndKeys))); + _assetGetFront(storage.findDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 3), + BoundInclusion::kExcludeBothStartAndEndKeys, + 1U))); _assertDocumentsInCollectionEquals( txn, @@ -845,20 +888,22 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneCollectionScanReturnsFirstDocumentInsertedIfScanDirectionIsForward) { + FindDocumentsCollScanReturnsFirstDocumentInsertedIfScanDirectionIsForward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); ASSERT_OK(storage.createCollection(txn, nss, CollectionOptions())); ASSERT_OK( storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); - ASSERT_BSONOBJ_EQ(BSON("_id" << 1), - unittest::assertGet(storage.findOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + ASSERT_BSONOBJ_EQ( + BSON("_id" << 1), + _assetGetFront(storage.findDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); // Check collection contents. OplogInterface returns documents in reverse natural order. OplogInterfaceLocal oplog(txn, nss.ns()); @@ -870,7 +915,7 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneCollectionScanReturnsLastDocumentInsertedIfScanDirectionIsBackward) { + FindDocumentsCollScanReturnsLastDocumentInsertedIfScanDirectionIsBackward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -879,19 +924,20 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_BSONOBJ_EQ( BSON("_id" << 0), - unittest::assertGet(storage.findOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kBackward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.findDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kBackward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals( txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)}); } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneCollectionScanReturnsNoSuchKeyIfStartKeyIsNotEmpty) { + FindDocumentsCollScanReturnsNoSuchKeyIfStartKeyIsNotEmpty) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -899,16 +945,19 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, ASSERT_OK( storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_EQUALS(ErrorCodes::NoSuchKey, - storage.findOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kIncludeStartKeyOnly)); + storage + .findDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - FindOneCollectionScanReturnsInvalidOptionsIfBoundIsNotStartKeyOnly) { + FindDocumentsCollScanReturnsInvalidOptionsIfBoundIsNotStartKeyOnly) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -916,62 +965,74 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, ASSERT_OK( storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_EQUALS(ErrorCodes::InvalidOptions, - storage.findOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeEndKeyOnly)); + storage + .findDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeEndKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneReturnsInvalidNamespaceIfCollectionIsMissing) { + DeleteDocumentsReturnsInvalidNamespaceIfCollectionIsMissing) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, - storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } -TEST_F(StorageInterfaceImplWithReplCoordTest, DeleteOneReturnsIndexNotFoundIfIndexIsMissing) { +TEST_F(StorageInterfaceImplWithReplCoordTest, DeleteDocumentsReturnsIndexNotFoundIfIndexIsMissing) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "nonexistent"_sd; ASSERT_OK(storage.createCollection(txn, nss, CollectionOptions())); ASSERT_EQUALS(ErrorCodes::IndexNotFound, - storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneReturnsCollectionIsEmptyIfCollectionIsEmpty) { + DeleteDocumentsReturnsCollectionIsEmptyIfCollectionIsEmpty) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); auto indexName = "_id_"_sd; ASSERT_OK(storage.createCollection(txn, nss, CollectionOptions())); ASSERT_EQUALS(ErrorCodes::CollectionIsEmpty, - storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly)); + storage + .deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneReturnsDocumentWithLowestKeyValueIfScanDirectionIsForward) { + DeleteDocumentsReturnsDocumentWithLowestKeyValueIfScanDirectionIsForward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -991,12 +1052,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey not provided ASSERT_BSONOBJ_EQ( BSON("_id" << 0), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, @@ -1011,12 +1073,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey provided; include start key ASSERT_BSONOBJ_EQ( BSON("_id" << 2), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 2), - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 2), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, @@ -1030,12 +1093,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey provided; exclude start key ASSERT_BSONOBJ_EQ( BSON("_id" << 5), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kForward, - BSON("" << 4), - BoundInclusion::kIncludeEndKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kForward, + BSON("" << 4), + BoundInclusion::kIncludeEndKeyOnly, + 1U))); _assertDocumentsInCollectionEquals( txn, @@ -1044,7 +1108,7 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneReturnsDocumentWithHighestKeyValueIfScanDirectionIsBackward) { + DeleteDocumentsReturnsDocumentWithHighestKeyValueIfScanDirectionIsBackward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -1064,12 +1128,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey not provided ASSERT_BSONOBJ_EQ( BSON("_id" << 7), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, @@ -1084,12 +1149,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey provided; include start key ASSERT_BSONOBJ_EQ( BSON("_id" << 5), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 5), - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 5), + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, @@ -1103,12 +1169,13 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, // startKey provided; exclude start key ASSERT_BSONOBJ_EQ( BSON("_id" << 2), - unittest::assertGet(storage.deleteOne(txn, - nss, - indexName, - StorageInterface::ScanDirection::kBackward, - BSON("" << 3), - BoundInclusion::kIncludeEndKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + indexName, + StorageInterface::ScanDirection::kBackward, + BSON("" << 3), + BoundInclusion::kIncludeEndKeyOnly, + 1U))); _assertDocumentsInCollectionEquals( txn, @@ -1117,7 +1184,7 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneCollectionScanReturnsFirstDocumentInsertedIfScanDirectionIsForward) { + DeleteDocumentsCollScanReturnsFirstDocumentInsertedIfScanDirectionIsForward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -1126,18 +1193,19 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_BSONOBJ_EQ( BSON("_id" << 1), - unittest::assertGet(storage.deleteOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, {BSON("_id" << 2), BSON("_id" << 0)}); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneCollectionScanReturnsLastDocumentInsertedIfScanDirectionIsBackward) { + DeleteDocumentsCollScanReturnsLastDocumentInsertedIfScanDirectionIsBackward) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -1146,18 +1214,19 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_BSONOBJ_EQ( BSON("_id" << 0), - unittest::assertGet(storage.deleteOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kBackward, - {}, - BoundInclusion::kIncludeStartKeyOnly))); + _assetGetFront(storage.deleteDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kBackward, + {}, + BoundInclusion::kIncludeStartKeyOnly, + 1U))); _assertDocumentsInCollectionEquals(txn, nss, {BSON("_id" << 1), BSON("_id" << 2)}); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneCollectionScanReturnsNoSuchKeyIfStartKeyIsNotEmpty) { + DeleteDocumentsCollScanReturnsNoSuchKeyIfStartKeyIsNotEmpty) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -1165,16 +1234,19 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, ASSERT_OK( storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_EQUALS(ErrorCodes::NoSuchKey, - storage.deleteOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - BSON("" << 1), - BoundInclusion::kIncludeStartKeyOnly)); + storage + .deleteDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + BSON("" << 1), + BoundInclusion::kIncludeStartKeyOnly, + 1U) + .getStatus()); } TEST_F(StorageInterfaceImplWithReplCoordTest, - DeleteOneCollectionScanReturnsInvalidOptionsIfBoundIsNotStartKeyOnly) { + DeleteDocumentsCollScanReturnsInvalidOptionsIfBoundIsNotStartKeyOnly) { auto txn = getOperationContext(); StorageInterfaceImpl storage; auto nss = makeNamespace(_agent); @@ -1182,12 +1254,15 @@ TEST_F(StorageInterfaceImplWithReplCoordTest, ASSERT_OK( storage.insertDocuments(txn, nss, {BSON("_id" << 1), BSON("_id" << 2), BSON("_id" << 0)})); ASSERT_EQUALS(ErrorCodes::InvalidOptions, - storage.deleteOne(txn, - nss, - boost::none, - StorageInterface::ScanDirection::kForward, - {}, - BoundInclusion::kIncludeEndKeyOnly)); + storage + .deleteDocuments(txn, + nss, + boost::none, + StorageInterface::ScanDirection::kForward, + {}, + BoundInclusion::kIncludeEndKeyOnly, + 1U) + .getStatus()); } } // namespace diff --git a/src/mongo/db/repl/storage_interface_mock.h b/src/mongo/db/repl/storage_interface_mock.h index a11cf789ef1..911244c2670 100644 --- a/src/mongo/db/repl/storage_interface_mock.h +++ b/src/mongo/db/repl/storage_interface_mock.h @@ -101,18 +101,22 @@ public: OperationContext* txn, const NamespaceString& nss, const CollectionOptions& options)>; using DropCollectionFn = stdx::function<Status(OperationContext* txn, const NamespaceString& nss)>; - using FindOneFn = stdx::function<StatusWith<BSONObj>(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion)>; - using DeleteOneFn = stdx::function<StatusWith<BSONObj>(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion)>; + using FindDocumentsFn = + stdx::function<StatusWith<std::vector<BSONObj>>(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit)>; + using DeleteDocumentsFn = + stdx::function<StatusWith<std::vector<BSONObj>>(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit)>; using IsAdminDbValidFn = stdx::function<Status(OperationContext* txn)>; StorageInterfaceMock() = default; @@ -174,22 +178,25 @@ public: return dropCollFn(txn, nss); }; - StatusWith<BSONObj> findOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) override { - return findOneFn(txn, nss, indexName, scanDirection, startKey, boundInclusion); + StatusWith<std::vector<BSONObj>> findDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) override { + return findDocumentsFn(txn, nss, indexName, scanDirection, startKey, boundInclusion, limit); } - StatusWith<BSONObj> deleteOne(OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) override { - return deleteOneFn(txn, nss, indexName, scanDirection, startKey, boundInclusion); + StatusWith<std::vector<BSONObj>> deleteDocuments(OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) override { + return deleteDocumentsFn( + txn, nss, indexName, scanDirection, startKey, boundInclusion, limit); } Status isAdminDbValid(OperationContext* txn) override { @@ -227,20 +234,22 @@ public: DropCollectionFn dropCollFn = [](OperationContext* txn, const NamespaceString& nss) { return Status{ErrorCodes::IllegalOperation, "DropCollectionFn not implemented."}; }; - FindOneFn findOneFn = [](OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) { + FindDocumentsFn findDocumentsFn = [](OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) { return Status{ErrorCodes::IllegalOperation, "FindOneFn not implemented."}; }; - DeleteOneFn deleteOneFn = [](OperationContext* txn, - const NamespaceString& nss, - boost::optional<StringData> indexName, - ScanDirection scanDirection, - const BSONObj& startKey, - BoundInclusion boundInclusion) { + DeleteDocumentsFn deleteDocumentsFn = [](OperationContext* txn, + const NamespaceString& nss, + boost::optional<StringData> indexName, + ScanDirection scanDirection, + const BSONObj& startKey, + BoundInclusion boundInclusion, + std::size_t limit) { return Status{ErrorCodes::IllegalOperation, "DeleteOneFn not implemented."}; }; IsAdminDbValidFn isAdminDbValidFn = [](OperationContext*) { |