diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2021-09-08 01:57:49 +0300 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2021-09-08 19:17:07 +0300 |
commit | 1db925076641526a3ef5c4c41fc94f0c9d3361ee (patch) | |
tree | 58805b325d92247ed6c8bb1ae1a32cb0d7461a6d /Tests | |
parent | 7bb3b2839eaa5b138af6527bb22053dc11776a1a (diff) | |
download | serenity-1db925076641526a3ef5c4c41fc94f0c9d3361ee.zip |
AK: Make IntrusiveRedBlackTree capable of holding non-raw pointers
This is completely based on e4412f1f599bea034dea608b8c7dcc4408d90066
and will allow us to convert some AK::HashMap users in the kernel.
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/AK/TestIntrusiveRedBlackTree.cpp | 91 |
1 files changed, 85 insertions, 6 deletions
diff --git a/Tests/AK/TestIntrusiveRedBlackTree.cpp b/Tests/AK/TestIntrusiveRedBlackTree.cpp index 207b026cec..3ae0c7fe56 100644 --- a/Tests/AK/TestIntrusiveRedBlackTree.cpp +++ b/Tests/AK/TestIntrusiveRedBlackTree.cpp @@ -18,20 +18,21 @@ public: { } - IntrusiveRedBlackTreeNode<int> m_tree_node; + IntrusiveRedBlackTreeNode<int, IntrusiveTest, RawPtr<IntrusiveTest>> m_tree_node; int m_some_value; }; +using IntrusiveRBTree = IntrusiveRedBlackTree<int, IntrusiveTest, RawPtr<IntrusiveTest>, &IntrusiveTest::m_tree_node>; TEST_CASE(construct) { - IntrusiveRedBlackTree<int, IntrusiveTest, &IntrusiveTest::m_tree_node> empty; + IntrusiveRBTree empty; EXPECT(empty.is_empty()); EXPECT(empty.size() == 0); } TEST_CASE(ints) { - IntrusiveRedBlackTree<int, IntrusiveTest, &IntrusiveTest::m_tree_node> test; + IntrusiveRBTree test; IntrusiveTest first { 1, 10 }; test.insert(first); IntrusiveTest second { 3, 20 }; @@ -51,7 +52,7 @@ TEST_CASE(ints) TEST_CASE(largest_smaller_than) { - IntrusiveRedBlackTree<int, IntrusiveTest, &IntrusiveTest::m_tree_node> test; + IntrusiveRBTree test; IntrusiveTest first { 1, 10 }; test.insert(first); IntrusiveTest second { 11, 20 }; @@ -71,7 +72,7 @@ TEST_CASE(largest_smaller_than) TEST_CASE(key_ordered_iteration) { constexpr auto amount = 10000; - IntrusiveRedBlackTree<int, IntrusiveTest, &IntrusiveTest::m_tree_node> test; + IntrusiveRBTree test; NonnullOwnPtrVector<IntrusiveTest> m_entries; Array<int, amount> keys {}; @@ -104,7 +105,7 @@ TEST_CASE(key_ordered_iteration) TEST_CASE(clear) { - IntrusiveRedBlackTree<int, IntrusiveTest, &IntrusiveTest::m_tree_node> test; + IntrusiveRBTree test; NonnullOwnPtrVector<IntrusiveTest> m_entries; for (size_t i = 0; i < 1000; i++) { auto entry = make<IntrusiveTest>(i, i); @@ -114,3 +115,81 @@ TEST_CASE(clear) test.clear(); EXPECT_EQ(test.size(), 0u); } + +class IntrusiveRefPtrTest : public RefCounted<IntrusiveRefPtrTest> { +public: + IntrusiveRefPtrTest(int key) + : m_tree_node(key) + { + } + + IntrusiveRedBlackTreeNode<int, IntrusiveRefPtrTest, RefPtr<IntrusiveRefPtrTest>> m_tree_node; +}; +using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveRefPtrTest, RefPtr<IntrusiveRefPtrTest>, &IntrusiveRefPtrTest::m_tree_node>; + +TEST_CASE(intrusive_ref_ptr_no_ref_leaks) +{ + auto item = adopt_ref(*new IntrusiveRefPtrTest(0)); + EXPECT_EQ(1u, item->ref_count()); + IntrusiveRefPtrRBTree ref_tree; + + ref_tree.insert(*item); + EXPECT_EQ(2u, item->ref_count()); + + ref_tree.remove(0); + EXPECT_EQ(1u, item->ref_count()); +} + +TEST_CASE(intrusive_ref_ptr_clear) +{ + auto item = adopt_ref(*new IntrusiveRefPtrTest(0)); + EXPECT_EQ(1u, item->ref_count()); + IntrusiveRefPtrRBTree ref_tree; + + ref_tree.insert(*item); + EXPECT_EQ(2u, item->ref_count()); + + ref_tree.clear(); + EXPECT_EQ(1u, item->ref_count()); +} + +TEST_CASE(intrusive_ref_ptr_destructor) +{ + auto item = adopt_ref(*new IntrusiveRefPtrTest(0)); + EXPECT_EQ(1u, item->ref_count()); + + { + IntrusiveRefPtrRBTree ref_tree; + ref_tree.insert(*item); + EXPECT_EQ(2u, item->ref_count()); + } + + EXPECT_EQ(1u, item->ref_count()); +} + +class IntrusiveNonnullRefPtrTest : public RefCounted<IntrusiveNonnullRefPtrTest> { +public: + IntrusiveNonnullRefPtrTest(int key) + : m_tree_node(key) + { + } + + IntrusiveRedBlackTreeNode<int, IntrusiveNonnullRefPtrTest, NonnullRefPtr<IntrusiveNonnullRefPtrTest>> m_tree_node; +}; +using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveNonnullRefPtrTest, NonnullRefPtr<IntrusiveNonnullRefPtrTest>, &IntrusiveNonnullRefPtrTest::m_tree_node>; + +TEST_CASE(intrusive_nonnull_ref_ptr_intrusive) +{ + auto item = adopt_ref(*new IntrusiveNonnullRefPtrTest(0)); + EXPECT_EQ(1u, item->ref_count()); + IntrusiveNonnullRefPtrRBTree nonnull_ref_tree; + + nonnull_ref_tree.insert(*item); + EXPECT_EQ(2u, item->ref_count()); + EXPECT(!nonnull_ref_tree.is_empty()); + + nonnull_ref_tree.remove(0); + EXPECT_EQ(1u, item->ref_count()); + + EXPECT(nonnull_ref_tree.is_empty()); +} |