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


Go to the source code of this file.
The Flat Priority Queue Interface.
A flat priority queue is a contiguous container storing elements in heap order. This offers tightly packed data for efficient push, pop, min/max operations in O(lg N) time.
A flat priority queue can use memory sources from the stack, heap, or data segment and can be initialized at compile or runtime. The container offers efficient initialization options such as an O(N) heap building initializer. The flat priority queue also offers a destructive heap sort option if the user desires an in-place strict O(N * log(N)) and O(1) space sort that does not use recursion.
Many functions in the interface request a temporary argument be passed as a swap slot. This is because a flat priority queue is backed by a binary heap and swaps elements to maintain its properties. Because the user may forgo passing an allocator, the user must provide this swap slot. An easy way to do this in C99 and later is with anonymous compound literal references. For example, if we have a int flat priority queue we can provide a temporary slot inline to a function as follows.
Any user defined struct can also use this technique.
This is the preferred method because the storage remains anonymous and inaccessible to other code in the calling scope.
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_flat_priority_queue_default(type_name, order, comparator...) CCC_private_flat_priority_queue_default(type_name, order, comparator) |
| Initialize an empty priority queue. | |
| #define | CCC_flat_priority_queue_for( type_name, order, comparator, capacity, data_pointer) |
| Initialize a priority_queue as a min or max heap. | |
| #define | CCC_flat_priority_queue_heapify( type_name, order, comparator, capacity, count, data_pointer...) |
| Partial order an array of elements as a min or max heap at runtime in O(N) time and space equal to the provided data capacity. | |
| #define | CCC_flat_priority_queue_from( order, comparator, allocator, optional_capacity, compound_literal_array...) |
| Partial order a compound literal array of elements as a min or max heap. O(N). | |
| #define | CCC_flat_priority_queue_with_capacity( type_name, order, comparator, allocator, capacity) |
| Initialize a Flat_priority_queue with a capacity. | |
| #define | CCC_flat_priority_queue_with_storage( order, comparator, compound_literal_array) |
| Initialize a priority_queue as a min or max heap with no allocation permission, no context data, and a compound literal as backing storage. | |
| CCC_Result | CCC_flat_priority_queue_copy (CCC_Flat_priority_queue *destination, CCC_Flat_priority_queue const *source, CCC_Allocator const *allocator) |
| Copy the priority_queue from source to newly initialized destination. | |
| CCC_Result | CCC_flat_priority_queue_reserve (CCC_Flat_priority_queue *priority_queue, size_t to_add, CCC_Allocator const *allocator) |
| Reserves space for at least to_add more elements. | |
Insert and Remove Interface | |
Insert or remove elements from the flat priority queue. | |
| #define | CCC_flat_priority_queue_emplace( priority_queue_pointer, allocator_pointer, type_compound_literal...) |
| Write a type directly to a priority queue slot. O(lgN). | |
| #define | CCC_flat_priority_queue_update_with( priority_queue_pointer, closure_parameter, update_closure_over_closure_parameter...) |
| Update the held user type stored in the priority queue. O(lgN). | |
| #define | CCC_flat_priority_queue_increase_with( flat_priority_queue_pointer, closure_parameter, increase_closure_over_closure_parameter...) |
| Increase the user type stored in the priority queue directly. O(lgN). | |
| #define | CCC_flat_priority_queue_decrease_with( flat_priority_queue_pointer, closure_parameter, decrease_closure_over_closure_parameter...) |
| Increase the user type stored in the priority queue directly. O(lgN). | |
| CCC_Result | CCC_flat_priority_queue_copy_heapify (CCC_Flat_priority_queue *priority_queue, CCC_Buffer const *buffer, void *temp, CCC_Allocator const *allocator) |
| Copy input buffer into the flat priority queue, organizing into data into heap order in O(N) time. | |
| CCC_Flat_priority_queue | CCC_flat_priority_queue_in_place_heapify (CCC_Buffer *buffer, void *temp, CCC_Order order, CCC_Comparator const *comparator) |
| Order count elements of the input Buffer as a flat priority queue, destroying the input metadata Buffer struct taking ownership of its underlying memory. | |
| void * | CCC_flat_priority_queue_push (CCC_Flat_priority_queue *priority_queue, void const *type, void *temp, CCC_Allocator const *allocator) |
| Pushes element pointed to at e into flat_priority_queue. O(lgN). | |
| CCC_Result | CCC_flat_priority_queue_pop (CCC_Flat_priority_queue *priority_queue, void *temp) |
| Pop the front element (min or max) element in the flat_priority_queue. O(lgN). | |
| CCC_Result | CCC_flat_priority_queue_erase (CCC_Flat_priority_queue *priority_queue, void *type, void *temp) |
| Erase element e that is a handle to the stored flat_priority_queue element. | |
| void * | CCC_flat_priority_queue_update (CCC_Flat_priority_queue *priority_queue, void *type, void *temp, CCC_Modifier const *modifier) |
| Update e that is a handle to the stored priority_queue element. O(lgN). | |
| void * | CCC_flat_priority_queue_increase (CCC_Flat_priority_queue *priority_queue, void *type, void *temp, CCC_Modifier const *modifier) |
| Increase type that is a handle to the stored flat_priority_queue element. O(lgN). | |
| void * | CCC_flat_priority_queue_decrease (CCC_Flat_priority_queue *priority_queue, void *type, void *temp, CCC_Modifier const *modifier) |
| Decrease e that is a handle to the stored flat_priority_queue element. O(lgN). | |
Container Types | |
Types available in the container interface. | |
| typedef struct CCC_Flat_priority_queue | CCC_Flat_priority_queue |
| A container offering direct storage and sorting of user data by heap order. | |
Deallocation Interface | |
Deallocate the container or destroy the heap invariants. | |
| CCC_Result | CCC_flat_priority_queue_clear (CCC_Flat_priority_queue *priority_queue, CCC_Destructor const *destructor) |
| Clears the priority_queue calling destroy on every element if provided. O(1)-O(N). | |
| CCC_Result | CCC_flat_priority_queue_clear_and_free (CCC_Flat_priority_queue *priority_queue, CCC_Destructor const *destructor, CCC_Allocator const *allocator) |
| Clears the priority_queue calling destroy on every element if provided. O(1)-O(N). | |
State Interface | |
Obtain state from the container. | |
| void * | CCC_flat_priority_queue_front (CCC_Flat_priority_queue const *priority_queue) |
| Return a pointer to the front (min or max) element in the flat_priority_queue. O(1). | |
| CCC_Tribool | CCC_flat_priority_queue_is_empty (CCC_Flat_priority_queue const *priority_queue) |
| Returns true if the priority_queue is empty false if not. O(1). | |
| CCC_Count | CCC_flat_priority_queue_count (CCC_Flat_priority_queue const *priority_queue) |
| Returns the count of the priority_queue active slots. | |
| CCC_Count | CCC_flat_priority_queue_capacity (CCC_Flat_priority_queue const *priority_queue) |
| Returns the capacity of the priority_queue representing total possible slots. | |
| void * | CCC_flat_priority_queue_data (CCC_Flat_priority_queue const *priority_queue) |
| Return a pointer to the base of the backing array. O(1). | |
| CCC_Tribool | CCC_flat_priority_queue_validate (CCC_Flat_priority_queue const *priority_queue) |
| Verifies the internal invariants of the priority_queue hold. | |
| CCC_Order | CCC_flat_priority_queue_order (CCC_Flat_priority_queue const *priority_queue) |
| Return the order used to initialize the flat_priority_queue. | |
| #define CCC_flat_priority_queue_decrease_with | ( | flat_priority_queue_pointer, | |
| closure_parameter, | |||
| decrease_closure_over_closure_parameter... | |||
| ) |
Increase the user type stored in the priority queue directly. O(lgN).
| [in] | flat_priority_queue_pointer | a pointer to the flat priority queue. |
| [in] | closure_parameter | a pointer variable to user type being decreased. |
| [in] | decrease_closure_over_closure_parameter | the semicolon separated statements to execute on the user type provided (optionally wrapping {code here} in braces may help with formatting). This closure may safely decrease the key used to track the user element's priority in the priority queue. |
Note that if this priority queue is min or max, the runtime is the same.
| #define CCC_flat_priority_queue_default | ( | type_name, | |
| order, | |||
| comparator... | |||
| ) | CCC_private_flat_priority_queue_default(type_name, order, comparator) |
Initialize an empty priority queue.
| [in] | type_name | the name of the user type. |
| [in] | order | desired order of this priority queue. |
| [in] | comparator | a pointer to the CCC_Comparator. |
| #define CCC_flat_priority_queue_emplace | ( | priority_queue_pointer, | |
| allocator_pointer, | |||
| type_compound_literal... | |||
| ) |
Write a type directly to a priority queue slot. O(lgN).
| [in] | priority_queue_pointer | a pointer to the priority queue. |
| [in] | allocator_pointer | a pointer to CCC_Allocator. |
| [in] | type_compound_literal | the compound literal or direct scalar type. |
| #define CCC_flat_priority_queue_for | ( | type_name, | |
| order, | |||
| comparator, | |||
| capacity, | |||
| data_pointer | |||
| ) |
Initialize a priority_queue as a min or max heap.
| [in] | type_name | the name of the user type. |
| [in] | order | CCC_ORDER_LESSER or CCC_ORDER_GREATER for min or max heap, respectively. |
| [in] | comparator | a CCC_Comparator for comparing two user types. |
| [in] | capacity | the capacity of contiguous elements at data_pointer. |
| [in] | data_pointer | a pointer to an array of user types or NULL. |
| #define CCC_flat_priority_queue_from | ( | order, | |
| comparator, | |||
| allocator, | |||
| optional_capacity, | |||
| compound_literal_array... | |||
| ) |
Partial order a compound literal array of elements as a min or max heap. O(N).
| [in] | order | CCC_ORDER_LESSER or CCC_ORDER_GREATER for min or max heap, respectively. |
| [in] | comparator | a CCC_Comparator for comparing two user types. |
| [in] | allocator | a CCC_Allocator for allocating the needed memory to copy in the provided compound literal data. |
| [in] | optional_capacity | the optional capacity larger than the input compound literal array array to reserve. If capacity provided is less than the size of the input compound literal array, the capacity is set to the size of the input compound literal array. If not needed, simply leave as zero. |
| [in] | compound_literal_array | the initializer of the type stored in flat priority queue (e.g. (int[]){1,2,3}). |
Initialize a dynamic Flat_priority_queue with capacity equal to size.
Initialize a dynamic Flat_priority_queue with a large capacity.
Only dynamic priority queues may be initialized this way. For static or stack based initialization of fixed capacity compound literals with no elements see the CCC_flat_priority_queue_with_storage() macro.
| #define CCC_flat_priority_queue_heapify | ( | type_name, | |
| order, | |||
| comparator, | |||
| capacity, | |||
| count, | |||
| data_pointer... | |||
| ) |
Partial order an array of elements as a min or max heap at runtime in O(N) time and space equal to the provided data capacity.
| [in] | type_name | the name of the user type. |
| [in] | order | CCC_ORDER_LESSER or CCC_ORDER_GREATER for min or max heap, respectively. |
| [in] | comparator | a CCC_Comparator for comparing two user types. |
| [in] | capacity | the capacity of contiguous elements at data_pointer. |
| [in] | count | the count <= capacity of valid elements. |
| [in] | data_pointer | a pointer to an array of user types or NULL. |
| #define CCC_flat_priority_queue_increase_with | ( | flat_priority_queue_pointer, | |
| closure_parameter, | |||
| increase_closure_over_closure_parameter... | |||
| ) |
Increase the user type stored in the priority queue directly. O(lgN).
| [in] | flat_priority_queue_pointer | a pointer to the flat priority queue. |
| [in] | closure_parameter | a pointer variable to user type being increased. |
| [in] | increase_closure_over_closure_parameter | the semicolon separated statements to execute on the user type provided (optionally wrapping {code here} in braces may help with formatting). This closure may safely increase the key used to track the user element's priority in the priority queue. |
Note that if this priority queue is min or max, the runtime is the same.
| #define CCC_flat_priority_queue_update_with | ( | priority_queue_pointer, | |
| closure_parameter, | |||
| update_closure_over_closure_parameter... | |||
| ) |
Update the held user type stored in the priority queue. O(lgN).
| [in] | priority_queue_pointer | a pointer to the flat priority queue. |
| [in] | closure_parameter | a pointer variable to the user type being updated. |
| [in] | update_closure_over_closure_parameter | the semicolon separated statements to execute on the user type provided (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 whether the key increases or decreases does not affect runtime.
| #define CCC_flat_priority_queue_with_capacity | ( | type_name, | |
| order, | |||
| comparator, | |||
| allocator, | |||
| capacity | |||
| ) |
Initialize a Flat_priority_queue with a capacity.
| [in] | type_name | the name of the user type. |
| [in] | order | CCC_ORDER_LESSER or CCC_ORDER_GREATER for min or max heap, respectively. |
| [in] | comparator | a CCC_Comparator for comparing user types. |
| [in] | allocator | a pointer to CCC_Allocator for allocating the needed memory to reserve capacity. |
| [in] | capacity | the capacity of contiguous elements at data_pointer. |
Initialize a dynamic Flat_priority_queue.
Only dynamic priority queues may be initialized this way. For static or stack based initialization of fixed capacity compound literals with no elements see the CCC_flat_priority_queue_with_storage() macro.
| #define CCC_flat_priority_queue_with_storage | ( | order, | |
| comparator, | |||
| compound_literal_array | |||
| ) |
Initialize a priority_queue as a min or max heap with no allocation permission, no context data, and a compound literal as backing storage.
| [in] | order | CCC_ORDER_LESSER or CCC_ORDER_GREATER for min or max heap, respectively. |
| [in] | comparator | CCC_Comparator for comparing user types. |
| [in] | compound_literal_array | the compound literal array of fixed capacity. |
| typedef struct CCC_Flat_priority_queue CCC_Flat_priority_queue |
A container offering direct storage and sorting of user data by heap order.
A flat priority queue can be initialized on the stack, heap, or data segment at runtime or compile time.
| CCC_Count CCC_flat_priority_queue_capacity | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Returns the capacity of the priority_queue representing total possible slots.
| [in] | priority_queue | a pointer to the flat priority queue. |
| CCC_Result CCC_flat_priority_queue_clear | ( | CCC_Flat_priority_queue * | priority_queue, |
| CCC_Destructor const * | destructor | ||
| ) |
Clears the priority_queue calling destroy on every element if provided. O(1)-O(N).
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | destructor | the destructor function and context, if needed. |
Note that because the priority queue is flat there is no need to free elements stored in the flat_priority_queue. However, the destructor is free to manage cleanup in other parts of user code as needed upon destruction of each element.
If the destructor is empty, &(CCC_Destructor){}, the function is O(1) and no attempt is made to free capacity of the flat_priority_queue.
| CCC_Result CCC_flat_priority_queue_clear_and_free | ( | CCC_Flat_priority_queue * | priority_queue, |
| CCC_Destructor const * | destructor, | ||
| CCC_Allocator const * | allocator | ||
| ) |
Clears the priority_queue calling destroy on every element if provided. O(1)-O(N).
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | destructor | the destructor function and context, if needed. |
| [in] | allocator | the allocator context needed to free storage. |
Note that because the priority queue is flat there is no need to free elements stored in the flat_priority_queue. However, the destructor is free to manage cleanup in other parts of user code as needed upon destruction of each element.
If the destructor is empty, &(CCC_Destructor){}, the function is O(1) and no attempt is made to free capacity of the flat_priority_queue.
| CCC_Result CCC_flat_priority_queue_copy | ( | CCC_Flat_priority_queue * | destination, |
| CCC_Flat_priority_queue const * | source, | ||
| CCC_Allocator const * | allocator | ||
| ) |
Copy the priority_queue from source to newly initialized destination.
| [in] | destination | the destination that will copy the source flat_priority_queue. |
| [in] | source | the source of the flat_priority_queue. |
| [in] | allocator | a CCC_Allocator for resizing. |
Note that there are two ways to copy data from source to destination: provide sufficient memory and pass NULL as allocate, or allow the copy function to take care of allocation for the copy.
Manual memory management with no allocation function provided.
The above requires destination capacity be greater than or equal to source capacity. Here is memory management handed over to the copy function.
These options allow users to stay consistent across containers with their memory management strategies.
| CCC_Result CCC_flat_priority_queue_copy_heapify | ( | CCC_Flat_priority_queue * | priority_queue, |
| CCC_Buffer const * | buffer, | ||
| void * | temp, | ||
| CCC_Allocator const * | allocator | ||
| ) |
Copy input buffer into the flat priority queue, organizing into data into heap order in O(N) time.
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | buffer | a pointer to the buffer of types to copy into the flat priority queue and heapify. |
| [in] | temp | a pointer to an additional element of array type for swapping. |
| [in] | allocator | a pointer to CCC_Allocator for resizing. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(My_type){}.
Note that this version of heapify copies elements from the input buffer. If an in place heapify is required see any of the following functions.
This function does not modify the input buffer.
| CCC_Count CCC_flat_priority_queue_count | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Returns the count of the priority_queue active slots.
| [in] | priority_queue | a pointer to the flat priority queue. |
| void * CCC_flat_priority_queue_data | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Return a pointer to the base of the backing array. O(1).
| [in] | priority_queue | a pointer to the priority queue. |
| void * CCC_flat_priority_queue_decrease | ( | CCC_Flat_priority_queue * | priority_queue, |
| void * | type, | ||
| void * | temp, | ||
| CCC_Modifier const * | modifier | ||
| ) |
Decrease e that is a handle to the stored flat_priority_queue element. O(lgN).
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | type | a pointer to the stored priority_queue element. Must be in the flat_priority_queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
| [in] | modifier | the CCC_Modifier to operate on an element. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| CCC_Result CCC_flat_priority_queue_erase | ( | CCC_Flat_priority_queue * | priority_queue, |
| void * | type, | ||
| void * | temp | ||
| ) |
Erase element e that is a handle to the stored flat_priority_queue element.
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type | a pointer to the stored priority_queue element. Must be in the flat_priority_queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
Note that the reference to type is invalidated after this call.
| void * CCC_flat_priority_queue_front | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Return a pointer to the front (min or max) element in the flat_priority_queue. O(1).
| [in] | priority_queue | a pointer to the priority queue. |
| CCC_Flat_priority_queue CCC_flat_priority_queue_in_place_heapify | ( | CCC_Buffer * | buffer, |
| void * | temp, | ||
| CCC_Order | order, | ||
| CCC_Comparator const * | comparator | ||
| ) |
Order count elements of the input Buffer as a flat priority queue, destroying the input metadata Buffer struct taking ownership of its underlying memory.
| [in] | buffer | a pointer to a buffer with memory that will be sorted into heap order, given to the flat priority queue, and its metadata struct will be cleared. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
| [in] | order | the order of the heap, minimum or maximum priority queue. |
| [in] | comparator | the comparison function used during heapify. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| void * CCC_flat_priority_queue_increase | ( | CCC_Flat_priority_queue * | priority_queue, |
| void * | type, | ||
| void * | temp, | ||
| CCC_Modifier const * | modifier | ||
| ) |
Increase type that is a handle to the stored flat_priority_queue element. O(lgN).
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | type | a pointer to the stored priority_queue element. Must be in the flat_priority_queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
| [in] | modifier | the CCC_Modifier to operate on an element. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| CCC_Tribool CCC_flat_priority_queue_is_empty | ( | CCC_Flat_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 flat priority queue. |
| CCC_Order CCC_flat_priority_queue_order | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Return the order used to initialize the flat_priority_queue.
| [in] | priority_queue | a pointer to the flat priority queue. |
| CCC_Result CCC_flat_priority_queue_pop | ( | CCC_Flat_priority_queue * | priority_queue, |
| void * | temp | ||
| ) |
Pop the front element (min or max) element in the flat_priority_queue. O(lgN).
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| void * CCC_flat_priority_queue_push | ( | CCC_Flat_priority_queue * | priority_queue, |
| void const * | type, | ||
| void * | temp, | ||
| CCC_Allocator const * | allocator | ||
| ) |
Pushes element pointed to at e into flat_priority_queue. O(lgN).
| [in] | priority_queue | a pointer to the priority queue. |
| [in] | type | a pointer to the user element of same type as in flat_priority_queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
| [in] | allocator | a pointer to CCC_Allocator for resizing. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| CCC_Result CCC_flat_priority_queue_reserve | ( | CCC_Flat_priority_queue * | priority_queue, |
| size_t | to_add, | ||
| CCC_Allocator const * | allocator | ||
| ) |
Reserves space for at least to_add more elements.
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | to_add | the number of elements to add to the current size. |
| [in] | allocator | a pointer to CCC_Allocator for resizing. |
This function can be used for a dynamic priority_queue with or without allocation permission. If the priority_queue has allocation permission, it will reserve the required space and later resize if more space is needed.
If the priority_queue has been initialized with no allocation permission and no memory this function can serve as a one-time reservation. This is helpful when a fixed size is needed but that size is only known dynamically at runtime. To free the priority_queue in such a case see the CCC_flat_priority_queue_clear_and_free_reserve function.
| void * CCC_flat_priority_queue_update | ( | CCC_Flat_priority_queue * | priority_queue, |
| void * | type, | ||
| void * | temp, | ||
| CCC_Modifier const * | modifier | ||
| ) |
Update e that is a handle to the stored priority_queue element. O(lgN).
| [in] | priority_queue | a pointer to the flat priority queue. |
| [in] | type | a pointer to the stored priority_queue element. Must be in the flat_priority_queue. |
| [in] | temp | a pointer to a dummy user type that will be used for swapping. |
| [in] | modifier | the modifier function to call with context, if needed. |
A simple way to provide a temp for swapping is with an inline compound literal reference provided directly to the function argument &(name_of_type){}.
| CCC_Tribool CCC_flat_priority_queue_validate | ( | CCC_Flat_priority_queue const * | priority_queue | ) |
Verifies the internal invariants of the priority_queue hold.
| [in] | priority_queue | a pointer to the flat priority queue. |