Skip to content

Commit 64b0bf9

Browse files
committed
concurrency issues solved
1 parent 2723a1e commit 64b0bf9

File tree

3 files changed

+37
-57
lines changed

3 files changed

+37
-57
lines changed

include/xrpl/ledger/LedgerIndexMap.h

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
#include <algorithm>
44
#include <mutex>
5+
#include <optional>
56
#include <unordered_map>
7+
#include <utility>
68

79
namespace xrpl {
810

@@ -23,45 +25,19 @@ class LedgerIndexMap
2325
LedgerIndexMap&
2426
operator=(LedgerIndexMap&&) = delete;
2527

26-
Mapped&
27-
operator[](Key const& k)
28-
{
29-
std::lock_guard lock(mutex_);
30-
return data_[k];
31-
}
32-
33-
Mapped&
34-
operator[](Key&& k)
35-
{
36-
std::lock_guard lock(mutex_);
37-
return data_[std::move(k)];
38-
}
39-
40-
[[nodiscard]] Mapped*
41-
get(Key const& k)
42-
{
43-
std::lock_guard lock(mutex_);
44-
auto it = data_.find(k);
45-
return it == data_.end() ? nullptr : &it->second;
46-
}
47-
48-
[[nodiscard]] Mapped const*
28+
[[nodiscard]] std::optional<Mapped>
4929
get(Key const& k) const
5030
{
5131
std::lock_guard lock(mutex_);
5232
auto it = data_.find(k);
53-
return it == data_.end() ? nullptr : &it->second;
33+
return it == data_.end() ? std::nullopt : std::optional<Mapped>{it->second};
5434
}
5535

56-
template <class... Args>
57-
Mapped&
58-
put(Key const& k, Args&&... args)
36+
bool
37+
put(Key const& k, Mapped value)
5938
{
6039
std::lock_guard lock(mutex_);
61-
auto [it, inserted] = data_.try_emplace(k, std::forward<Args>(args)...);
62-
if (!inserted)
63-
it->second = Mapped(std::forward<Args>(args)...);
64-
return it->second;
40+
return data_.insert_or_assign(k, std::move(value)).second;
6541
}
6642

6743
bool
@@ -72,14 +48,14 @@ class LedgerIndexMap
7248
}
7349

7450
std::size_t
75-
size() const noexcept
51+
size() const
7652
{
7753
std::lock_guard lock(mutex_);
7854
return data_.size();
7955
}
8056

8157
bool
82-
empty() const noexcept
58+
empty() const
8359
{
8460
std::lock_guard lock(mutex_);
8561
return data_.empty();

src/tests/libxrpl/ledger/LedgerIndexMap.cpp

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,60 +15,64 @@ TEST(LedgerIndexMap, DefaultEmpty)
1515
TestMap m;
1616
EXPECT_EQ(m.size(), 0);
1717
EXPECT_TRUE(m.empty());
18-
EXPECT_EQ(m.get(42), nullptr);
18+
EXPECT_FALSE(m.get(42).has_value());
1919
EXPECT_FALSE(m.contains(42));
2020
}
2121

22-
TEST(LedgerIndexMap, OperatorBracketInsertsDefault)
22+
TEST(LedgerIndexMap, PutInsertsValue)
2323
{
2424
TestMap m;
25-
auto& v = m[10];
25+
bool inserted = m.put(10, "");
26+
EXPECT_TRUE(inserted);
2627
EXPECT_EQ(m.size(), 1);
2728
EXPECT_TRUE(m.contains(10));
28-
EXPECT_TRUE(v.empty());
29+
auto got = m.get(10);
30+
ASSERT_TRUE(got.has_value());
31+
EXPECT_TRUE(got->empty());
2932
}
3033

