Skip to content

Commit

Permalink
Add additional priority queue related APIs (#1067)
Browse files Browse the repository at this point in the history
Co-authored-by: Bret Ambrose <bambrose@amazon.com>
Co-authored-by: Michael Graeb <graebm@amazon.com>
  • Loading branch information
3 people authored Oct 27, 2023
1 parent e381a7b commit a0689cf
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 2 deletions.
24 changes: 24 additions & 0 deletions include/aws/common/priority_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ int aws_priority_queue_remove(struct aws_priority_queue *queue, void *item, cons
AWS_COMMON_API
int aws_priority_queue_top(const struct aws_priority_queue *queue, void **item);

/**
* Removes all elements from the queue, but does not free internal memory.
*/
AWS_COMMON_API
void aws_priority_queue_clear(struct aws_priority_queue *queue);

/**
* Current number of elements in the queue
*/
Expand All @@ -175,6 +181,24 @@ size_t aws_priority_queue_size(const struct aws_priority_queue *queue);
AWS_COMMON_API
size_t aws_priority_queue_capacity(const struct aws_priority_queue *queue);

/**
* Initializes a queue node to a default value that indicates the node is not in the queue.
*
* @param node priority queue node to initialize with a default value
*/
AWS_COMMON_API
void aws_priority_queue_node_init(struct aws_priority_queue_node *node);

/**
* Checks if a priority queue node is currently in a priority queue.
*
* @param node priority queue node to check usage for
*
* @return true if the node is in a queue, false otherwise
*/
AWS_COMMON_API
bool aws_priority_queue_node_is_in_queue(const struct aws_priority_queue_node *node);

AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL

Expand Down
24 changes: 24 additions & 0 deletions source/priority_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,27 @@ size_t aws_priority_queue_size(const struct aws_priority_queue *queue) {
size_t aws_priority_queue_capacity(const struct aws_priority_queue *queue) {
return aws_array_list_capacity(&queue->container);
}

void aws_priority_queue_clear(struct aws_priority_queue *queue) {
AWS_PRECONDITION(aws_priority_queue_is_valid(queue));
size_t backpointer_count = aws_array_list_length(&queue->backpointers);
for (size_t i = 0; i < backpointer_count; ++i) {
struct aws_priority_queue_node *node = NULL;
aws_array_list_get_at(&queue->backpointers, &node, i);
if (node != NULL) {
node->current_index = SIZE_MAX;
}
}

aws_array_list_clear(&queue->backpointers);
aws_array_list_clear(&queue->container);
AWS_PRECONDITION(aws_priority_queue_is_valid(queue));
}

void aws_priority_queue_node_init(struct aws_priority_queue_node *node) {
node->current_index = SIZE_MAX;
}

bool aws_priority_queue_node_is_in_queue(const struct aws_priority_queue_node *node) {
return node->current_index != SIZE_MAX;
}
4 changes: 2 additions & 2 deletions source/task_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void aws_task_scheduler_schedule_now(struct aws_task_scheduler *scheduler, struc
(void *)task,
task->type_tag);

task->priority_queue_node.current_index = SIZE_MAX;
aws_priority_queue_node_init(&task->priority_queue_node);
aws_linked_list_node_reset(&task->node);
task->timestamp = 0;

Expand All @@ -161,7 +161,7 @@ void aws_task_scheduler_schedule_future(

task->timestamp = time_to_run;

task->priority_queue_node.current_index = SIZE_MAX;
aws_priority_queue_node_init(&task->priority_queue_node);
aws_linked_list_node_reset(&task->node);
int err = aws_priority_queue_push_ref(&scheduler->timed_queue, &task, &task->priority_queue_node);
if (AWS_UNLIKELY(err)) {
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ add_test_case(priority_queue_remove_root_test)
add_test_case(priority_queue_remove_leaf_test)
add_test_case(priority_queue_remove_interior_sift_up_test)
add_test_case(priority_queue_remove_interior_sift_down_test)
add_test_case(priority_queue_clear_backpointers_test)

add_test_case(linked_list_push_back_pop_front)
add_test_case(linked_list_push_front_pop_back)
Expand Down
36 changes: 36 additions & 0 deletions tests/priority_queue_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,46 @@ static int s_test_remove_interior_sift_down(struct aws_allocator *allocator, voi
return 0;
}

#define BACKPOINTER_CLEAR_NODE_COUNT 16

static int s_priority_queue_clear_backpointers_test(struct aws_allocator *allocator, void *ctx) {
(void)ctx;

struct aws_priority_queue queue;

ASSERT_SUCCESS(aws_priority_queue_init_dynamic(&queue, allocator, 16, sizeof(int), s_compare_ints));

struct aws_priority_queue_node queue_nodes[BACKPOINTER_CLEAR_NODE_COUNT];

for (size_t i = 0; i < BACKPOINTER_CLEAR_NODE_COUNT; ++i) {
aws_priority_queue_node_init(&queue_nodes[i]);
}

for (int i = 0; i < BACKPOINTER_CLEAR_NODE_COUNT; i++) {
aws_priority_queue_push_ref(&queue, &i, &queue_nodes[i]);
}

for (size_t i = 0; i < BACKPOINTER_CLEAR_NODE_COUNT; ++i) {
ASSERT_TRUE(aws_priority_queue_node_is_in_queue(&queue_nodes[i]));
}

aws_priority_queue_clear(&queue);
ASSERT_INT_EQUALS(0, aws_priority_queue_size(&queue));

for (size_t i = 0; i < BACKPOINTER_CLEAR_NODE_COUNT; ++i) {
ASSERT_FALSE(aws_priority_queue_node_is_in_queue(&queue_nodes[i]));
}

aws_priority_queue_clean_up(&queue);

return 0;
}

AWS_TEST_CASE(priority_queue_remove_interior_sift_down_test, s_test_remove_interior_sift_down);
AWS_TEST_CASE(priority_queue_remove_interior_sift_up_test, s_test_remove_interior_sift_up);
AWS_TEST_CASE(priority_queue_remove_leaf_test, s_test_remove_leaf);
AWS_TEST_CASE(priority_queue_remove_root_test, s_test_remove_root);
AWS_TEST_CASE(priority_queue_push_pop_order_test, s_test_priority_queue_preserves_order);
AWS_TEST_CASE(priority_queue_random_values_test, s_test_priority_queue_random_values);
AWS_TEST_CASE(priority_queue_size_and_capacity_test, s_test_priority_queue_size_and_capacity);
AWS_TEST_CASE(priority_queue_clear_backpointers_test, s_priority_queue_clear_backpointers_test);

0 comments on commit a0689cf

Please sign in to comment.