forked from ad-freiburg/qlever
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BlankNodeManagerTest.cpp
94 lines (79 loc) · 3.34 KB
/
BlankNodeManagerTest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2024, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Author: Moritz Dom ([email protected])
#include <gtest/gtest.h>
#include "gmock/gmock.h"
#include "util/BlankNodeManager.h"
#include "util/GTestHelpers.h"
namespace ad_utility {
// _____________________________________________________________________________
TEST(BlankNodeManager, blockAllocationAndFree) {
BlankNodeManager bnm(0);
EXPECT_TRUE(bnm.usedBlocksSet_.rlock()->empty());
{
// LocalBlankNodeManager allocates a new block
BlankNodeManager::LocalBlankNodeManager lbnm(&bnm);
[[maybe_unused]] uint64_t id = lbnm.getId();
EXPECT_EQ(bnm.usedBlocksSet_.rlock()->size(), 1);
}
// Once the LocalBlankNodeManager is destroyed, all Blocks allocated through
// it are freed/removed from the BlankNodeManager's set.
EXPECT_TRUE(bnm.usedBlocksSet_.rlock()->empty());
// Mock randomIntGenerator to let the block index generation collide.
bnm.randBlockIndex_ = SlowRandomIntGenerator<uint64_t>(0, 1);
[[maybe_unused]] auto _ = bnm.allocateBlock();
for (int i = 0; i < 30; ++i) {
auto block = bnm.allocateBlock();
bnm.usedBlocksSet_.wlock()->erase(block.blockIdx_);
}
}
// _____________________________________________________________________________
TEST(BlankNodeManager, LocalBlankNodeManagerGetID) {
BlankNodeManager bnm(0);
auto l = std::make_shared<BlankNodeManager::LocalBlankNodeManager>(&bnm);
// initially the LocalBlankNodeManager doesn't have any blocks
EXPECT_EQ(l->blocks_->size(), 0);
// A new Block is allocated, if
// no blocks are allocated yet
uint64_t id = l->getId();
EXPECT_EQ(l->blocks_->size(), 1);
EXPECT_TRUE(l->containsBlankNodeIndex(id));
EXPECT_FALSE(l->containsBlankNodeIndex(id + 1));
EXPECT_FALSE(l->containsBlankNodeIndex(id - 1));
// or the ids of the last block are all used
l->blocks_->back().nextIdx_ = id + BlankNodeManager::blockSize_;
id = l->getId();
EXPECT_TRUE(l->containsBlankNodeIndex(id));
EXPECT_EQ(l->blocks_->size(), 2);
// The `LocalBlankNodeManager` still works when recursively merged.
std::vector itSelf{l};
l->mergeWith(itSelf);
EXPECT_TRUE(l->containsBlankNodeIndex(id));
EXPECT_TRUE(l->containsBlankNodeIndex(l->getId()));
EXPECT_EQ(l->blocks_, l->otherBlocks_[0]);
}
// _____________________________________________________________________________
TEST(BlankNodeManager, maxNumOfBlocks) {
// Mock a high `minIndex_` to simulate reduced space in the `usedBlocksSet_`
BlankNodeManager bnm(ValueId::maxIndex - 256 * BlankNodeManager::blockSize_ +
2);
AD_EXPECT_THROW_WITH_MESSAGE(
[[maybe_unused]] auto _ = bnm.allocateBlock(),
::testing::HasSubstr(
"Critical high number of blank node blocks in use:"));
}
// _____________________________________________________________________________
TEST(BlankNodeManager, moveLocalBlankNodeManager) {
// This ensures that the `blocks_` of the `LocalBlankNodeManager` are moved
// correctly, such that they're freed/removed from the `BlankNodeManager`
// set only once.
BlankNodeManager bnm(0);
EXPECT_NO_THROW({
BlankNodeManager::LocalBlankNodeManager l1(&bnm);
auto l2(std::move(l1));
BlankNodeManager::LocalBlankNodeManager l3(&bnm);
l3 = std::move(l2);
});
EXPECT_TRUE(bnm.usedBlocksSet_.rlock()->empty());
}
} // namespace ad_utility