diff --git a/AK/HashTable.h b/AK/HashTable.h index e57d83146de..9ac8c9d507c 100644 --- a/AK/HashTable.h +++ b/AK/HashTable.h @@ -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; } diff --git a/Tests/AK/TestHashTable.cpp b/Tests/AK/TestHashTable.cpp index ad466da149b..97b7cb0ae7a 100644 --- a/Tests/AK/TestHashTable.cpp +++ b/Tests/AK/TestHashTable.cpp @@ -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 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 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); +} diff --git a/Userland/Utilities/tsort.cpp b/Userland/Utilities/tsort.cpp index 31fb603be32..074136f98cd 100644 --- a/Userland/Utilities/tsort.cpp +++ b/Userland/Utilities/tsort.cpp @@ -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