summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2020-05-07 17:03:10 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-11 17:39:41 +0000
commite6dcc106ab333e7f2a96ea9f92d0c9fad6ff0da7 (patch)
treefa15bb8b9234afb07dc92b29bb170760f15425db
parentc2479d57f11528846cd4b87cd62cd75e5e2eebfc (diff)
downloadmongo-e6dcc106ab333e7f2a96ea9f92d0c9fad6ff0da7.tar.gz
SERVER-48034 Fix bug in radix store merge3() when the nodes just diff in the data they hold
-rw-r--r--src/mongo/db/storage/biggie/store.h5
-rw-r--r--src/mongo/db/storage/biggie/store_test.cpp16
2 files changed, 19 insertions, 2 deletions
diff --git a/src/mongo/db/storage/biggie/store.h b/src/mongo/db/storage/biggie/store.h
index a09b5b49b63..7ae2087617c 100644
--- a/src/mongo/db/storage/biggie/store.h
+++ b/src/mongo/db/storage/biggie/store.h
@@ -1404,13 +1404,14 @@ private:
if (node->isLeaf() && baseNode->isLeaf() && otherNode->isLeaf())
throw merge_conflict_exception();
- // If the keys are all the exact same, then we can keep recursing.
+ // If the keys and data are all the exact same, then we can keep recursing.
// Otherwise, we manually resolve the differences element by element. The
// structure of compressed radix tries makes it difficult to compare the
// trees node by node, hence the reason for resolving these differences
// element by element.
if (node->_trieKey == baseNode->_trieKey &&
- baseNode->_trieKey == otherNode->_trieKey) {
+ baseNode->_trieKey == otherNode->_trieKey && node->_data == baseNode->_data &&
+ baseNode->_data == otherNode->_data) {
_merge3Helper(node, baseNode, otherNode, context, trieKeyIndex);
} else {
_mergeResolveConflict(node, baseNode, otherNode);
diff --git a/src/mongo/db/storage/biggie/store_test.cpp b/src/mongo/db/storage/biggie/store_test.cpp
index e75a81bc7c7..14f23d9551c 100644
--- a/src/mongo/db/storage/biggie/store_test.cpp
+++ b/src/mongo/db/storage/biggie/store_test.cpp
@@ -1575,6 +1575,22 @@ TEST_F(RadixStoreTest, MergeInsertionDeletionModification) {
ASSERT_EQ(itemsVisited, 4);
}
+TEST_F(RadixStoreTest, MergeOnlyDataDifferenceInBranch) {
+ baseStore.insert({"a", ""});
+ baseStore.insert({"aa", ""});
+
+ otherStore = baseStore;
+ otherStore.update({"a", "a"});
+
+ thisStore = baseStore;
+ thisStore.update({"aa", "b"});
+ thisStore.merge3(baseStore, otherStore);
+
+ expected.insert({"a", "a"});
+ expected.insert({"aa", "b"});
+ ASSERT_TRUE(thisStore == expected);
+}
+
TEST_F(RadixStoreTest, MergeConflictingModifications) {
value_type value1 = std::make_pair("foo", "1");
value_type value2 = std::make_pair("foo", "2");