|
cctools
|
#include <stdint.h>#include <stdbool.h>Go to the source code of this file.
Macros | |
| #define | skip_list_cursor_move_to_priority(cur, ...) skip_list_cursor_move_to_priority_arr(cur, (double[]){__VA_ARGS__}) |
| Move a cursor to the first item with the given priority tuple. More... | |
| #define | skip_list_remove_by_priority(sl, ...) skip_list_remove_by_priority_arr(sl, (double[]){__VA_ARGS__}) |
| Remove the first node found with the given priority tuple. More... | |
| #define | skip_list_insert(lst, item, ...) skip_list_insert_arr(lst, item, (double[]){__VA_ARGS__}) |
| Insert an item with priority into the skip list. More... | |
| #define | SKIP_LIST_ITERATE(cursor, item) for(; skip_list_get(cursor, (void **)&item); skip_list_next(cursor)) |
| Iterate over all items in a skip list (highest to lowest priority). More... | |
Functions | |
| struct skip_list * | skip_list_create (unsigned priority_size, double probability) |
| Create an empty skip list with priority-based sorting. More... | |
| bool | skip_list_delete (struct skip_list *sl) |
| Delete a skip list. More... | |
| int | skip_list_size (struct skip_list *sl) |
| Get the number of items in a skip list. More... | |
| const double * | skip_list_peek_head_priority (struct skip_list *sl) |
| Get the priority tuple of the first item in the skip list. More... | |
| const void * | skip_list_peek_head (struct skip_list *sl) |
| Get the first item in the skip list without removing it. More... | |
| void * | skip_list_pop_head (struct skip_list *sl) |
| Remove and return the first item in the skip list. More... | |
| struct skip_list_cursor * | skip_list_cursor_create (struct skip_list *sl) |
| Create a cursor for traversing a skip list. More... | |
| void | skip_list_cursor_delete (struct skip_list_cursor *cur) |
| Delete a previously created cursor. More... | |
| struct skip_list_cursor * | skip_list_cursor_clone (struct skip_list_cursor *cur) |
| Get a copy of an existing cursor. More... | |
| void | skip_list_cursor_move (struct skip_list_cursor *to_move, struct skip_list_cursor *destination) |
| Move a cursor's position to match another cursor. More... | |
| void | skip_list_reset (struct skip_list_cursor *cur) |
| Reset the position of a cursor. More... | |
| bool | skip_list_seek (struct skip_list_cursor *cur, int index) |
| Move a cursor to an item by index. More... | |
| bool | skip_list_tell (struct skip_list_cursor *cur, unsigned *index) |
| Get the position of a cursor within a skip list. More... | |
| bool | skip_list_next (struct skip_list_cursor *cur) |
| Move a cursor to the next item. More... | |
| bool | skip_list_prev (struct skip_list_cursor *cur) |
| Move a cursor to the previous item. More... | |
| bool | skip_list_cursor_move_to_priority_arr (struct skip_list_cursor *cur, double *priority) |
| Move a cursor to the first item with the given priority tuple (internal function). More... | |
| bool | skip_list_get (struct skip_list_cursor *cur, void **item) |
| Get the item under a cursor. More... | |
| const double * | skip_list_get_priority (struct skip_list_cursor *cur) |
| Get the priority tuple of the item under a cursor. More... | |
| bool | skip_list_set (struct skip_list_cursor *cur, void *item) |
| Set the value under the cursor. More... | |
| bool | skip_list_remove_here (struct skip_list_cursor *cur) |
| Remove the item under the cursor. More... | |
| bool | skip_list_remove (struct skip_list *sl, void *data) |
| Remove the first node found with the given data pointer. More... | |
| bool | skip_list_remove_by_priority_arr (struct skip_list *sl, double *priority) |
| Remove the first node found with the given priority tuple. More... | |
| void | skip_list_insert_arr (struct skip_list *lst, void *item, double *priority) |
| Insert an item with priority into the skip list (internal function). More... | |
Skip list structure built on top of list.h
A skip list is a probabilistic data structure that allows O(log n) search, insertion, and deletion. This implementation uses multiple levels of linked lists, where each level contains ceil(log(n)) elements from the level below.
Items are stored sorted by priority tuples in descending order (highest priority first). Priority tuples are compared lexicographically.
Example: Creating and populating a skip list with 2-element priority tuples
struct skip_list *sl = skip_list_create(2, 0.5); // 2-element priority tuples, 0.5 probability struct skip_list_cursor *cur = skip_list_cursor_create(sl); char *apple = "apple", *banana = "banana", *cherry = "cherry";
skip_list_insert(cur, apple, 10.0, 5.0); // Priority: (10.0, 5.0) skip_list_insert(cur, banana, 20.0, 3.0); // Priority: (20.0, 3.0) - highest skip_list_insert(cur, cherry, 10.0, 8.0); // Priority: (10.0, 8.0)
skip_list_cursor_delete(cur); skip_list_delete(sl);
Example: Iterating through all items (in priority order)
struct skip_list_cursor *cur = skip_list_cursor_create(sl); skip_list_seek(cur, 0);
void *item;
do {
if (skip_list_get(cur, &item)) {
printf("%s\n", (char *)item); // Prints: banana, cherry, apple
}
} while (skip_list_next(cur));skip_list_cursor_delete(cur);
| #define skip_list_cursor_move_to_priority | ( | cur, | |
| ... | |||
| ) | skip_list_cursor_move_to_priority_arr(cur, (double[]){__VA_ARGS__}) |
Move a cursor to the first item with the given priority tuple.
This uses the skip list structure for faster O(log n) lookup. Priority values should be passed as doubles matching the priority_size from skip_list_create.
| cur | The cursor to move. |
| ... | Priority values (doubles) matching the priority_size. |
| #define skip_list_remove_by_priority | ( | sl, | |
| ... | |||
| ) | skip_list_remove_by_priority_arr(sl, (double[]){__VA_ARGS__}) |
Remove the first node found with the given priority tuple.
This uses the skip list structure for faster O(log n) lookup.
| sl | The skip list to search. |
| ... | Priority values (doubles) matching the priority_size. |
| #define skip_list_insert | ( | lst, | |
| item, | |||
| ... | |||
| ) | skip_list_insert_arr(lst, item, (double[]){__VA_ARGS__}) |
Insert an item with priority into the skip list.
Items are automatically inserted in sorted order by priority (high to low). Priority values should be passed as doubles matching the priority_size from skip_list_create.
Example for priority_size=2: skip_list_insert(cur, data, 10.0, 5.0);
Example for priority_size=3: skip_list_insert(cur, data, 10.0, 5.0, 2.5);
| lst | The skip list to insert into. |
| item | The pointer to insert. |
| ... | Priority values (doubles) matching the priority_size. |
| #define SKIP_LIST_ITERATE | ( | cursor, | |
| item | |||
| ) | for(; skip_list_get(cursor, (void **)&item); skip_list_next(cursor)) |
Iterate over all items in a skip list (highest to lowest priority).
These macros provide a convenient way to iterate over all items while maintaining a cursor that points to the current item during each iteration.
| cursor | A pre-existing cursor (struct skip_list_cursor *) that will be positioned at each item during iteration. Can be used to modify or remove the current item. Iteration starts at the position of that the cursor is currently at. |
| item | A pointer variable that will receive each item's data. |
Example usage:
struct skip_list *sl = skip_list_create(1, 0.5); struct skip_list_cursor *cur = skip_list_cursor_create(sl); struct my_data *data;
// Insert some items...
skip_list_seek(cur, 0);
SKIP_LIST_ITERATE_START(cur, data)
printf("Processing: %s\n", data->name);
if (should_remove(data)) {
skip_list_remove_here(cur);
}
SKIP_LIST_ITERATE_END(cur)skip_list_cursor_delete(cur);
| struct skip_list* skip_list_create | ( | unsigned | priority_size, |
| double | probability | ||
| ) |
Create an empty skip list with priority-based sorting.
Items are sorted by priority tuples in descending (high to low) order. Priority tuples are compared lexicographically.
| priority_size | The number of doubles in each priority tuple. |
| probability | The probability (0 < p <= 0.5) of promoting an item to the next level (default: 0.5). |
| bool skip_list_delete | ( | struct skip_list * | sl | ) |
Delete a skip list.
The caller is responsible for removing all items before deleting. If the skip list is non-empty or there are living cursors, this call fails.
| sl | The skip list to delete. |
| int skip_list_size | ( | struct skip_list * | sl | ) |
Get the number of items in a skip list.
| sl | The skip list to examine. |
| const double* skip_list_peek_head_priority | ( | struct skip_list * | sl | ) |
Get the priority tuple of the first item in the skip list.
| sl | The skip list to examine. |
| const void* skip_list_peek_head | ( | struct skip_list * | sl | ) |
Get the first item in the skip list without removing it.
| sl | The skip list to examine. |
| void* skip_list_pop_head | ( | struct skip_list * | sl | ) |
Remove and return the first item in the skip list.
| sl | The skip list to examine. |
| struct skip_list_cursor* skip_list_cursor_create | ( | struct skip_list * | sl | ) |
Create a cursor for traversing a skip list.
| sl | The skip list to create a cursor for. |
| void skip_list_cursor_delete | ( | struct skip_list_cursor * | cur | ) |
Delete a previously created cursor.
| cur | The cursor to free. |
| struct skip_list_cursor* skip_list_cursor_clone | ( | struct skip_list_cursor * | cur | ) |
Get a copy of an existing cursor.
| cur | The cursor to clone. |
| void skip_list_cursor_move | ( | struct skip_list_cursor * | to_move, |
| struct skip_list_cursor * | destination | ||
| ) |
Move a cursor's position to match another cursor.
After this call, to_move will point to the same item as destination.
| to_move | The cursor whose position will be updated. |
| destination | The source cursor whose position will be copied. |
| void skip_list_reset | ( | struct skip_list_cursor * | cur | ) |
Reset the position of a cursor.
| cur | The cursor to reset. |
| bool skip_list_seek | ( | struct skip_list_cursor * | cur, |
| int | index | ||
| ) |
Move a cursor to an item by index.
| cur | The cursor to move. |
| index | The position (negative indices from the tail). |
| bool skip_list_tell | ( | struct skip_list_cursor * | cur, |
| unsigned * | index | ||
| ) |
Get the position of a cursor within a skip list.
| cur | The cursor to check. |
| index | The location to store the index. |
| bool skip_list_next | ( | struct skip_list_cursor * | cur | ) |
Move a cursor to the next item.
| cur | The cursor to move. |
| bool skip_list_prev | ( | struct skip_list_cursor * | cur | ) |
Move a cursor to the previous item.
| cur | The cursor to move. |
| bool skip_list_cursor_move_to_priority_arr | ( | struct skip_list_cursor * | cur, |
| double * | priority | ||
| ) |
Move a cursor to the first item with the given priority tuple (internal function).
This uses the skip list structure for faster O(log n) lookup. Use the skip_list_cursor_move_to_priority macro instead of calling this directly.
| cur | The cursor to move. |
| priority | Array of doubles representing the priority tuple to find. |
| bool skip_list_get | ( | struct skip_list_cursor * | cur, |
| void ** | item | ||
| ) |
Get the item under a cursor.
| cur | The cursor to look at. |
| item | The location to store the value. |
| const double* skip_list_get_priority | ( | struct skip_list_cursor * | cur | ) |
Get the priority tuple of the item under a cursor.
| cur | The cursor to look at. |
| bool skip_list_set | ( | struct skip_list_cursor * | cur, |
| void * | item | ||
| ) |
Set the value under the cursor.
| cur | The cursor position to set. |
| item | The value to set. |
| bool skip_list_remove_here | ( | struct skip_list_cursor * | cur | ) |
Remove the item under the cursor.
| cur | The cursor to use. |
| bool skip_list_remove | ( | struct skip_list * | sl, |
| void * | data | ||
| ) |
Remove the first node found with the given data pointer.
| sl | The skip list to search. |
| data | The data pointer to find and remove. |
| bool skip_list_remove_by_priority_arr | ( | struct skip_list * | sl, |
| double * | priority | ||
| ) |
Remove the first node found with the given priority tuple.
This uses the skip list structure for faster O(log n) lookup.
| sl | The skip list to search. |
| priority | Array of doubles representing the priority tuple to find and remove. |
| void skip_list_insert_arr | ( | struct skip_list * | lst, |
| void * | item, | ||
| double * | priority | ||
| ) |
Insert an item with priority into the skip list (internal function).
Items are inserted in sorted order by priority (descending). Use the skip_list_insert macro instead of calling this directly.
| lst | The skip list to insert into. |
| item | The pointer to insert. |
| priority | Array of doubles representing the priority tuple. |