The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
Doubly linked list implementation. More...
#include <freeradius-devel/build.h>
#include <freeradius-devel/missing.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/talloc.h>
Go to the source code of this file.
Data Structures | |
struct | fr_dlist_head_t |
Head of a doubly linked list. More... | |
struct | fr_dlist_s |
Entry in a doubly linked list. More... | |
Macros | |
#define | CHECK_ELEMENT_COUNT(_head, _add) |
Verify we're not going to overflow the element count. More... | |
#define | FR_DLIST_ENTRY(_name) _name ## _entry_t |
Expands to the type name used for the entry wrapper structure. More... | |
#define | FR_DLIST_ENTRY_INITIALISER(_entry) { .next = &_entry, .prev = &_entry } |
Static initialiser for entries. More... | |
#define | fr_dlist_foreach(_list_head, _type, _iter) for (_type *_iter = fr_dlist_head(_list_head); _iter; _iter = fr_dlist_next(_list_head, _iter)) |
Iterate over the contents of a list. More... | |
#define | fr_dlist_foreach_safe(_list_head, _type, _iter) |
Iterate over the contents of a list allowing for removals. More... | |
#define | FR_DLIST_FUNCS(_name, _element_type, _element_entry) |
Define type specific wrapper functions for dlists. More... | |
#define | FR_DLIST_HEAD(_name) _name ## _head_t |
Expands to the type name used for the head wrapper structure. More... | |
#define | FR_DLIST_HEAD_INITIALISER(_head) { .entry = FR_DLIST_ENTRY_INITIALISER((_head).entry) } |
Static initialiser for list heads. More... | |
#define | fr_dlist_init(_head, _type, _field) _Generic((((_type *)0)->_field), fr_dlist_t: _fr_dlist_init(_head, offsetof(_type, _field), NULL)) |
Initialise the head structure of a doubly linked list. More... | |
#define | fr_dlist_talloc_init(_head, _type, _field) _Generic((((_type *)0)->_field), fr_dlist_t: _fr_dlist_init(_head, offsetof(_type, _field), #_type)) |
Initialise the head structure of a doubly linked list. More... | |
#define | FR_DLIST_TYPEDEFS(_name, _head, _entry) |
Define friendly names for type specific dlist head and entry structures. More... | |
#define | FR_DLIST_TYPES(_name) |
Define type specific wrapper structs for dlists. More... | |
#define | fr_dlist_verify(_head) _fr_dlist_verify(__FILE__, __LINE__, _head) |
Typedefs | |
typedef struct fr_dlist_s | fr_dlist_t |
Functions | |
static void | _fr_dlist_init (fr_dlist_head_t *list_head, size_t offset, char const *type) |
Initialise common fields in a dlist. More... | |
static void | _fr_dlist_verify (char const *file, int line, fr_dlist_head_t const *list_head) |
Check all items in the list are valid. More... | |
static void | fr_dlist_clear (fr_dlist_head_t *list_head) |
Efficiently remove all elements in a dlist. More... | |
static bool | fr_dlist_empty (fr_dlist_head_t const *list_head) |
Check whether a list has any items. More... | |
static bool | fr_dlist_entry_in_list (fr_dlist_t const *entry) |
Check if a list entry is part of a list. More... | |
static void | fr_dlist_entry_init (fr_dlist_t *entry) |
Initialise a linked list without metadata. More... | |
static void | fr_dlist_entry_link_after (fr_dlist_t *entry, fr_dlist_t *to_link) |
Link in a single entry after the current entry. More... | |
static void | fr_dlist_entry_link_before (fr_dlist_t *entry, fr_dlist_t *to_link) |
Link in a single entry before the current entry. More... | |
static void | fr_dlist_entry_move (fr_dlist_t *dst, fr_dlist_t *src) |
Link in a sublist before the current entry. More... | |
static void | fr_dlist_entry_replace (fr_dlist_t *entry, fr_dlist_t *replacement) |
Replace one entry with another. More... | |
static void * | fr_dlist_entry_to_item (size_t offset, fr_dlist_t const *entry) |
Get the item from a fr_dlist_t. More... | |
static void | fr_dlist_entry_unlink (fr_dlist_t *entry) |
Remove an item from the dlist when we don't have access to the head. More... | |
static void * | fr_dlist_head (fr_dlist_head_t const *list_head) |
Return the HEAD item of a list or NULL if the list is empty. More... | |
static bool | fr_dlist_in_list (fr_dlist_head_t *list_head, void *ptr) |
Check if a list entry is part of a list. More... | |
static bool | fr_dlist_initialised (fr_dlist_head_t const *list_head) |
Check if the list head is initialised. More... | |
static int | fr_dlist_insert_after (fr_dlist_head_t *list_head, void *pos, void *ptr) |
Insert an item after an item already in the list. More... | |
static int | fr_dlist_insert_before (fr_dlist_head_t *list_head, void *pos, void *ptr) |
Insert an item before an item already in the list. More... | |
static int | fr_dlist_insert_head (fr_dlist_head_t *list_head, void *ptr) |
Insert an item into the head of a list. More... | |
static int | fr_dlist_insert_tail (fr_dlist_head_t *list_head, void *ptr) |
Insert an item into the tail of a list. More... | |
static fr_dlist_t * | fr_dlist_item_to_entry (size_t offset, void const *item) |
Find the dlist pointers within a list item. More... | |
static int | fr_dlist_move (fr_dlist_head_t *list_dst, fr_dlist_head_t *list_src) |
Merge two lists, inserting the source at the tail of the destination. More... | |
static int | fr_dlist_move_head (fr_dlist_head_t *list_dst, fr_dlist_head_t *list_src) |
Merge two lists, inserting the source at the head of the destination. More... | |
static void * | fr_dlist_next (fr_dlist_head_t const *list_head, void const *ptr) |
Get the next item in a list. More... | |
static void | fr_dlist_noop (void) |
static unsigned int | fr_dlist_num_elements (fr_dlist_head_t const *head) |
Return the number of elements in the dlist. More... | |
static void * | fr_dlist_pop_head (fr_dlist_head_t *list_head) |
Remove the head item in a list. More... | |
static void * | fr_dlist_pop_tail (fr_dlist_head_t *list_head) |
Remove the tail item in a list. More... | |
static void * | fr_dlist_prev (fr_dlist_head_t const *list_head, void const *ptr) |
Get the previous item in a list. More... | |
static void | fr_dlist_recursive_sort (fr_dlist_head_t *head, void **ptr, fr_cmp_t cmp) |
Recursive sort routine for dlist. More... | |
static void * | fr_dlist_remove (fr_dlist_head_t *list_head, void *ptr) |
Remove an item from the list. More... | |
static void * | fr_dlist_replace (fr_dlist_head_t *list_head, void *item, void *ptr) |
Replace an item in a dlist. More... | |
static void | fr_dlist_sort (fr_dlist_head_t *list, fr_cmp_t cmp) |
Sort a dlist using merge sort. More... | |
static void * | fr_dlist_sort_merge (fr_dlist_head_t *head, void **a, void **b, fr_cmp_t cmp) |
Merge phase of a merge sort of a dlist. More... | |
static void | fr_dlist_sort_split (fr_dlist_head_t *head, void **source, void **front, void **back) |
Split phase of a merge sort of a dlist. More... | |
static void * | fr_dlist_tail (fr_dlist_head_t const *list_head) |
Return the TAIL item of a list or NULL if the list is empty. More... | |
static void | fr_dlist_talloc_free (fr_dlist_head_t *head) |
Free all items in a doubly linked list (with talloc) More... | |
static void | fr_dlist_talloc_free_head (fr_dlist_head_t *list_head) |
Free the first item in the list. More... | |
static void * | fr_dlist_talloc_free_item (fr_dlist_head_t *list_head, void *ptr) |
Free the item specified. More... | |
static void | fr_dlist_talloc_free_tail (fr_dlist_head_t *list_head) |
Free the last item in the list. More... | |
static void | fr_dlist_talloc_free_to_tail (fr_dlist_head_t *head, void *ptr) |
Free items in a doubly linked list (with talloc) More... | |
static void | fr_dlist_talloc_reverse_free (fr_dlist_head_t *head) |
Free all items in a doubly linked list from the tail backwards. More... | |
Doubly linked list implementation.
Definition in file dlist.h.
struct fr_dlist_head_t |
Head of a doubly linked list.
Holds additional information about the list items, like at which offset the next/prev pointers can be found.
Data Fields | ||
---|---|---|
fr_dlist_t | entry |
Struct holding the head and tail of the list. First for efficient traversal. |
unsigned int | num_elements | Number of elements contained within the dlist. |
unsigned int | offset |
Positive offset from start of structure to fr_dlist_t. Yes, this should really be size_t, but we shave 8 bytes off each head structure by making it unsigned int. |
char const * | type |
of items contained within the list. Used for talloc validation. |
struct fr_dlist_s |
#define CHECK_ELEMENT_COUNT | ( | _head, | |
_add | |||
) |
Verify we're not going to overflow the element count.
#define FR_DLIST_ENTRY | ( | _name | ) | _name ## _entry_t |
#define fr_dlist_foreach | ( | _list_head, | |
_type, | |||
_iter | |||
) | for (_type *_iter = fr_dlist_head(_list_head); _iter; _iter = fr_dlist_next(_list_head, _iter)) |
#define fr_dlist_foreach_safe | ( | _list_head, | |
_type, | |||
_iter | |||
) |
Iterate over the contents of a list allowing for removals.
}}
. We need to use another scoping section as we can't declare variables of multiple types within the initialiser of a for loop.[in] | _list_head | to iterate over. |
[in] | _type | of item the list contains. |
[in] | _iter | Name of iteration variable. Will be declared in the scope of the loop. |
#define FR_DLIST_FUNCS | ( | _name, | |
_element_type, | |||
_element_entry | |||
) |
Define type specific wrapper functions for dlists.
[in] | _name | Prefix we add to type-specific dlist functions. |
[in] | _element_type | Type of structure that'll be inserted into the dlist. |
[in] | _element_entry | Field in the _element_type that holds the dlist entry information. |
#define FR_DLIST_HEAD | ( | _name | ) | _name ## _head_t |
#define FR_DLIST_HEAD_INITIALISER | ( | _head | ) | { .entry = FR_DLIST_ENTRY_INITIALISER((_head).entry) } |
Static initialiser for list heads.
[in] | _head | what's being initialised. |
#define fr_dlist_init | ( | _head, | |
_type, | |||
_field | |||
) | _Generic((((_type *)0)->_field), fr_dlist_t: _fr_dlist_init(_head, offsetof(_type, _field), NULL)) |
Initialise the head structure of a doubly linked list.
[in] | _head | structure to initialise. |
[in] | _type | of item being stored in the list, e.g. fr_value_box_t, fr_dict_attr_t etc... |
[in] | _field | Containing the fr_dlist_t within item being stored. |
#define fr_dlist_talloc_init | ( | _head, | |
_type, | |||
_field | |||
) | _Generic((((_type *)0)->_field), fr_dlist_t: _fr_dlist_init(_head, offsetof(_type, _field), #_type)) |
Initialise the head structure of a doubly linked list.
Initialise the head structure of a doubly linked list.
[in] | _head | structure to initialise. |
[in] | _type | of item being stored in the list, e.g. fr_value_box_t, fr_dict_attr_t etc... |
[in] | _field | Containing the fr_dlist_t within item being stored. |
#define FR_DLIST_TYPEDEFS | ( | _name, | |
_head, | |||
_entry | |||
) |
Define friendly names for type specific dlist head and entry structures.
[in] | _name | Prefix we add to type-specific structures. |
[in] | _head | Name to use for head structure. |
[in] | _entry | Name to use for entry structure. |
#define FR_DLIST_TYPES | ( | _name | ) |
Define type specific wrapper structs for dlists.
#define fr_dlist_verify | ( | _head | ) | _fr_dlist_verify(__FILE__, __LINE__, _head) |
typedef struct fr_dlist_s fr_dlist_t |
|
inlinestatic |
|
inlinestatic |
Check all items in the list are valid.
Checks item talloc headers and types to ensure they're consistent with what we expect.
Does nothing if the list was not initialised with fr_dlist_talloc_init.
Definition at line 735 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Check if a list entry is part of a list.
This works because the fr_dlist_head_t has an entry in the list. So if next and prev both point to the entry for the object being passed in, then it can't be part of a list with a fr_dlist_head_t.
Definition at line 163 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Link in a sublist before the current entry.
[in] | dst | to link src in before. |
[in] | src | to link in before dst. |
Definition at line 206 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Check if a list entry is part of a list.
This works because the fr_dlist_head_t has an entry in the list. So if next and prev both point to the entry for the object being passed in, then it can't be part of a list with a fr_dlist_head_t.
Definition at line 320 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
Insert an item after an item already in the list.
[in] | list_head | to insert ptr into. |
[in] | pos | to insert ptr after. |
[in] | ptr | to insert. |
Definition at line 414 of file dlist.h.
|
inlinestatic |
Insert an item before an item already in the list.
[in] | list_head | to insert ptr into. |
[in] | pos | to insert ptr before. |
[in] | ptr | to insert. |
Definition at line 450 of file dlist.h.
|
inlinestatic |
Insert an item into the head of a list.
[in] | list_head | to insert ptr into. |
[in] | ptr | to insert. |
Definition at line 338 of file dlist.h.
|
inlinestatic |
Insert an item into the tail of a list.
[in] | list_head | to insert ptr into. |
[in] | ptr | to insert. |
Definition at line 378 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Get the next item in a list.
[in] | list_head | containing ptr. |
[in] | ptr | to retrieve the next item from. If ptr is NULL, the HEAD of the list will be returned. |
Definition at line 555 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Get the previous item in a list.
[in] | list_head | containing ptr. |
[in] | ptr | to retrieve the previous item to. If ptr is NULL, the TAIL of the list will be returned. |
Definition at line 588 of file dlist.h.
|
inlinestatic |
Recursive sort routine for dlist.
[in] | head | of the list being sorted |
[in,out] | ptr | to the first item in the current section of the list being sorted. |
[in] | cmp | comparison function to sort with |
Definition at line 1038 of file dlist.h.
|
inlinestatic |
Remove an item from the list.
When removing items in an iteration loop, the iterator variable must be assigned the item returned by this function.
If the iterator variable is not updated, the item removed will be the last item iterated over, as its next/prev pointers are set to point to itself.
[in] | list_head | to remove ptr from. |
[in] | ptr | to remove. |
Definition at line 638 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
Sort a dlist using merge sort.
[in,out] | list | to sort |
[in] | cmp | comparison function to sort with |
Definition at line 1064 of file dlist.h.
|
inlinestatic |
Merge phase of a merge sort of a dlist.
[in] | head | of the original list being sorted |
[in] | a | first element of first list being merged |
[in] | b | first element of second list being merged |
[in] | cmp | comparison function for the sort |
Definition at line 1002 of file dlist.h.
|
inlinestatic |
Split phase of a merge sort of a dlist.
[in] | head | of the original list being sorted |
[in] | source | first item in the section of the list to split |
[out] | front | first item of the first half of the split list |
[out] | back | first item of the second half of the split list |
Definition at line 953 of file dlist.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |