mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 08:23:56 +00:00
lib: add proper doc comments for hash & linklist
* Remove references to ospf source files from linklist.[ch] * Remove documentation comments from hash.c and linklist.c * Add comprehensive documentation comments to linklist.h and hash.h Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
91f1037064
commit
6fd8c487e1
18
lib/hash.c
18
lib/hash.c
@ -36,7 +36,6 @@ DEFINE_MTYPE_STATIC(LIB, HASH_INDEX, "Hash Index")
|
||||
pthread_mutex_t _hashes_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct list *_hashes;
|
||||
|
||||
/* Allocate a new hash. */
|
||||
struct hash *hash_create_size(unsigned int size,
|
||||
unsigned int (*hash_key)(void *),
|
||||
int (*hash_cmp)(const void *, const void *),
|
||||
@ -67,7 +66,6 @@ struct hash *hash_create_size(unsigned int size,
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* Allocate a new hash with default hash size. */
|
||||
struct hash *hash_create(unsigned int (*hash_key)(void *),
|
||||
int (*hash_cmp)(const void *, const void *),
|
||||
const char *name)
|
||||
@ -75,9 +73,6 @@ struct hash *hash_create(unsigned int (*hash_key)(void *),
|
||||
return hash_create_size(HASH_INITIAL_SIZE, hash_key, hash_cmp, name);
|
||||
}
|
||||
|
||||
/* Utility function for hash_get(). When this function is specified
|
||||
as alloc_func, return arugment as it is. This function is used for
|
||||
intern already allocated value. */
|
||||
void *hash_alloc_intern(void *arg)
|
||||
{
|
||||
return arg;
|
||||
@ -133,9 +128,6 @@ static void hash_expand(struct hash *hash)
|
||||
hash->index = new_index;
|
||||
}
|
||||
|
||||
/* Lookup and return hash backet in hash. If there is no
|
||||
corresponding hash backet and alloc_func is specified, create new
|
||||
hash backet. */
|
||||
void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
|
||||
{
|
||||
unsigned int key;
|
||||
@ -189,13 +181,11 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Hash lookup. */
|
||||
void *hash_lookup(struct hash *hash, void *data)
|
||||
{
|
||||
return hash_get(hash, data, NULL);
|
||||
}
|
||||
|
||||
/* Simple Bernstein hash which is simple and fast for common case */
|
||||
unsigned int string_hash_make(const char *str)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
@ -206,9 +196,6 @@ unsigned int string_hash_make(const char *str)
|
||||
return hash;
|
||||
}
|
||||
|
||||
/* This function release registered value from specified hash. When
|
||||
release is successfully finished, return the data pointer in the
|
||||
hash backet. */
|
||||
void *hash_release(struct hash *hash, void *data)
|
||||
{
|
||||
void *ret;
|
||||
@ -248,7 +235,6 @@ void *hash_release(struct hash *hash, void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Iterator function for hash. */
|
||||
void hash_iterate(struct hash *hash, void (*func)(struct hash_backet *, void *),
|
||||
void *arg)
|
||||
{
|
||||
@ -266,7 +252,6 @@ void hash_iterate(struct hash *hash, void (*func)(struct hash_backet *, void *),
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterator function for hash. */
|
||||
void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
|
||||
void *arg)
|
||||
{
|
||||
@ -288,7 +273,6 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up hash. */
|
||||
void hash_clean(struct hash *hash, void (*free_func)(void *))
|
||||
{
|
||||
unsigned int i;
|
||||
@ -327,8 +311,6 @@ struct list *hash_to_list(struct hash *hash)
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Free hash memory. You may call hash_clean before call this
|
||||
function. */
|
||||
void hash_free(struct hash *hash)
|
||||
{
|
||||
pthread_mutex_lock(&_hashes_mtx);
|
||||
|
235
lib/hash.h
235
lib/hash.h
@ -36,9 +36,10 @@ DECLARE_MTYPE(HASH_BACKET)
|
||||
#define HASHWALK_ABORT -1
|
||||
|
||||
struct hash_backet {
|
||||
/* if this backet is the head of the linked listed, len denotes the
|
||||
* number of
|
||||
* elements in the list */
|
||||
/*
|
||||
* if this backet is the head of the linked listed, len denotes the
|
||||
* number of elements in the list
|
||||
*/
|
||||
int len;
|
||||
|
||||
/* Linked list. */
|
||||
@ -85,38 +86,232 @@ struct hash {
|
||||
|
||||
#define hashcount(X) ((X)->count)
|
||||
|
||||
extern struct hash *hash_create(unsigned int (*)(void *),
|
||||
int (*)(const void *, const void *),
|
||||
const char *);
|
||||
extern struct hash *hash_create_size(unsigned int, unsigned int (*)(void *),
|
||||
int (*)(const void *, const void *),
|
||||
const char *);
|
||||
/*
|
||||
* Create a hash table.
|
||||
*
|
||||
* The created hash table uses chaining and a user-provided comparator function
|
||||
* to resolve collisions. For best performance use a perfect hash function.
|
||||
* Worst case lookup time is O(N) when using a constant hash function. Best
|
||||
* case lookup time is O(1) when using a perfect hash function.
|
||||
*
|
||||
* The initial size of the created hash table is HASH_INITIAL_SIZE.
|
||||
*
|
||||
* hash_key
|
||||
* hash function to use; should return a unique unsigned integer when called
|
||||
* with a data item. Collisions are acceptable.
|
||||
*
|
||||
* hash_cmp
|
||||
* comparison function used for resolving collisions; when called with two
|
||||
* data items, should return nonzero if the two items are equal and 0
|
||||
* otherwise
|
||||
*
|
||||
* name
|
||||
* optional name for the hashtable; this is used when displaying global
|
||||
* hashtable statistics. If this parameter is NULL the hash's name will be
|
||||
* set to NULL and the default name will be displayed when showing
|
||||
* statistics.
|
||||
*
|
||||
* Returns:
|
||||
* a new hash table
|
||||
*/
|
||||
extern struct hash *hash_create(unsigned int (*hash_key)(void *),
|
||||
int (*hash_cmp)(const void *, const void *),
|
||||
const char *name);
|
||||
|
||||
extern void *hash_get(struct hash *, void *, void *(*)(void *));
|
||||
extern void *hash_alloc_intern(void *);
|
||||
extern void *hash_lookup(struct hash *, void *);
|
||||
extern void *hash_release(struct hash *, void *);
|
||||
/*
|
||||
* Create a hash table.
|
||||
*
|
||||
* The created hash table uses chaining and a user-provided comparator function
|
||||
* to resolve collisions. For best performance use a perfect hash function.
|
||||
* Worst case lookup time is O(N) when using a constant hash function. Best
|
||||
* case lookup time is O(1) when using a perfect hash function.
|
||||
*
|
||||
* size
|
||||
* initial number of hash buckets to allocate; must be a power of 2 or the
|
||||
* program will assert
|
||||
*
|
||||
* hash_key
|
||||
* hash function to use; should return a unique unsigned integer when called
|
||||
* with a data item. Collisions are acceptable.
|
||||
*
|
||||
* hash_cmp
|
||||
* comparison function used for resolving collisions; when called with two
|
||||
* data items, should return nonzero if the two items are equal and 0
|
||||
* otherwise
|
||||
*
|
||||
* name
|
||||
* optional name for the hashtable; this is used when displaying global
|
||||
* hashtable statistics. If this parameter is NULL the hash's name will be
|
||||
* set to NULL and the default name will be displayed when showing
|
||||
* statistics.
|
||||
*
|
||||
* Returns:
|
||||
* a new hash table
|
||||
*/
|
||||
extern struct hash *
|
||||
hash_create_size(unsigned int size, unsigned int (*hash_key)(void *),
|
||||
int (*hash_cmp)(const void *, const void *), const char *name);
|
||||
|
||||
extern void hash_iterate(struct hash *, void (*)(struct hash_backet *, void *),
|
||||
void *);
|
||||
/*
|
||||
* Retrieve or insert data from / into a hash table.
|
||||
*
|
||||
* This function is somewhat counterintuitive in its usage. In order to look up
|
||||
* an element from its key, you must provide the data item itself, with the
|
||||
* portions used in the hash function set to the same values as the data item
|
||||
* to retrieve. To insert a data element, either provide the key as just
|
||||
* described and provide alloc_func as descrbied below to allocate the full
|
||||
* data element, or provide the full data element and pass 'hash_alloc_intern'
|
||||
* to alloc_func.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* data
|
||||
* data to insert or retrieve
|
||||
*
|
||||
* alloc_func
|
||||
* function to call if the item is not found in the hash table. This
|
||||
* function is called with the value of 'data' and should create the data
|
||||
* item to insert and return a pointer to it. If the data has already been
|
||||
* completely created and provided in the 'data' parameter, passing
|
||||
* 'hash_alloc_intern' to this parameter will cause 'data' to be inserted.
|
||||
* If this parameter is NULL, then this call to hash_get is equivalent to
|
||||
* hash_lookup.
|
||||
*
|
||||
* Returns:
|
||||
* the data item found or inserted, or NULL if alloc_func is NULL and the
|
||||
* data is not found
|
||||
*/
|
||||
extern void *hash_get(struct hash *hash, void *data,
|
||||
void *(*alloc_func)(void *));
|
||||
|
||||
extern void hash_walk(struct hash *, int (*)(struct hash_backet *, void *),
|
||||
void *);
|
||||
/*
|
||||
* Dummy element allocation function.
|
||||
*
|
||||
* See hash_get for details.
|
||||
*
|
||||
* data
|
||||
* data to insert into the hash table
|
||||
*
|
||||
* Returns:
|
||||
* data
|
||||
*/
|
||||
extern void *hash_alloc_intern(void *data);
|
||||
|
||||
extern void hash_clean(struct hash *, void (*)(void *));
|
||||
extern void hash_free(struct hash *);
|
||||
/*
|
||||
* Retrieve an item from a hash table.
|
||||
*
|
||||
* This function is equivalent to calling hash_get with alloc_func set to NULL.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* data
|
||||
* data element with values used for key computation set
|
||||
*
|
||||
* Returns:
|
||||
* the data element if found, or NULL if not found
|
||||
*/
|
||||
extern void *hash_lookup(struct hash *hash, void *data);
|
||||
|
||||
/*
|
||||
* Remove an element from a hash table.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* data
|
||||
* data element to remove with values used for key computation set
|
||||
*
|
||||
* Returns:
|
||||
* the removed element if found, or NULL if not found
|
||||
*/
|
||||
extern void *hash_release(struct hash *hash, void *data);
|
||||
|
||||
/*
|
||||
* Iterate over the elements in a hash table.
|
||||
*
|
||||
* It is safe to delete items passed to the iteration function from the hash
|
||||
* table during iteration.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* func
|
||||
* function to call with each data item
|
||||
*
|
||||
* arg
|
||||
* arbitrary argument passed as the second parameter in each call to 'func'
|
||||
*/
|
||||
extern void hash_iterate(struct hash *hash,
|
||||
void (*func)(struct hash_backet *, void *), void *arg);
|
||||
|
||||
/*
|
||||
* Iterate over the elements in a hash table, stopping on condition.
|
||||
*
|
||||
* It is safe to delete items passed to the iteration function from the hash
|
||||
* table during iteration.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* func
|
||||
* function to call with each data item. If this function returns
|
||||
* HASHWALK_ABORT then the iteration stops.
|
||||
*
|
||||
* arg
|
||||
* arbitrary argument passed as the second parameter in each call to 'func'
|
||||
*/
|
||||
extern void hash_walk(struct hash *hash,
|
||||
int (*func)(struct hash_backet *, void *), void *arg);
|
||||
|
||||
/*
|
||||
* Remove all elements from a hash table.
|
||||
*
|
||||
* hash
|
||||
* hash table to operate on
|
||||
*
|
||||
* free_func
|
||||
* function to call with each removed item; intended to free the data
|
||||
*/
|
||||
extern void hash_clean(struct hash *hash, void (*free_func)(void *));
|
||||
|
||||
/*
|
||||
* Delete a hash table.
|
||||
*
|
||||
* This function assumes the table is empty. Call hash_clean to delete the
|
||||
* hashtable contents if necessary.
|
||||
*
|
||||
* hash
|
||||
* hash table to delete
|
||||
*/
|
||||
extern void hash_free(struct hash *hash);
|
||||
|
||||
/*
|
||||
* Converts a hash table to an unsorted linked list.
|
||||
* Does not modify the hash table in any way.
|
||||
*
|
||||
* hash
|
||||
* the hash to convert
|
||||
* hash table to convert
|
||||
*/
|
||||
extern struct list *hash_to_list(struct hash *hash);
|
||||
|
||||
/*
|
||||
* Hash a string using the modified Bernstein hash.
|
||||
*
|
||||
* This is not a perfect hash function.
|
||||
*
|
||||
* str
|
||||
* string to hash
|
||||
*
|
||||
* Returns:
|
||||
* modified Bernstein hash of the string
|
||||
*/
|
||||
extern unsigned int string_hash_make(const char *);
|
||||
|
||||
/*
|
||||
* Install CLI commands for viewing global hash table statistics.
|
||||
*/
|
||||
extern void hash_cmd_init(void);
|
||||
|
||||
#endif /* _ZEBRA_HASH_H */
|
||||
|
@ -27,7 +27,6 @@
|
||||
DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List")
|
||||
DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node")
|
||||
|
||||
/* Allocate new list. */
|
||||
struct list *list_new(void)
|
||||
{
|
||||
return XCALLOC(MTYPE_LINK_LIST, sizeof(struct list));
|
||||
@ -51,7 +50,6 @@ static void listnode_free(struct listnode *node)
|
||||
XFREE(MTYPE_LINK_NODE, node);
|
||||
}
|
||||
|
||||
/* Add new data to the list. */
|
||||
void listnode_add(struct list *list, void *val)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -72,12 +70,6 @@ void listnode_add(struct list *list, void *val)
|
||||
list->count++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a node to the list. If the list was sorted according to the
|
||||
* cmp function, insert a new node with the given val such that the
|
||||
* list remains sorted. The new node is always inserted; there is no
|
||||
* notion of omitting duplicates.
|
||||
*/
|
||||
void listnode_add_sort(struct list *list, void *val)
|
||||
{
|
||||
struct listnode *n;
|
||||
@ -186,14 +178,12 @@ struct listnode *listnode_add_before(struct list *list, struct listnode *pp,
|
||||
return nn;
|
||||
}
|
||||
|
||||
/* Move given listnode to tail of the list */
|
||||
void listnode_move_to_tail(struct list *l, struct listnode *n)
|
||||
{
|
||||
LISTNODE_DETACH(l, n);
|
||||
LISTNODE_ATTACH(l, n);
|
||||
}
|
||||
|
||||
/* Delete specific date pointer from the list. */
|
||||
void listnode_delete(struct list *list, void *val)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -218,7 +208,6 @@ void listnode_delete(struct list *list, void *val)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return first node's data if it is there. */
|
||||
void *listnode_head(struct list *list)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -231,7 +220,6 @@ void *listnode_head(struct list *list)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Delete all listnode from the list. */
|
||||
void list_delete_all_node(struct list *list)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -248,7 +236,6 @@ void list_delete_all_node(struct list *list)
|
||||
list->count = 0;
|
||||
}
|
||||
|
||||
/* Delete all listnode then free list itself. */
|
||||
void list_delete_and_null(struct list **list)
|
||||
{
|
||||
assert(*list);
|
||||
@ -262,7 +249,6 @@ void list_delete_original(struct list *list)
|
||||
list_delete_and_null(&list);
|
||||
}
|
||||
|
||||
/* Lookup the node which has given data. */
|
||||
struct listnode *listnode_lookup(struct list *list, void *data)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -274,7 +260,6 @@ struct listnode *listnode_lookup(struct list *list, void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Delete the node from list. For ospfd and ospf6d. */
|
||||
void list_delete_node(struct list *list, struct listnode *node)
|
||||
{
|
||||
if (node->prev)
|
||||
@ -289,25 +274,24 @@ void list_delete_node(struct list *list, struct listnode *node)
|
||||
listnode_free(node);
|
||||
}
|
||||
|
||||
/* ospf_spf.c */
|
||||
void list_add_list(struct list *l, struct list *m)
|
||||
void list_add_list(struct list *list, struct list *add)
|
||||
{
|
||||
struct listnode *n;
|
||||
|
||||
for (n = listhead(m); n; n = listnextnode(n))
|
||||
listnode_add(l, n->data);
|
||||
for (n = listhead(add); n; n = listnextnode(n))
|
||||
listnode_add(list, n->data);
|
||||
}
|
||||
|
||||
struct list *list_dup(struct list *l)
|
||||
struct list *list_dup(struct list *list)
|
||||
{
|
||||
struct list *new = list_new();
|
||||
struct listnode *ln;
|
||||
void *data;
|
||||
|
||||
new->cmp = l->cmp;
|
||||
new->del = l->del;
|
||||
new->cmp = list->cmp;
|
||||
new->del = list->del;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(l, ln, data))
|
||||
for (ALL_LIST_ELEMENTS_RO(list, ln, data))
|
||||
listnode_add(new, data);
|
||||
|
||||
return new;
|
||||
|
234
lib/linklist.h
234
lib/linklist.h
@ -59,23 +59,166 @@ struct list {
|
||||
/* return X->data only if X and X->data are not NULL */
|
||||
#define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data)
|
||||
|
||||
/* Prototypes. */
|
||||
extern struct list *
|
||||
list_new(void); /* encouraged: set list.del callback on new lists */
|
||||
/*
|
||||
* Create a new linked list.
|
||||
*
|
||||
* Returns:
|
||||
* the created linked list
|
||||
*/
|
||||
extern struct list *list_new(void);
|
||||
|
||||
extern void listnode_add(struct list *, void *);
|
||||
extern void listnode_add_sort(struct list *, void *);
|
||||
extern struct listnode *listnode_add_after(struct list *, struct listnode *,
|
||||
void *);
|
||||
extern struct listnode *listnode_add_before(struct list *, struct listnode *,
|
||||
void *);
|
||||
extern void listnode_move_to_tail(struct list *, struct listnode *);
|
||||
extern void listnode_delete(struct list *, void *);
|
||||
extern struct listnode *listnode_lookup(struct list *, void *);
|
||||
extern void *listnode_head(struct list *);
|
||||
/*
|
||||
* Add a new element to the tail of a list.
|
||||
*
|
||||
* Runtime is O(1).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* data
|
||||
* element to add
|
||||
*/
|
||||
extern void listnode_add(struct list *list, void *data);
|
||||
|
||||
/*
|
||||
* Insert a new element into a list with insertion sort.
|
||||
*
|
||||
* If list->cmp is set, this function is used to determine the position to
|
||||
* insert the new element. If it is not set, this function is equivalent to
|
||||
* listnode_add.
|
||||
*
|
||||
* Runtime is O(N).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* val
|
||||
* element to add
|
||||
*/
|
||||
extern void listnode_add_sort(struct list *list, void *val);
|
||||
|
||||
/*
|
||||
* Insert a new element into a list after another element.
|
||||
*
|
||||
* Runtime is O(1).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* pp
|
||||
* listnode to insert after
|
||||
*
|
||||
* data
|
||||
* data to insert
|
||||
*
|
||||
* Returns:
|
||||
* pointer to newly created listnode that contains the inserted data
|
||||
*/
|
||||
extern struct listnode *listnode_add_after(struct list *list,
|
||||
struct listnode *pp, void *data);
|
||||
|
||||
/*
|
||||
* Insert a new element into a list before another element.
|
||||
*
|
||||
* Runtime is O(1).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* pp
|
||||
* listnode to insert before
|
||||
*
|
||||
* data
|
||||
* data to insert
|
||||
*
|
||||
* Returns:
|
||||
* pointer to newly created listnode that contains the inserted data
|
||||
*/
|
||||
extern struct listnode *listnode_add_before(struct list *list,
|
||||
struct listnode *pp, void *data);
|
||||
|
||||
/*
|
||||
* Move a node to the tail of a list.
|
||||
*
|
||||
* Runtime is O(1).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* node
|
||||
* node to move to tail
|
||||
*/
|
||||
extern void listnode_move_to_tail(struct list *list, struct listnode *node);
|
||||
|
||||
/*
|
||||
* Delete an element from a list.
|
||||
*
|
||||
* Runtime is O(N).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* data
|
||||
* data to insert into list
|
||||
*/
|
||||
extern void listnode_delete(struct list *list, void *data);
|
||||
|
||||
/*
|
||||
* Find the listnode corresponding to an element in a list.
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* data
|
||||
* data to search for
|
||||
*
|
||||
* Returns:
|
||||
* pointer to listnode storing the given data if found, NULL otherwise
|
||||
*/
|
||||
extern struct listnode *listnode_lookup(struct list *list, void *data);
|
||||
|
||||
/*
|
||||
* Retrieve the element at the head of a list.
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* Returns:
|
||||
* data at head of list, or NULL if list is empty
|
||||
*/
|
||||
extern void *listnode_head(struct list *list);
|
||||
|
||||
/*
|
||||
* Duplicate a list.
|
||||
*
|
||||
* list
|
||||
* list to duplicate
|
||||
*
|
||||
* Returns:
|
||||
* copy of the list
|
||||
*/
|
||||
extern struct list *list_dup(struct list *l);
|
||||
|
||||
/*
|
||||
* Sort a list in place.
|
||||
*
|
||||
* The sorting algorithm used is quicksort. Runtimes are equivalent to those of
|
||||
* quicksort plus N. The sort is not stable.
|
||||
*
|
||||
* For portability reasons, the comparison function takes a pointer to pointer
|
||||
* to void. This pointer should be dereferenced to get the actual data pointer.
|
||||
* It is always safe to do this.
|
||||
*
|
||||
* list
|
||||
* list to sort
|
||||
*
|
||||
* cmp
|
||||
* comparison function for quicksort. Should return less than, equal to or
|
||||
* greater than zero if the first argument is less than, equal to or greater
|
||||
* than the second argument.
|
||||
*/
|
||||
extern void list_sort(struct list *list,
|
||||
int (*cmp)(const void *, const void *));
|
||||
int (*cmp)(const void **, const void **));
|
||||
|
||||
/*
|
||||
* The usage of list_delete is being transitioned to pass in
|
||||
@ -90,8 +233,27 @@ extern void list_sort(struct list *list,
|
||||
#if defined(VERSION_TYPE_DEV) && CONFDATE > 20181001
|
||||
CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
|
||||
#endif
|
||||
extern void list_delete_and_null(struct list **);
|
||||
extern void list_delete_original(struct list *);
|
||||
|
||||
/*
|
||||
* Delete a list and NULL its pointer.
|
||||
*
|
||||
* If non-null, list->del is called with each data element.
|
||||
*
|
||||
* plist
|
||||
* pointer to list pointer; this will be set to NULL after the list has been
|
||||
* deleted
|
||||
*/
|
||||
extern void list_delete_and_null(struct list **plist);
|
||||
|
||||
/*
|
||||
* Delete a list.
|
||||
*
|
||||
* If non-null, list->del is called with each data element.
|
||||
*
|
||||
* plist
|
||||
* pointer to list pointer
|
||||
*/
|
||||
extern void list_delete_original(struct list *list);
|
||||
#define list_delete(X) \
|
||||
list_delete_original((X)) \
|
||||
CPP_WARN("Please transition to using list_delete_and_null")
|
||||
@ -99,13 +261,43 @@ extern void list_delete_original(struct list *);
|
||||
list_delete_original((X)) \
|
||||
CPP_WARN("Please transition tousing list_delete_and_null")
|
||||
|
||||
extern void list_delete_all_node(struct list *);
|
||||
/*
|
||||
* Delete all nodes from a list without deleting the list itself.
|
||||
*
|
||||
* If non-null, list->del is called with each data element.
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*/
|
||||
extern void list_delete_all_node(struct list *list);
|
||||
|
||||
/* For ospfd and ospf6d. */
|
||||
extern void list_delete_node(struct list *, struct listnode *);
|
||||
/*
|
||||
* Delete a node from a list.
|
||||
*
|
||||
* list->del is not called with the data associated with the node.
|
||||
*
|
||||
* Runtime is O(1).
|
||||
*
|
||||
* list
|
||||
* list to operate on
|
||||
*
|
||||
* node
|
||||
* the node to delete
|
||||
*/
|
||||
extern void list_delete_node(struct list *list, struct listnode *node);
|
||||
|
||||
/* For ospf_spf.c */
|
||||
extern void list_add_list(struct list *, struct list *);
|
||||
/*
|
||||
* Append a list to an existing list.
|
||||
*
|
||||
* Runtime is O(N) where N = listcount(add).
|
||||
*
|
||||
* list
|
||||
* list to append to
|
||||
*
|
||||
* add
|
||||
* list to append
|
||||
*/
|
||||
extern void list_add_list(struct list *list, struct list *add);
|
||||
|
||||
/* List iteration macro.
|
||||
* Usage: for (ALL_LIST_ELEMENTS (...) { ... }
|
||||
|
Loading…
Reference in New Issue
Block a user