mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-22 02:26:11 +00:00
AK: Set IntrusiveRBTree Node key on insertion instead of construction
This makes the API look much nicer.
This commit is contained in:
parent
1db9250766
commit
cb9720baab
|
@ -48,10 +48,11 @@ public:
|
||||||
return node_to_value(*node);
|
return node_to_value(*node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(V& value)
|
void insert(K key, V& value)
|
||||||
{
|
{
|
||||||
auto& node = value.*member;
|
auto& node = value.*member;
|
||||||
VERIFY(!node.m_in_tree);
|
VERIFY(!node.m_in_tree);
|
||||||
|
node.key = key;
|
||||||
BaseTree::insert(&node);
|
BaseTree::insert(&node);
|
||||||
if constexpr (!TreeNode::IsRaw)
|
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.
|
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>
|
template<Integral K, typename V, typename Container>
|
||||||
class IntrusiveRedBlackTreeNode : public BaseRedBlackTree<K>::Node {
|
class IntrusiveRedBlackTreeNode : public BaseRedBlackTree<K>::Node {
|
||||||
public:
|
public:
|
||||||
IntrusiveRedBlackTreeNode(K key)
|
|
||||||
: BaseRedBlackTree<K>::Node(key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~IntrusiveRedBlackTreeNode()
|
~IntrusiveRedBlackTreeNode()
|
||||||
{
|
{
|
||||||
VERIFY(!is_in_tree());
|
VERIFY(!is_in_tree());
|
||||||
|
|
|
@ -38,6 +38,9 @@ public:
|
||||||
: key(key)
|
: key(key)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Node()
|
||||||
|
{
|
||||||
|
}
|
||||||
virtual ~Node() {};
|
virtual ~Node() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,8 @@
|
||||||
|
|
||||||
class IntrusiveTest {
|
class IntrusiveTest {
|
||||||
public:
|
public:
|
||||||
IntrusiveTest(int key, int value)
|
IntrusiveTest(int value)
|
||||||
: m_tree_node(key)
|
: m_some_value(value)
|
||||||
, m_some_value(value)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,12 +32,12 @@ TEST_CASE(construct)
|
||||||
TEST_CASE(ints)
|
TEST_CASE(ints)
|
||||||
{
|
{
|
||||||
IntrusiveRBTree test;
|
IntrusiveRBTree test;
|
||||||
IntrusiveTest first { 1, 10 };
|
IntrusiveTest first { 10 };
|
||||||
test.insert(first);
|
test.insert(1, first);
|
||||||
IntrusiveTest second { 3, 20 };
|
IntrusiveTest second { 20 };
|
||||||
test.insert(second);
|
test.insert(3, second);
|
||||||
IntrusiveTest third { 2, 30 };
|
IntrusiveTest third { 30 };
|
||||||
test.insert(third);
|
test.insert(2, third);
|
||||||
EXPECT_EQ(test.size(), 3u);
|
EXPECT_EQ(test.size(), 3u);
|
||||||
EXPECT_EQ(test.find(3)->m_some_value, 20);
|
EXPECT_EQ(test.find(3)->m_some_value, 20);
|
||||||
EXPECT_EQ(test.find(2)->m_some_value, 30);
|
EXPECT_EQ(test.find(2)->m_some_value, 30);
|
||||||
|
@ -53,12 +52,12 @@ TEST_CASE(ints)
|
||||||
TEST_CASE(largest_smaller_than)
|
TEST_CASE(largest_smaller_than)
|
||||||
{
|
{
|
||||||
IntrusiveRBTree test;
|
IntrusiveRBTree test;
|
||||||
IntrusiveTest first { 1, 10 };
|
IntrusiveTest first { 10 };
|
||||||
test.insert(first);
|
test.insert(1, first);
|
||||||
IntrusiveTest second { 11, 20 };
|
IntrusiveTest second { 20 };
|
||||||
test.insert(second);
|
test.insert(11, second);
|
||||||
IntrusiveTest third { 21, 30 };
|
IntrusiveTest third { 30 };
|
||||||
test.insert(third);
|
test.insert(21, third);
|
||||||
EXPECT_EQ(test.size(), 3u);
|
EXPECT_EQ(test.size(), 3u);
|
||||||
EXPECT_EQ(test.find_largest_not_above(3)->m_some_value, 10);
|
EXPECT_EQ(test.find_largest_not_above(3)->m_some_value, 10);
|
||||||
EXPECT_EQ(test.find_largest_not_above(17)->m_some_value, 20);
|
EXPECT_EQ(test.find_largest_not_above(17)->m_some_value, 20);
|
||||||
|
@ -86,8 +85,8 @@ TEST_CASE(key_ordered_iteration)
|
||||||
|
|
||||||
// insert random keys
|
// insert random keys
|
||||||
for (size_t i = 0; i < amount; i++) {
|
for (size_t i = 0; i < amount; i++) {
|
||||||
auto entry = make<IntrusiveTest>(keys[i], keys[i]);
|
auto entry = make<IntrusiveTest>(keys[i]);
|
||||||
test.insert(*entry);
|
test.insert(keys[i], *entry);
|
||||||
m_entries.append(move(entry));
|
m_entries.append(move(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +107,8 @@ TEST_CASE(clear)
|
||||||
IntrusiveRBTree test;
|
IntrusiveRBTree test;
|
||||||
NonnullOwnPtrVector<IntrusiveTest> m_entries;
|
NonnullOwnPtrVector<IntrusiveTest> m_entries;
|
||||||
for (size_t i = 0; i < 1000; i++) {
|
for (size_t i = 0; i < 1000; i++) {
|
||||||
auto entry = make<IntrusiveTest>(i, i);
|
auto entry = make<IntrusiveTest>(i);
|
||||||
test.insert(*entry);
|
test.insert(i, *entry);
|
||||||
m_entries.append(move(entry));
|
m_entries.append(move(entry));
|
||||||
}
|
}
|
||||||
test.clear();
|
test.clear();
|
||||||
|
@ -118,8 +117,7 @@ TEST_CASE(clear)
|
||||||
|
|
||||||
class IntrusiveRefPtrTest : public RefCounted<IntrusiveRefPtrTest> {
|
class IntrusiveRefPtrTest : public RefCounted<IntrusiveRefPtrTest> {
|
||||||
public:
|
public:
|
||||||
IntrusiveRefPtrTest(int key)
|
IntrusiveRefPtrTest()
|
||||||
: m_tree_node(key)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,11 +127,11 @@ using IntrusiveRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveRefPtrTest, Re
|
||||||
|
|
||||||
TEST_CASE(intrusive_ref_ptr_no_ref_leaks)
|
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());
|
EXPECT_EQ(1u, item->ref_count());
|
||||||
IntrusiveRefPtrRBTree ref_tree;
|
IntrusiveRefPtrRBTree ref_tree;
|
||||||
|
|
||||||
ref_tree.insert(*item);
|
ref_tree.insert(0, *item);
|
||||||
EXPECT_EQ(2u, item->ref_count());
|
EXPECT_EQ(2u, item->ref_count());
|
||||||
|
|
||||||
ref_tree.remove(0);
|
ref_tree.remove(0);
|
||||||
|
@ -142,11 +140,11 @@ TEST_CASE(intrusive_ref_ptr_no_ref_leaks)
|
||||||
|
|
||||||
TEST_CASE(intrusive_ref_ptr_clear)
|
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());
|
EXPECT_EQ(1u, item->ref_count());
|
||||||
IntrusiveRefPtrRBTree ref_tree;
|
IntrusiveRefPtrRBTree ref_tree;
|
||||||
|
|
||||||
ref_tree.insert(*item);
|
ref_tree.insert(0, *item);
|
||||||
EXPECT_EQ(2u, item->ref_count());
|
EXPECT_EQ(2u, item->ref_count());
|
||||||
|
|
||||||
ref_tree.clear();
|
ref_tree.clear();
|
||||||
|
@ -155,12 +153,12 @@ TEST_CASE(intrusive_ref_ptr_clear)
|
||||||
|
|
||||||
TEST_CASE(intrusive_ref_ptr_destructor)
|
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());
|
EXPECT_EQ(1u, item->ref_count());
|
||||||
|
|
||||||
{
|
{
|
||||||
IntrusiveRefPtrRBTree ref_tree;
|
IntrusiveRefPtrRBTree ref_tree;
|
||||||
ref_tree.insert(*item);
|
ref_tree.insert(0, *item);
|
||||||
EXPECT_EQ(2u, item->ref_count());
|
EXPECT_EQ(2u, item->ref_count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +167,7 @@ TEST_CASE(intrusive_ref_ptr_destructor)
|
||||||
|
|
||||||
class IntrusiveNonnullRefPtrTest : public RefCounted<IntrusiveNonnullRefPtrTest> {
|
class IntrusiveNonnullRefPtrTest : public RefCounted<IntrusiveNonnullRefPtrTest> {
|
||||||
public:
|
public:
|
||||||
IntrusiveNonnullRefPtrTest(int key)
|
IntrusiveNonnullRefPtrTest()
|
||||||
: m_tree_node(key)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,11 +177,11 @@ using IntrusiveNonnullRefPtrRBTree = IntrusiveRedBlackTree<int, IntrusiveNonnull
|
||||||
|
|
||||||
TEST_CASE(intrusive_nonnull_ref_ptr_intrusive)
|
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());
|
EXPECT_EQ(1u, item->ref_count());
|
||||||
IntrusiveNonnullRefPtrRBTree nonnull_ref_tree;
|
IntrusiveNonnullRefPtrRBTree nonnull_ref_tree;
|
||||||
|
|
||||||
nonnull_ref_tree.insert(*item);
|
nonnull_ref_tree.insert(0, *item);
|
||||||
EXPECT_EQ(2u, item->ref_count());
|
EXPECT_EQ(2u, item->ref_count());
|
||||||
EXPECT(!nonnull_ref_tree.is_empty());
|
EXPECT(!nonnull_ref_tree.is_empty());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue