|
C Container Collection (CCC)
|
The Priority Queue Interface. More...


Go to the source code of this file.
The Priority Queue Interface.
A priority queue offers simple, fast, pointer stable management of a priority queue. Push is O(1). The cost to execute the increase key in a max heap and decrease key in a min heap is O(1). However, due to the restructuring this causes that increases the cost of later pops, the more accurate runtime is o(log(N)). The cost of a pop operation is O(log(N)).
To shorten names in the interface, define the following preprocessor directive at the top of your file.
All types and functions can then be written without the CCC_ prefix.
Initialization Interface | |
Initialize the container with memory, callbacks, and permissions. | |
| #define | CCC_priority_queue_initialize(struct_name, type_intruder_field, order, compare, allocate, context_data) |
| Initialize a priority queue at runtime or compile time. | |
| #define | CCC_priority_queue_from(type_intruder_field, order, compare, allocate, destroy, context_data, compound_literal_array...) |
| Initialize a priority queue at runtime from a compound literal array. | |
Insert and Remove Interface | |
Insert and remove elements from the priority queue. | |
| #define | CCC_priority_queue_emplace(Priority_queue_pointer, type_compound_literal...) |
| Write user type_intruder directly to a newly allocated priority queue elem. | |
| #define | CCC_priority_queue_update_with(priority_queue_pointer, type_pointer, update_closure_over_T...) |
| Update the priority in the user type_intruder stored in the container. | |
| #define | CCC_priority_queue_increase_with(priority_queue_pointer, type_pointer, increase_closure_over_T...) |
| Increases the priority of the user type_intruder stored in the container. | |
| #define | CCC_priority_queue_decrease_with(priority_queue_pointer, type_pointer, decrease_closure_over_T...) |
| Decreases the priority of the user type_intruder stored in the container. | |
| void * | CCC_priority_queue_push (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder) |
| Adds an element to the priority queue in correct total order. O(1). | |
| CCC_Result | CCC_priority_queue_pop (CCC_Priority_queue *priority_queue) |
| Pops the front element from the priority queue. Amortized O(lgN). | |
| void * | CCC_priority_queue_extract (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder) |
| CCC_Result | CCC_priority_queue_erase (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder) |
| Erase type_intruder from the priority_queue. Amortized O(lgN). | |
| void * | CCC_priority_queue_update (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder, CCC_Type_modifier *modify, void *context) |
| Update the priority in the user type_intruder wrapping elem. | |
| void * | CCC_priority_queue_increase (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder, CCC_Type_modifier *modify, void *context) |
| Increases the priority of the type_intruder wrapping elem. O(1) or O(lgN) | |
| void * | CCC_priority_queue_decrease (CCC_Priority_queue *priority_queue, CCC_Priority_queue_node *type_intruder, CCC_Type_modifier *modify, void *context) |
| Decreases the value of the type_intruder wrapping elem. O(1) or O(lgN) | |
Container Types | |
Types available in the container interface. | |
| typedef struct CCC_Priority_queue | CCC_Priority_queue |
| A container for pointer stability and an O(1) push and amortized o(lg
N) increase/decrease key. | |
| typedef struct CCC_Priority_queue_node | CCC_Priority_queue_node |
| The embedded struct type_intruder for operation of the priority queue. | |
Deallocation Interface | |
Deallocate the container. | |
| CCC_Result | CCC_priority_queue_clear (CCC_Priority_queue *priority_queue, CCC_Type_destructor *destroy) |
| Removes all elements from the priority_queue, freeing if needed. | |
State Interface | |
Obtain state from the container. | |
| void * | CCC_priority_queue_front (CCC_Priority_queue const *priority_queue) |
| Obtain a reference to the front of the priority queue. O(1). | |
| CCC_Tribool | CCC_priority_queue_is_empty (CCC_Priority_queue const *priority_queue) |
| Returns true if the priority queue is empty false if not. O(1). | |
| CCC_Count | CCC_priority_queue_count (CCC_Priority_queue const *priority_queue) |
| Returns the count of priority queue occupied nodes. | |
| CCC_Tribool | CCC_priority_queue_validate (CCC_Priority_queue const *priority_queue) |
| Verifies the internal invariants of the priority_queue hold. | |
| CCC_Order | CCC_priority_queue_order (CCC_Priority_queue const *priority_queue) |
| Return the order used to initialize the priority_queue. | |
| #define CCC_priority_queue_decrease_with | ( | priority_queue_pointer, | |
| type_pointer, | |||
| decrease_closure_over_T... | |||
| ) |
Decreases the priority of the user type_intruder stored in the container.
| [in] | priority_queue_pointer | a pointer to the priority queue. |
| [in] | type_pointer | a pointer to the user struct type_intruder in the priority_queue. |
| [in] | decrease_closure_over_T | a pointer to the user struct type_intruder T is made available. Use a semicolon separated statements to execute on the user type which wraps priority_queue_node_pointer (optionally wrapping {code here} in braces may help with formatting). This closure may safely modify the key used to track the user element's priority in the priority queue. |
Note that this is optimal update technique if the priority queue has been initialized as a min queue and the new value is known to be less than the old value. If this is a min heap O(1), otherwise O(lgN).
While the best case operation is O(1) the impact of restructuring on future pops from the priority_queue creates an amortized o(lgN) runtime for this function.
| #define CCC_priority_queue_emplace | ( | Priority_queue_pointer, | |
| type_compound_literal... | |||
| ) |
Write user type_intruder directly to a newly allocated priority queue elem.
| [in] | Priority_queue_pointer | a pointer to the priority queue. |
| [in] | type_compound_literal | the compound literal to write to the allocation. |
Note that the priority queue must be initialized with allocation permission to use this macro.
| #define CCC_priority_queue_from | ( | type_intruder_field, | |
| order, | |||
| compare, | |||
| allocate, | |||
| destroy, | |||
| context_data, | |||
| compound_literal_array... | |||
| ) |
Initialize a priority queue at runtime from a compound literal array.
| [in] | type_intruder_field | the name of the field intruding on user's type. |
| [in] | order | CCC_ORDER_LESSER for a min priority queue or CCC_ORDER_GREATER for a max priority queue. |
| [in] | compare | the function used to compare two user types. |
| [in] | allocate | the allocation function required for construction. |
| [in] | destroy | the optional destructor to run if insertion fails. |
| [in] | context_data | context data needed for comparison or destruction. |
| [in] | compound_literal_array | the array of user types to insert into the map (e.g. (struct My_type[]){ {.key = 1, .val = 1}, {.key = 2, .val = 2}}). |
| #define CCC_priority_queue_increase_with | ( | priority_queue_pointer, | |
| type_pointer, | |||
| increase_closure_over_T... | |||
| ) |
Increases the priority of the user type_intruder stored in the container.
| [in] | priority_queue_pointer | a pointer to the priority queue. |
| [in] | type_pointer | a pointer to the user struct type_intruder in the priority_queue. |
| [in] | increase_closure_over_T | a pointer to the user struct type_intruder T is made available. Use a semicolon separated statements to execute on the user type which wraps priority_queue_node_pointer (optionally wrapping {code here} in braces may help with formatting). This closure may safely modify the key used to track the user element's priority in the priority queue. |
Note that this is optimal update technique if the priority queue has been initialized as a max queue and the new value is known to be greater than the old value. If this is a max heap O(1), otherwise O(lgN).
While the best case operation is O(1) the impact of restructuring on future pops from the priority_queue creates an amortized o(lgN) runtime for this function.
| #define CCC_priority_queue_initialize | ( | struct_name, | |
| type_intruder_field, | |||
| order, | |||
| compare, | |||
| allocate, | |||
| context_data | |||
| ) |
Initialize a priority queue at runtime or compile time.
| [in] | struct_name | the name of the user type_intruder wrapping priority_queue elems. |
| [in] | type_intruder_field | the name of the field for the priority_queue elem. |
| [in] | order | CCC_ORDER_LESSER for a min priority_queue or CCC_ORDER_GREATER for a max priority_queue. |
| [in] | compare | the function used to compare two user types. |
| [in] | allocate | the allocation function or NULL if allocation is banned. |
| [in] | context_data | context data needed for comparison or destruction. |
| #define CCC_priority_queue_update_with | ( | priority_queue_pointer, | |
| type_pointer, | |||
| update_closure_over_T... | |||
| ) |
Update the priority in the user type_intruder stored in the container.
| [in] | priority_queue_pointer | a pointer to the priority queue. |
| [in] | type_pointer | a pointer to the user struct type_intruder in the priority_queue. |
| [in] | update_closure_over_T | a pointer to the user struct type_intruder T is made available. Use a semicolon separated statements to execute on the user type which wraps priority_queue_node_pointer (optionally wrapping {code here} in braces may help with formatting). This closure may safely modify the key used to track the user element's priority in the priority queue. |
Note that this operation may incur unnecessary overhead if the user can't deduce if an increase or decrease is occurring. See the increase and decrease operations. O(1) best case, O(lgN) worst case.
| typedef struct CCC_Priority_queue CCC_Priority_queue |
A container for pointer stability and an O(1) push and amortized o(lg N) increase/decrease key.
A priority queue can be initialized on the stack, heap, or data segment at runtime or compile time.
| typedef struct CCC_Priority_queue_node CCC_Priority_queue_node |
The embedded struct type_intruder for operation of the priority queue.
It can be used in an allocating or non allocating container. If allocation is prohibited the container assumes the element is wrapped in pre-allocated memory with the appropriate lifetime and scope for the user's needs; the container does not allocate or free in this case. If allocation is allowed the container will handle copying the data wrapping the element to allocations and deallocating when necessary.
| CCC_Result CCC_priority_queue_clear | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Type_destructor * | destroy | ||
| ) |
Removes all elements from the priority_queue, freeing if needed.
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | destroy | the destructor function or NULL if not needed. |
Note that if allocation is allowed the container will free the user type wrapping each element in the priority_queue. Therefore, the user should not free in the destructor function. Only perform context cleanup operations if needed.
If allocation is not allowed, the user may free their stored types in the destructor function if they wish to do so. The container simply removes all the elements from the priority_queue, calling destroy on each user type_intruder if provided, and sets the size to zero.
| CCC_Count CCC_priority_queue_count | ( | CCC_Priority_queue const * | priority_queue | ) |
Returns the count of priority queue occupied nodes.
| [in] | priority_queue | a pointer to the priority queue. |
| void * CCC_priority_queue_decrease | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder, | ||
| CCC_Type_modifier * | modify, | ||
| void * | context | ||
| ) |
Decreases the value of the type_intruder wrapping elem. O(1) or O(lgN)
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
| [in] | modify | the update function to act on the type_intruder wrapping elem. |
| [in] | context | any context data needed for the update function. |
Note that this is optimal update technique if the priority queue has been initialized as a min queue and the new value is known to be less than the old value. If this is a min heap O(1), otherwise O(lgN).
While the best case operation is O(1) the impact of restructuring on future pops from the priority_queue creates an amortized o(lgN) runtime for this function.
| CCC_Result CCC_priority_queue_erase | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder | ||
| ) |
Erase type_intruder from the priority_queue. Amortized O(lgN).
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
Note that the user must ensure that type_intruder is in the priority queue.
| void * CCC_priority_queue_extract | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder | ||
| ) |
Extract the element known to be in the priority_queue without freeing memory. Amortized O(lgN).
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
Note that the user must ensure that type_intruder is in the priority queue.
| void * CCC_priority_queue_front | ( | CCC_Priority_queue const * | priority_queue | ) |
Obtain a reference to the front of the priority queue. O(1).
| [in] | priority_queue | a pointer to the priority queue. |
| void * CCC_priority_queue_increase | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder, | ||
| CCC_Type_modifier * | modify, | ||
| void * | context | ||
| ) |
Increases the priority of the type_intruder wrapping elem. O(1) or O(lgN)
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
| [in] | modify | the update function to act on the type_intruder wrapping elem. |
| [in] | context | any context data needed for the update function. |
Note that this is optimal update technique if the priority queue has been initialized as a max queue and the new value is known to be greater than the old value. If this is a max heap O(1), otherwise O(lgN).
While the best case operation is O(1) the impact of restructuring on future pops from the priority_queue creates an amortized o(lgN) runtime for this function.
| CCC_Tribool CCC_priority_queue_is_empty | ( | CCC_Priority_queue const * | priority_queue | ) |
Returns true if the priority queue is empty false if not. O(1).
| [in] | priority_queue | a pointer to the priority queue. |
| CCC_Order CCC_priority_queue_order | ( | CCC_Priority_queue const * | priority_queue | ) |
Return the order used to initialize the priority_queue.
| [in] | priority_queue | a pointer to the priority queue. |
| CCC_Result CCC_priority_queue_pop | ( | CCC_Priority_queue * | priority_queue | ) |
Pops the front element from the priority queue. Amortized O(lgN).
| [in] | priority_queue | a pointer to the priority queue. |
| void * CCC_priority_queue_push | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder | ||
| ) |
Adds an element to the priority queue in correct total order. O(1).
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
Note that if allocation is permitted the user type_intruder is copied into a newly allocated node.
If allocation is not permitted this function assumes the memory wrapping elem has been allocated with the appropriate lifetime for the user's needs.
| void * CCC_priority_queue_update | ( | CCC_Priority_queue * | priority_queue, |
| CCC_Priority_queue_node * | type_intruder, | ||
| CCC_Type_modifier * | modify, | ||
| void * | context | ||
| ) |
Update the priority in the user type_intruder wrapping elem.
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type_intruder | a pointer to the intrusive element in the user type. |
| [in] | modify | the update function to act on the type_intruder wrapping elem. |
| [in] | context | any context data needed for the update function. |
Note that this operation may incur unnecessary overhead if the user can't deduce if an increase or decrease is occurring. See the increase and decrease operations. O(1) best case, O(lgN) worst case.
| CCC_Tribool CCC_priority_queue_validate | ( | CCC_Priority_queue const * | priority_queue | ) |
Verifies the internal invariants of the priority_queue hold.
| [in] | priority_queue | a pointer to the priority queue. |