AK: Add take_first to HashTable and rename pop to take_last

This naming scheme matches Vector.

This also changes `take_last` to move the value it takes, and delete by
known pointer, avoiding a full lookup and potential copies.
This commit is contained in:
Hediadyoin1 2023-02-21 11:30:52 +01:00 committed by Jelle Raaijmakers
parent 93945062a7
commit fd8c54d720
Notes: sideshowbarker 2024-07-17 17:38:29 +09:00
3 changed files with 45 additions and 8 deletions

View file

@ -405,12 +405,21 @@ public:
return has_removed_anything;
}
T pop()
T take_last()
requires(IsOrdered)
{
VERIFY(!is_empty());
T element = *m_collection_data.tail->slot();
remove(element);
T element = move(*m_collection_data.tail->slot());
delete_bucket(*m_collection_data.tail);
return element;
}
T take_first()
requires(IsOrdered)
{
VERIFY(!is_empty());
T element = move(*m_collection_data.head->slot());
delete_bucket(*m_collection_data.head);
return element;
}

View file

@ -358,16 +358,16 @@ TEST_CASE(ordered_deletion_and_reinsertion)
EXPECT_EQ(it, table.end());
}
TEST_CASE(ordered_pop)
TEST_CASE(ordered_take_last)
{
OrderedHashTable<int> table;
table.set(1);
table.set(2);
table.set(3);
EXPECT_EQ(table.pop(), 3);
EXPECT_EQ(table.pop(), 2);
EXPECT_EQ(table.pop(), 1);
EXPECT_EQ(table.take_last(), 3);
EXPECT_EQ(table.take_last(), 2);
EXPECT_EQ(table.take_last(), 1);
EXPECT(table.is_empty());
}
@ -382,3 +382,31 @@ TEST_CASE(ordered_iterator_removal)
EXPECT_EQ(it, map.end());
EXPECT_EQ(map.size(), 1u);
}
TEST_CASE(ordered_remove_from_head)
{
OrderedHashTable<int> map;
map.set(1);
map.set(2);
map.set(3);
map.set(4);
map.set(5);
map.set(6);
EXPECT_EQ(map.size(), 6u);
auto it = map.begin();
map.remove(it);
it = map.begin();
map.remove(it);
it = map.begin();
map.remove(it);
it = map.begin();
map.remove(it);
it = map.begin();
map.remove(it);
it = map.begin();
map.remove(it);
EXPECT_EQ(map.size(), 0u);
}

View file

@ -76,7 +76,7 @@ static void prioritize_nodes(Node& start, NodeMap& node_map, NodeStack& stack, b
node.status = NodeStatus::Prioritized;
outln("{}", stack.take_last().name);
} else {
auto next_ancestor_name = node.ancestors.pop();
auto next_ancestor_name = node.ancestors.take_last();
auto& next_ancestor = node_map.get(next_ancestor_name).release_value();
if (next_ancestor.status == NodeStatus::Seen)
// If the same node is seen multiple times, this represents a cycle in