summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormay <may.hoque@mongodb.com>2017-08-03 19:55:36 -0400
committermay <may.hoque@mongodb.com>2017-08-03 19:55:36 -0400
commit4f173c14a1f5c6608f0f114a52d776975690572d (patch)
treef4bee25d5deedb20191f41828a2ea1b97893c1f4
parent5ab64bbe07e98b7cc0b8a88b6adb3b348e174651 (diff)
downloadmongo-4f173c14a1f5c6608f0f114a52d776975690572d.tar.gz
SERVER-30301 Add explicit configuration object for DocumentStructureEnumerator
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/idempotency_document_structure.cpp116
-rw-r--r--src/mongo/db/repl/idempotency_document_structure.h32
-rw-r--r--src/mongo/db/repl/idempotency_document_structure_test.cpp148
-rw-r--r--src/mongo/db/repl/idempotency_sequence.cpp42
-rw-r--r--src/mongo/db/repl/idempotency_sequence.h2
-rw-r--r--src/mongo/db/repl/idempotency_update_sequence.cpp2
7 files changed, 219 insertions, 124 deletions
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 059c78057d7..0c841ed5e45 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -595,7 +595,6 @@ env.Library(
target='idempotency_test_util',
source=[
'idempotency_document_structure.cpp',
- 'idempotency_sequence.cpp',
'idempotency_update_sequence.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/db/repl/idempotency_document_structure.cpp b/src/mongo/db/repl/idempotency_document_structure.cpp
index efb9f0aec74..94319acf816 100644
--- a/src/mongo/db/repl/idempotency_document_structure.cpp
+++ b/src/mongo/db/repl/idempotency_document_structure.cpp
@@ -34,6 +34,17 @@
namespace mongo {
+DocumentStructureEnumeratorConfig::DocumentStructureEnumeratorConfig(std::set<StringData> fields_,
+ size_t depth_,
+ size_t length_,
+ bool skipSubDocs_,
+ bool skipSubArrs_)
+ : fields(std::move(fields_)),
+ depth(depth_),
+ length(length_),
+ skipSubDocs(skipSubDocs_),
+ skipSubArrs(skipSubArrs_) {}
+
DocumentStructureEnumerator::iterator DocumentStructureEnumerator::begin() const {
return this->_docs.cbegin();
}
@@ -55,12 +66,9 @@ BSONArrayBuilder DocumentStructureEnumerator::_getArrayBuilderFromArr(BSONArray
return arrBuilder;
}
-void DocumentStructureEnumerator::_enumerateFixedLenArrs(const std::set<StringData>& fields,
- const std::size_t depthRemaining,
- const std::size_t length,
- BSONArray arr,
- std::vector<BSONArray>* arrs) {
- if (!length) {
+void DocumentStructureEnumerator::_enumerateFixedLenArrs(
+ const DocumentStructureEnumeratorConfig& config, BSONArray arr, std::vector<BSONArray>* arrs) {
+ if (!config.length) {
// Base case: no more room for any other elements.
arrs->push_back(arr);
return;
@@ -68,101 +76,117 @@ void DocumentStructureEnumerator::_enumerateFixedLenArrs(const std::set<StringDa
// Otherwise, go through our choices, similar to the approach to documents.
//
+ DocumentStructureEnumeratorConfig nextElementConfig(config);
+ nextElementConfig.length--;
// Scalar.
BSONArrayBuilder scalarArr = _getArrayBuilderFromArr(arr);
scalarArr.append(0);
- _enumerateFixedLenArrs(fields, depthRemaining, length - 1, scalarArr.arr(), arrs);
+ _enumerateFixedLenArrs(nextElementConfig, scalarArr.arr(), arrs);
- if (depthRemaining <= 0) {
+ if (config.depth <= 0) {
return;
}
+ DocumentStructureEnumeratorConfig nextLayerConfig(config);
+ nextLayerConfig.depth--;
+ nextLayerConfig.length += arr.nFields();
// Subarray.
- std::vector<BSONArray> subArrs =
- _enumerateArrs(fields, depthRemaining - 1, length + arr.nFields());
+ std::vector<BSONArray> subArrs = _enumerateArrs(nextLayerConfig);
for (auto subArr : subArrs) {
BSONArrayBuilder arrayArr = _getArrayBuilderFromArr(arr);
arrayArr.append(subArr);
- _enumerateFixedLenArrs(fields, depthRemaining, length - 1, arrayArr.arr(), arrs);
+ _enumerateFixedLenArrs(nextElementConfig, arrayArr.arr(), arrs);
}
// Document.
- BSONObj blankDoc;
- std::vector<BSONObj> subDocs;
- _enumerateDocs(fields, depthRemaining - 1, length, blankDoc, &subDocs);
- for (auto subDoc : subDocs) {
- BSONArrayBuilder docArr = _getArrayBuilderFromArr(arr);
- docArr.append(subDoc);
- _enumerateFixedLenArrs(fields, depthRemaining, length - 1, docArr.arr(), arrs);
+ if (!config.skipSubDocs) {
+ BSONObj blankDoc;
+ std::vector<BSONObj> subDocs;
+ _enumerateDocs(nextLayerConfig, blankDoc, &subDocs);
+ for (auto subDoc : subDocs) {
+ BSONArrayBuilder docArr = _getArrayBuilderFromArr(arr);
+ docArr.append(subDoc);
+ _enumerateFixedLenArrs(nextElementConfig, docArr.arr(), arrs);
+ }
}
return;
}
-void DocumentStructureEnumerator::_enumerateDocs(const std::set<StringData>& fields,
- const std::size_t depthRemaining,
- const std::size_t length,
+void DocumentStructureEnumerator::_enumerateDocs(const DocumentStructureEnumeratorConfig& config,
BSONObj doc,
std::vector<BSONObj>* docs) {
- if (fields.empty()) {
+ if (config.fields.empty()) {
// Base case: when we have run out of fields to use
docs->push_back(doc);
return;
}
// Create a copy of the fields we have.
- std::set<StringData> remainingFields(fields);
+ std::set<StringData> remainingFields(config.fields);
// Pop the first field arbitrarily.
StringData field = *remainingFields.begin();
remainingFields.erase(remainingFields.begin());
+ DocumentStructureEnumeratorConfig nextFieldConfig(config);
+ nextFieldConfig.fields = remainingFields;
+
// Branch off depending on the choice.
//
// Scalar.
BSONObjBuilder scalarDoc(doc);
scalarDoc.append(field, 0);
- _enumerateDocs(remainingFields, depthRemaining, length, scalarDoc.obj(), docs);
+ _enumerateDocs(nextFieldConfig, scalarDoc.obj(), docs);
// Omit the field.
BSONObjBuilder vanishDoc(doc);
- _enumerateDocs(remainingFields, depthRemaining, length, vanishDoc.obj(), docs);
+ _enumerateDocs(nextFieldConfig, vanishDoc.obj(), docs);
- if (depthRemaining <= 0) {
+ if (config.depth <= 0) {
// If we are ever at the deepest level possible, we have no more choices after this.
return;
}
- // Array.
- for (auto subArr : _enumerateArrs(remainingFields, depthRemaining - 1, length)) {
- BSONObjBuilder arrayDoc(doc);
- arrayDoc.append(field, subArr);
- _enumerateDocs(remainingFields, depthRemaining, length, arrayDoc.obj(), docs);
+ DocumentStructureEnumeratorConfig nextLayerConfig(nextFieldConfig);
+ nextLayerConfig.depth--;
+
+ if (!config.skipSubArrs) {
+ // Array.
+ for (auto subArr : _enumerateArrs(nextLayerConfig)) {
+ BSONObjBuilder arrayDoc(doc);
+ arrayDoc.append(field, subArr);
+ _enumerateDocs(nextFieldConfig, arrayDoc.obj(), docs);
+ }
}
// Subdocument.
- BSONObj blankDoc;
- std::vector<BSONObj> subDocs;
- _enumerateDocs(remainingFields, depthRemaining - 1, length, blankDoc, &subDocs);
- for (auto subDoc : subDocs) {
- BSONObjBuilder docDoc(doc);
- docDoc.append(field, subDoc);
- _enumerateDocs(remainingFields, depthRemaining, length, docDoc.obj(), docs);
+ if (!config.skipSubDocs) {
+ BSONObj blankDoc;
+ std::vector<BSONObj> subDocs;
+ _enumerateDocs(nextLayerConfig, blankDoc, &subDocs);
+ for (auto subDoc : subDocs) {
+ BSONObjBuilder docDoc(doc);
+ docDoc.append(field, subDoc);
+ _enumerateDocs(nextFieldConfig, docDoc.obj(), docs);
+ }
}
}
std::vector<BSONArray> DocumentStructureEnumerator::_enumerateArrs(
- const std::set<StringData>& fields, const std::size_t depth, const std::size_t length) {
+ const DocumentStructureEnumeratorConfig& config) {
std::vector<BSONArray> arrs;
// We enumerate arrays of each possible length independently of each other to avoid having to
// account for how different omissions of elements in an array are equivalent to each other.
// For example, we'd otherwise need to treat omitting the first element and adding x as distinct
// from adding x and omitting the second element since both yield an array containing only the
// element x. Without this, we will enumerate duplicate arrays.
- for (std::size_t i = 0; i <= length; i++) {
+ for (std::size_t i = 0; i <= config.length; i++) {
BSONArray emptyArr;
- _enumerateFixedLenArrs(fields, depth, i, emptyArr, &arrs);
+ DocumentStructureEnumeratorConfig nextConfig(config);
+ nextConfig.length = i;
+ _enumerateFixedLenArrs(nextConfig, emptyArr, &arrs);
}
return arrs;
@@ -171,18 +195,16 @@ std::vector<BSONArray> DocumentStructureEnumerator::_enumerateArrs(
std::vector<BSONObj> DocumentStructureEnumerator::enumerateDocs() const {
BSONObj startDoc;
std::vector<BSONObj> docs;
- _enumerateDocs(this->_fields, this->_depth, this->_length, startDoc, &docs);
+ _enumerateDocs(this->_config, startDoc, &docs);
return docs;
}
std::vector<BSONArray> DocumentStructureEnumerator::enumerateArrs() const {
- return _enumerateArrs(this->_fields, this->_depth, this->_length);
+ return _enumerateArrs(this->_config);
}
-DocumentStructureEnumerator::DocumentStructureEnumerator(std::set<StringData> fields,
- std::size_t depth,
- std::size_t length)
- : _fields(std::move(fields)), _depth(depth), _length(length) {
+DocumentStructureEnumerator::DocumentStructureEnumerator(DocumentStructureEnumeratorConfig config)
+ : _config(std::move(config)) {
this->_docs = enumerateDocs();
}
} // namespace mongo
diff --git a/src/mongo/db/repl/idempotency_document_structure.h b/src/mongo/db/repl/idempotency_document_structure.h
index 04f24952e3e..1ed964951c0 100644
--- a/src/mongo/db/repl/idempotency_document_structure.h
+++ b/src/mongo/db/repl/idempotency_document_structure.h
@@ -39,11 +39,25 @@ namespace mongo {
class BSONArrayBuilder;
class StringData;
+struct DocumentStructureEnumeratorConfig {
+ DocumentStructureEnumeratorConfig(std::set<StringData> fields_,
+ size_t depth_,
+ size_t length_,
+ bool skipSubDocs_ = false,
+ bool skipSubArrs_ = false);
+
+ std::set<StringData> fields = {};
+ size_t depth = 0;
+ size_t length = 0;
+ const bool skipSubDocs = false;
+ const bool skipSubArrs = false;
+};
+
class DocumentStructureEnumerator {
public:
using iterator = std::vector<BSONObj>::const_iterator;
- DocumentStructureEnumerator(std::set<StringData> fields, std::size_t depth, std::size_t length);
+ explicit DocumentStructureEnumerator(DocumentStructureEnumeratorConfig config);
iterator begin() const;
@@ -58,26 +72,18 @@ public:
private:
static BSONArrayBuilder _getArrayBuilderFromArr(BSONArray arr);
- static void _enumerateFixedLenArrs(const std::set<StringData>& fields,
- const std::size_t depthRemaining,
- const std::size_t length,
+ static void _enumerateFixedLenArrs(const DocumentStructureEnumeratorConfig& config,
BSONArray arr,
std::vector<BSONArray>* arrs);
- static void _enumerateDocs(const std::set<StringData>& fields,
- const std::size_t depthRemaining,
- const std::size_t length,
+ static void _enumerateDocs(const DocumentStructureEnumeratorConfig& config,
BSONObj doc,
std::vector<BSONObj>* docs);
- static std::vector<BSONArray> _enumerateArrs(const std::set<StringData>& fields,
- const std::size_t depth,
- const std::size_t length);
+ static std::vector<BSONArray> _enumerateArrs(const DocumentStructureEnumeratorConfig& config);
- const std::set<StringData> _fields;
- const std::size_t _depth = 0;
- const std::size_t _length = 0;
+ const DocumentStructureEnumeratorConfig _config;
std::vector<BSONObj> _docs;
};
diff --git a/src/mongo/db/repl/idempotency_document_structure_test.cpp b/src/mongo/db/repl/idempotency_document_structure_test.cpp
index 3b0aa85f2bf..9a024d2032a 100644
--- a/src/mongo/db/repl/idempotency_document_structure_test.cpp
+++ b/src/mongo/db/repl/idempotency_document_structure_test.cpp
@@ -28,27 +28,32 @@
#include "mongo/platform/basic.h"
-#include "mongo/bson/bsonmisc.h"
-#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/bson/json.h"
+#include "mongo/db/jsobj.h"
#include "mongo/db/repl/idempotency_document_structure.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
namespace {
-std::vector<BSONObj> getEnumeratedDocs(std::set<StringData> fields, size_t depth, size_t length) {
- DocumentStructureEnumerator enumerator(fields, depth, length);
+std::vector<BSONObj> getEnumeratedDocs(DocumentStructureEnumeratorConfig config) {
+ DocumentStructureEnumerator enumerator(config);
return enumerator.getDocs();
}
TEST(DocGenTest, NumDocsIsCorrect) {
- std::vector<BSONObj> docs = getEnumeratedDocs({"a", "b"}, 2, 1);
+ std::vector<BSONObj> docs = getEnumeratedDocs({{"a", "b"}, 2, 1, false, false});
ASSERT_EQUALS(docs.size(), 104U);
+ docs = getEnumeratedDocs({{"a", "b"}, 2, 1, true, false});
+ ASSERT_EQUALS(docs.size(), 36U);
+ docs = getEnumeratedDocs({{"a", "b"}, 2, 1, false, true});
+ ASSERT_EQUALS(docs.size(), 15U);
+ docs = getEnumeratedDocs({{"a", "b"}, 2, 1, true, true});
+ ASSERT_EQUALS(docs.size(), 4U);
}
TEST(DocGenTest, NoDuplicateDocs) {
- std::vector<BSONObj> docs = getEnumeratedDocs({"a", "b"}, 2, 1);
+ std::vector<BSONObj> docs = getEnumeratedDocs({{"a", "b"}, 2, 1});
for (size_t i = 0; i < docs.size(); i++) {
for (size_t j = i + 1; j < docs.size(); j++) {
if (docs[i].binaryEqual(docs[j])) {
@@ -66,7 +71,7 @@ TEST(DocGenTest, SomePreChosenDocExists) {
std::set<StringData> fields{"a", "b"};
size_t depth = 2;
size_t length = 1;
- DocumentStructureEnumerator enumerator(fields, depth, length);
+ DocumentStructureEnumerator enumerator({fields, depth, length});
BSONObj start;
bool docFound = false;
for (auto doc : enumerator) {
@@ -108,8 +113,6 @@ void testEnumeratedDocsAreCorrect(const std::vector<BSONObj>& enumeratedDocs,
}
TEST(DocGenTest, EntireCollectionExistsABDepth2Length0) {
- // Although I could re-use some of these BSONObj (e.g. doc2 inside doc1), I think maintaining
- // the order demonstrates something about our enumeration path that is valuable.
std::vector<BSONObj> expectedDocs;
expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
expectedDocs.push_back(fromjson("{'a' : 0 }"));
@@ -140,13 +143,60 @@ TEST(DocGenTest, EntireCollectionExistsABDepth2Length0) {
expectedDocs.push_back(fromjson("{'a' : {'b' : {}}, 'b' : []}"));
expectedDocs.push_back(fromjson("{'a' : {'b' : {}}, 'b' : {}}"));
- auto enumeratedDocs = getEnumeratedDocs({"a", "b"}, 2, 0);
- testEnumeratedDocsAreCorrect(expectedDocs, enumeratedDocs);
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 2, 0});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth2Length0ArrsDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0 }"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+ expectedDocs.push_back(fromjson("{'b' : {} }"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}, 'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {}, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {}, 'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : {}}, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : {}}}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : {}}, 'b' : {}}"));
+
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 2, 0, false, true});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth2Length0DocsDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0 }"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : []}"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+ expectedDocs.push_back(fromjson("{'b' : [] }"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : 0 }"));
+ expectedDocs.push_back(fromjson("{'a' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : []}"));
+
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 2, 0, true, false});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth2Length0BothDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0 }"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 2, 0, true, true});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
}
TEST(DocGenTest, EntireCollectionExistsABDepth1Length2) {
- // Although we could re-use some of these BSONObj (e.g. doc2 inside doc1), we think maintaining
- // the order demonstrates something about our enumeration order that is valuable.
std::vector<BSONObj> expectedDocs;
expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
expectedDocs.push_back(fromjson("{'a' : 0}"));
@@ -191,24 +241,86 @@ TEST(DocGenTest, EntireCollectionExistsABDepth1Length2) {
expectedDocs.push_back(fromjson("{'a' : {}, 'b' : [0, 0]}"));
expectedDocs.push_back(fromjson("{'a' : {}, 'b' : {}}"));
- auto enumeratedDocs = getEnumeratedDocs({"a", "b"}, 1, 2);
- testEnumeratedDocsAreCorrect(expectedDocs, enumeratedDocs);
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 1, 2});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth1Length2ArrsDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+ expectedDocs.push_back(fromjson("{'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}}"));
+ expectedDocs.push_back(fromjson("{'a' : {'b' : 0}, 'b' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {}, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : {}}"));
+ expectedDocs.push_back(fromjson("{'a' : {}, 'b' : {}}"));
+
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 1, 2, false, true});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth1Length2DocsDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : [0]}"));
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : [0, 0]}"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+ expectedDocs.push_back(fromjson("{'b' : []}"));
+ expectedDocs.push_back(fromjson("{'b' : [0]}"));
+ expectedDocs.push_back(fromjson("{'b' : [0, 0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : [0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [], 'b' : [0, 0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0], 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : [0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0], 'b' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : [0], 'b' : [0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0], 'b' : [0, 0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0, 0], 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : [0, 0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0, 0], 'b' : []}"));
+ expectedDocs.push_back(fromjson("{'a' : [0, 0], 'b' : [0]}"));
+ expectedDocs.push_back(fromjson("{'a' : [0, 0], 'b' : [0, 0]}"));
+
+ auto enumeratedDocs = getEnumeratedDocs({{"a", "b"}, 1, 2, true, false});
+ testEnumeratedDocsAreCorrect(enumeratedDocs, expectedDocs);
+}
+
+TEST(DocGenTest, EntireCollectionExistsABDepth1Length2BothDisabled) {
+ std::vector<BSONObj> expectedDocs;
+ expectedDocs.push_back(fromjson("{'a' : 0, 'b' : 0}"));
+ expectedDocs.push_back(fromjson("{'a' : 0}"));
+ expectedDocs.push_back(fromjson("{'b' : 0}"));
+ expectedDocs.push_back(fromjson("{}"));
+
+ DocumentStructureEnumerator enumerator({{"a", "b"}, 1, 2, true, true});
+ testEnumeratedDocsAreCorrect(enumerator.getDocs(), expectedDocs);
}
TEST(EnumerateArrsTest, NumArrsIsCorrect) {
std::set<StringData> fields{"a"};
size_t depth = 2;
size_t length = 2;
- DocumentStructureEnumerator enumerator(fields, depth, length);
+ DocumentStructureEnumerator enumerator({fields, depth, length});
std::vector<BSONArray> arrs = enumerator.enumerateArrs();
- ASSERT_EQUALS(arrs.size(), 2365U);
+ ASSERT_EQUALS(arrs.size(), 2414U);
}
TEST(EnumerateArrsTest, NoDuplicateArrs) {
std::set<StringData> fields{"a", "b"};
size_t depth = 2;
size_t length = 2;
- DocumentStructureEnumerator enumerator(fields, depth, length);
+ DocumentStructureEnumerator enumerator({fields, depth, length});
BSONObj start;
std::vector<BSONArray> arrs = enumerator.enumerateArrs();
for (size_t i = 0; i < arrs.size(); i++) {
diff --git a/src/mongo/db/repl/idempotency_sequence.cpp b/src/mongo/db/repl/idempotency_sequence.cpp
deleted file mode 100644
index dca13e97fee..00000000000
--- a/src/mongo/db/repl/idempotency_sequence.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (C) 2017 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/repl/idempotency_sequence.h"
-
-namespace mongo {
-std::vector<BSONObj> SequenceGenerator::generateBatch(std::size_t count) const {
- std::vector<BSONObj> objs;
- for (std::size_t i = 0; i < count; i++) {
- objs.push_back(generate());
- }
-
- return objs;
-}
-} // namespace mongo
diff --git a/src/mongo/db/repl/idempotency_sequence.h b/src/mongo/db/repl/idempotency_sequence.h
index 90d143644e6..012be9754b8 100644
--- a/src/mongo/db/repl/idempotency_sequence.h
+++ b/src/mongo/db/repl/idempotency_sequence.h
@@ -40,8 +40,6 @@ public:
SequenceGenerator() = default;
virtual BSONObj generate() const = 0;
-
- std::vector<BSONObj> generateBatch(const std::size_t count) const;
};
} // namespace mongo
diff --git a/src/mongo/db/repl/idempotency_update_sequence.cpp b/src/mongo/db/repl/idempotency_update_sequence.cpp
index 6131d78a016..a3bf32f2d9a 100644
--- a/src/mongo/db/repl/idempotency_update_sequence.cpp
+++ b/src/mongo/db/repl/idempotency_update_sequence.cpp
@@ -238,7 +238,7 @@ DocumentStructureEnumerator UpdateSequenceGenerator::_getValidEnumeratorForPath(
remainingDepth -= 1;
}
- DocumentStructureEnumerator enumerator(remainingFields, remainingDepth, this->_length);
+ DocumentStructureEnumerator enumerator({remainingFields, remainingDepth, this->_length});
return enumerator;
}