Data Structures
A general, yet highly performant data structures library. It highly run-time configurable, in the sense that the memory used by the data structure handle, the elements the data structure will manage/contain, and structure metadata can be independently provided by the calling application, or malloc()ed by the library.
The data structures library is comprised of the following modules:
Module |
Notes |
Link |
---|---|---|
Ringbuffer |
||
Linked list. |
Doubly linked. |
|
FIFO |
Built on ringbuffer. |
|
Raw FIFO |
Only handles {1, 2, 4} byte elements. Uses only pointer math when adding/removing elements, instead of memcpy()/function calls, so is ISR safe. |
|
Dynamic array |
Just like |
|
Binary Search Tree |
Uses approach in Introduction To Algorithms. |
|
Red-Black tree |
Uses approach in Introduction To Algorithms. |
|
Order Statistics Tree |
Built on Red-Black Tree; uses approach in Introduction To Algorithms. |
|
Interval Tree |
Built on Red-Black Tree. Uses approach in Introduction To Algorithms. |
|
Hashmap |
Built using dynamic arrays. |
|
Binary heap |
Built using dynamic array. |
|
Matrix |
Static matrix; dimensions cannot change after initialization. |
|
Dynamic Matrix |
Dimensions can change after initialization. Can be used to represent dynamic graphs. Works best on densely connected graphs. |
|
Adjacency Matrix |
Dimensions (# vertices) cannot change after initialization. Can be used to represent graphs efficiently; works best on densely connected graphs. |
Common API
All of the data structures (loosely) conform to the following API; not all data
structures implement all functions. E.g., llist
does not implement
llist_data_get()
because linked lists don’t have a concept of indices.
Function |
Purpose |
---|---|
|
Initialize the data structure. Any usage of the data structure handle prior to calling this function is undefined. |
|
Give the max # of elements and the element size, compute the amount of space the calling application will need to reserve if it doesn’t want the data structure to do any allocations for elements in the data structure. |
|
Give the max # of elements, compute the amount of
space the calling application will need to reserve if it doesn’t want the
data structure to do any allocations for metadata to track the elements
it contains. Only applicable to e.g., |
|
Destroy the data structure. Any usage of the data structure handle after
calling this function is undefined until |
|
Add a new element to the data structure. |
|
Remove an existing element from the data structure. |
|
Remove all elements from the data structure, but doesn’t destroy it. |
|
Print all elements of the data structure using the callback provided during initialization. |
|
Is the data structure currently full ? i.e., any future attempts to try and add elements will fail unless one is removed first. |
|
Is the data structure currently empty? |
|
Get the current # of elements in the data structure. |
|
Get the maximum # of elements that the data structure can currently handle. Only applies to data structures which have a fixed capacity at every point in time, such as an array. This is different that the maximum possible capacity for a data structure, which is set during initialization. |
|
Sort the data structure. |
|
Remove elements from the data structure instance into a new instance OR just delete them from the data structure according to a user-defined predicate. |
|
Make a copy of the data structure, possibly conditioning element membership in the new data structure via a user-defined predicate. |
|
Iterate over all elements in the data structure, computing a cumulative something using a user-defined predicate. |
|
Apply a used-defined predicate to all elements in the data structure. |
|
Query a data structure to see if a given element is present. Some data structures implement querying by key, some by key or index, and some implement multiple querying modalities. |
|
Get an item from a data structure directly by index. No error checking is performed, so the index must be valid. |