31-
TEST(LedgerIndexMap, OperatorBracketRvalueKey)
34+
TEST(LedgerIndexMap, PutWithValue)
3235
{
3336
TestMap m;
34-
int k = 7;
35-
auto& v1 = m[std::move(k)];
36-
v1 = "seven";
37+
bool inserted = m.put(7, "seven");
38+
EXPECT_TRUE(inserted);
3739
EXPECT_EQ(m.size(), 1);
38-
auto* got = m.get(7);
39-
ASSERT_NE(got, nullptr);
40+
auto got = m.get(7);
41+
ASSERT_TRUE(got.has_value());
4042
EXPECT_EQ(*got, "seven");
4143
}
4244

4345
TEST(LedgerIndexMap, InsertThroughPut)
4446
{
4547
TestMap m;
46-
auto& v = m.put(20, "twenty");
47-
EXPECT_EQ(v, "twenty");
48-
auto* got = m.get(20);
49-
ASSERT_NE(got, nullptr);
48+
bool inserted = m.put(20, "twenty");
49+
EXPECT_TRUE(inserted);
50+
auto got = m.get(20);
51+
ASSERT_TRUE(got.has_value());
5052
EXPECT_EQ(*got, "twenty");
5153
EXPECT_EQ(m.size(), 1);
5254
}
5355

5456
TEST(LedgerIndexMap, OverwriteExistingKeyWithPut)
5557
{
5658
TestMap m;
57-
m.put(5, "five");
59+
bool inserted1 = m.put(5, "five");
60+
EXPECT_TRUE(inserted1);
5861
EXPECT_EQ(m.size(), 1);
59-
m.put(5, "FIVE");
62+
bool inserted2 = m.put(5, "FIVE");
63+
EXPECT_FALSE(inserted2); // Not a new insertion, it's an update
6064
EXPECT_EQ(m.size(), 1);
61-
auto* got = m.get(5);
62-
ASSERT_NE(got, nullptr);
65+
auto got = m.get(5);
66+
ASSERT_TRUE(got.has_value());
6367
EXPECT_EQ(*got, "FIVE");
6468
}
6569

6670
TEST(LedgerIndexMap, OnceFoundOneNotFound)
6771
{
6872
TestMap m;
6973
m.put(1, "one");
70-
EXPECT_NE(m.get(1), nullptr);
71-
EXPECT_EQ(m.get(2), nullptr);
74+
EXPECT_TRUE(m.get(1).has_value());
75+
EXPECT_FALSE(m.get(2).has_value());
7276
}
7377

7478
TEST(LedgerIndexMap, TryEraseBeforeNothingToDo)
@@ -174,8 +178,8 @@ TEST(LedgerIndexMap, RehashDoesNotLoseEntries)
174178

175179
for (int k = 0; k < 16; ++k)
176180
{
177-
auto* v = m.get(k);
178-
ASSERT_NE(v, nullptr);
181+
auto v = m.get(k);
182+
ASSERT_TRUE(v.has_value());
179183
EXPECT_EQ(*v, "v" + std::to_string(k));
180184
}
181185

src/xrpld/app/ledger/LedgerHistory.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ LedgerHistory::insert(std::shared_ptr<Ledger const> const& ledger, bool validate
3434

3535
bool const alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(ledger->header().hash, ledger);
3636
if (validated)
37-
mLedgersByIndex[ledger->header().seq] = ledger->header().hash;
37+
mLedgersByIndex.put(ledger->header().seq, ledger->header().hash);
3838

3939
return alreadyHad;
4040
}
@@ -67,7 +67,7 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
6767
// Add this ledger to the local tracking by index
6868
XRPL_ASSERT(ret->isImmutable(), "xrpl::LedgerHistory::getLedgerBySeq : immutable result ledger");
6969
m_ledgers_by_hash.canonicalize_replace_client(ret->header().hash, ret);
70-
mLedgersByIndex[ret->header().seq] = ret->header().hash;
70+
mLedgersByIndex.put(ret->header().seq, ret->header().hash);
7171
return (ret->header().seq == index) ? ret : nullptr;
7272
}
7373
}

0 commit comments

Comments
 (0)