Skip to content

Commit 26b1361

Browse files
committed
core: Expose consume page method for testing
Signed-off-by: Abhijat Malviya <abhijat@dragonflydb.io>
1 parent aba1726 commit 26b1361

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

src/core/page_usage_stats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ class PageUsage {
6969
return unique_pages_.CollectedStats();
7070
}
7171

72-
private:
7372
bool ConsumePageStats(mi_page_usage_stats_t stats);
7473

74+
private:
7575
CollectPageStats collect_stats_{CollectPageStats::NO};
7676
float threshold_;
7777

src/core/page_usage_stats_test.cc

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ extern "C" {
1919
#include "redis/zmalloc.h"
2020
}
2121

22+
using namespace dfly;
23+
2224
class PageUsageStatsTest : public ::testing::Test {
2325
protected:
2426
static void SetUpTestSuite() {
@@ -41,11 +43,11 @@ class PageUsageStatsTest : public ::testing::Test {
4143
}
4244

4345
void SetUp() override {
44-
score_map_ = std::make_unique<dfly::ScoreMap>(&m_);
45-
sorted_map_ = std::make_unique<dfly::detail::SortedMap>(&m_);
46-
string_set_ = std::make_unique<dfly::StringSet>(&m_);
47-
string_map_ = std::make_unique<dfly::StringMap>(&m_);
48-
dfly::SmallString::InitThreadLocal(m_.heap());
46+
score_map_ = std::make_unique<ScoreMap>(&m_);
47+
sorted_map_ = std::make_unique<detail::SortedMap>(&m_);
48+
string_set_ = std::make_unique<StringSet>(&m_);
49+
string_map_ = std::make_unique<StringMap>(&m_);
50+
SmallString::InitThreadLocal(m_.heap());
4951
}
5052

5153
void TearDown() override {
@@ -57,12 +59,12 @@ class PageUsageStatsTest : public ::testing::Test {
5759
EXPECT_EQ(zmalloc_used_memory_tl, 0);
5860
}
5961

60-
dfly::MiMemoryResource m_;
61-
std::unique_ptr<dfly::ScoreMap> score_map_;
62-
std::unique_ptr<dfly::detail::SortedMap> sorted_map_;
63-
std::unique_ptr<dfly::StringSet> string_set_;
64-
std::unique_ptr<dfly::StringMap> string_map_;
65-
dfly::SmallString small_string_{};
62+
MiMemoryResource m_;
63+
std::unique_ptr<ScoreMap> score_map_;
64+
std::unique_ptr<detail::SortedMap> sorted_map_;
65+
std::unique_ptr<StringSet> string_set_;
66+
std::unique_ptr<StringMap> string_map_;
67+
SmallString small_string_{};
6668
};
6769

6870
bool PageCannotRealloc(mi_page_usage_stats_t s) {
@@ -80,7 +82,7 @@ TEST_F(PageUsageStatsTest, Defrag) {
8082
small_string_.Assign("small-string");
8183

8284
{
83-
dfly::PageUsage p{dfly::CollectPageStats::YES, 0.1};
85+
PageUsage p{CollectPageStats::YES, 0.1};
8486
score_map_->begin().ReallocIfNeeded(&p);
8587
sorted_map_->DefragIfNeeded(&p);
8688
string_set_->begin().ReallocIfNeeded(&p);
@@ -92,7 +94,7 @@ TEST_F(PageUsageStatsTest, Defrag) {
9294
}
9395

9496
{
95-
dfly::PageUsage p{dfly::CollectPageStats::NO, 0.1};
97+
PageUsage p{CollectPageStats::NO, 0.1};
9698
score_map_->begin().ReallocIfNeeded(&p);
9799
sorted_map_->DefragIfNeeded(&p);
98100
string_set_->begin().ReallocIfNeeded(&p);
@@ -101,3 +103,68 @@ TEST_F(PageUsageStatsTest, Defrag) {
101103
EXPECT_EQ(p.CollectedStats().pages_scanned, 0);
102104
}
103105
}
106+
107+
TEST_F(PageUsageStatsTest, StatCollection) {
108+
constexpr auto threshold = 0.5;
109+
PageUsage p{CollectPageStats::YES, threshold};
110+
for (size_t i = 0; i < 10000; ++i) {
111+
p.ConsumePageStats({.page_address = uintptr_t{100000 + i},
112+
.block_size = 1,
113+
.capacity = 100,
114+
.reserved = 100,
115+
.used = 65,
116+
.flags = 0});
117+
}
118+
119+
for (size_t i = 0; i < 2000; ++i) {
120+
p.ConsumePageStats({.page_address = uintptr_t{200000 + i},
121+
.block_size = 1,
122+
.capacity = 100,
123+
.reserved = 100,
124+
.used = 85,
125+
.flags = 0});
126+
}
127+
128+
for (size_t i = 0; i < 1000; ++i) {
129+
p.ConsumePageStats({.page_address = uintptr_t{300000 + i},
130+
.block_size = 1,
131+
.capacity = 100,
132+
.reserved = 100,
133+
.used = 89,
134+
.flags = 0});
135+
}
136+
137+
constexpr auto page_count_per_flag = 150;
138+
// allow for collisions in filter
139+
constexpr auto expected_min_count = 140;
140+
141+
auto start = 0;
142+
for (const uint8_t flag : {MI_DFLY_PAGE_FULL, MI_DFLY_PAGE_USED_FOR_MALLOC, MI_DFLY_HEAP_MISMATCH,
143+
MI_DFLY_PAGE_BELOW_THRESHOLD}) {
144+
for (size_t i = 0; i < page_count_per_flag; ++i) {
145+
p.ConsumePageStats({.page_address = uintptr_t{start + i},
146+
.block_size = 1,
147+
.capacity = 100,
148+
.reserved = 100,
149+
.used = 100,
150+
.flags = flag});
151+
}
152+
start += page_count_per_flag;
153+
}
154+
155+
CollectedPageStats st;
156+
st.Merge(p.CollectedStats(), 1);
157+
158+
EXPECT_GT(st.pages_scanned, 12000);
159+
EXPECT_GT(st.pages_full, expected_min_count);
160+
EXPECT_GT(st.pages_reserved_for_malloc, expected_min_count);
161+
EXPECT_GT(st.pages_marked_for_realloc, expected_min_count);
162+
163+
const auto usage = st.shard_wide_summary;
164+
165+
EXPECT_EQ(usage.size(), 1);
166+
EXPECT_TRUE(usage.contains(1));
167+
168+
const CollectedPageStats::ShardUsageSummary expected{{50, 65}, {90, 85}, {99, 89}};
169+
EXPECT_EQ(usage.at(1), expected);
170+
}

0 commit comments

Comments
 (0)