1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-05 21:34:57 +00:00

AK: Set IntrusiveRBTree Node key on insertion instead of construction

This makes the API look much nicer.
This commit is contained in:
Idan Horowitz 2021-09-08 03:07:34 +03:00
parent 1db9250766
commit cb9720baab
3 changed files with 33 additions and 37 deletions

View File

@ -48,10 +48,11 @@ public:
return node_to_value(*node);
}
void insert(V& value)
void insert(K key, V& value)
{
auto& node = value.*member;
VERIFY(!node.m_in_tree);
node.key = key;
BaseTree::insert(&node);
if constexpr (!TreeNode::IsRaw)
node.m_self.reference = &value; // Note: Self-reference ensures that the object will keep a ref to itself when the Container is a smart pointer.
@ -165,11 +166,6 @@ namespace Detail {
template<Integral K, typename V, typename Container>
class IntrusiveRedBlackTreeNode : public BaseRedBlackTree<K>::Node {
public:
IntrusiveRedBlackTreeNode(K key)
: BaseRedBlackTree<K>::Node(key)
{
}
~IntrusiveRedBlackTreeNode()
{
VERIFY(!is_in_tree());

View File

@ -38,6 +38,9 @@ public:
: key(key)
{
}
Node()
{
}
virtual ~Node() {};
};

View File

@ -12,9 +12,8 @@
class IntrusiveTest {
public:
IntrusiveTest(int key, int value)
: m_tree_node(key)
, m_some_value(value)
IntrusiveTest(int value)
: m_some_value(value)
{
}
@ -33,12 +32,12 @@ TEST_CASE(construct)
TEST_CASE(ints)
{
IntrusiveRBTree test;
IntrusiveTest first { 1, 10 };
test.insert(first);
IntrusiveTest second { 3, 20 };
test.insert(second);
IntrusiveTest third { 2, 30 };
test.insert(third);
IntrusiveTest first { 10 };
test.insert(1, first);
IntrusiveTest second { 20 };
test.insert(3, second);
IntrusiveTest third { 30 };
test.insert(2, third);
EXPECT_EQ(test.size(), 3u);
EXPECT_EQ(test.find(3)->m_some_value, 20);
EXPECT_EQ(test.find(2)->m_some_value, 30);
@ -53,12 +52,12 @@ TEST_CASE(ints)
TEST_CASE(largest_smaller_than)
{
IntrusiveRBTree test;
IntrusiveTest first { 1, 10 };
test.insert(first);
IntrusiveTest second { 11, 20 };
test.insert(second);
IntrusiveTest third { 21, 30 };
test.insert(third);
IntrusiveTest first { 10 };
test.insert(1, first);
IntrusiveTest second { 20 };
test.insert(11, second);
IntrusiveTest third { 30 };
test.insert(21, third);
EXPECT_EQ(test.size(), 3u);
EXPECT_EQ(test.find_largest_not_above(3)->m_some_value, 10);
EXPECT_EQ(test.find_largest_not_above(17)->m_some_value, 20);
@ -86,8 +85,8 @@ TEST_CASE(key_ordered_iteration)
// insert random keys
for (size_t i = 0; i < amount; i++) {
auto entry = make<IntrusiveTest>(keys[i], keys[i]);
test.insert(*entry);
auto entry = make<IntrusiveTest>(keys[i]);
test.insert(keys[i], *entry);
m_entries.append(move(entry));
}
@ -108,8 +107,8 @@ TEST_CASE(clear)
IntrusiveRBTree test;
NonnullOwnPtrVector<IntrusiveTest> m_entries;
for (size_t i = 0; i < 1000; i++) {
auto entry = make<IntrusiveTest>(i, i);
test.insert(*entry);
auto entry = make<IntrusiveTest>(i);
test.insert(i, *entry);
m_entries.append(move(entry));
}
test.clear();
@ -118,8 +117,7 @@ TEST_CASE(clear)
class IntrusiveRefPtrTest : public RefCounted<IntrusiveRefPtrTest> {
public:
IntrusiveRefPtrTest(int key)
: m_tree_node(key)
IntrusiveRefPtrTest()
{
}
@ -129,11 +127,11 @@ using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveRefPtrTest, Re
TEST_CASE(intrusive_ref_ptr_no_ref_leaks)
{
auto item = adopt_ref(*new IntrusiveRefPtrTest(0));
auto item = adopt_ref(*new IntrusiveRefPtrTest());
EXPECT_EQ(1u, item->ref_count());
IntrusiveRefPtrRBTree ref_tree;
ref_tree.insert(*item);
ref_tree.insert(0, *item);
EXPECT_EQ(2u, item->ref_count());
ref_tree.remove(0);
@ -142,11 +140,11 @@ TEST_CASE(intrusive_ref_ptr_no_ref_leaks)
TEST_CASE(intrusive_ref_ptr_clear)
{
auto item = adopt_ref(*new IntrusiveRefPtrTest(0));
auto item = adopt_ref(*new IntrusiveRefPtrTest());
EXPECT_EQ(1u, item->ref_count());
IntrusiveRefPtrRBTree ref_tree;
ref_tree.insert(*item);
ref_tree.insert(0, *item);
EXPECT_EQ(2u, item->ref_count());
ref_tree.clear();
@ -155,12 +153,12 @@ TEST_CASE(intrusive_ref_ptr_clear)
TEST_CASE(intrusive_ref_ptr_destructor)
{
auto item = adopt_ref(*new IntrusiveRefPtrTest(0));
auto item = adopt_ref(*new IntrusiveRefPtrTest());
EXPECT_EQ(1u, item->ref_count());
{
IntrusiveRefPtrRBTree ref_tree;
ref_tree.insert(*item);
ref_tree.insert(0, *item);
EXPECT_EQ(2u, item->ref_count());
}
@ -169,8 +167,7 @@ TEST_CASE(intrusive_ref_ptr_destructor)
class IntrusiveNonnullRefPtrTest : public RefCounted<IntrusiveNonnullRefPtrTest> {
public:
IntrusiveNonnullRefPtrTest(int key)
: m_tree_node(key)
IntrusiveNonnullRefPtrTest()
{
}
@ -180,11 +177,11 @@ using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveNonnull
TEST_CASE(intrusive_nonnull_ref_ptr_intrusive)
{
auto item = adopt_ref(*new IntrusiveNonnullRefPtrTest(0));
auto item = adopt_ref(*new IntrusiveNonnullRefPtrTest());
EXPECT_EQ(1u, item->ref_count());
IntrusiveNonnullRefPtrRBTree nonnull_ref_tree;
nonnull_ref_tree.insert(*item);
nonnull_ref_tree.insert(0, *item);
EXPECT_EQ(2u, item->ref_count());
EXPECT(!nonnull_ref_tree.is_empty());