From e6dcc106ab333e7f2a96ea9f92d0c9fad6ff0da7 Mon Sep 17 00:00:00 2001 From: Henrik Edin Date: Thu, 7 May 2020 17:03:10 -0400 Subject: SERVER-48034 Fix bug in radix store merge3() when the nodes just diff in the data they hold --- src/mongo/db/storage/biggie/store.h | 5 +++-- src/mongo/db/storage/biggie/store_test.cpp | 16 ++++++++++++++++ 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"); -- cgit v1.2.1