#include <pthread.h>
#include <inttypes.h>
#include <citrusleaf/cf_types.h>
Go to the source code of this file.
|
void | cf_ll_append (cf_ll *ll, cf_ll_element *e) |
|
void | cf_ll_delete (cf_ll *ll, cf_ll_element *e) |
|
static cf_ll_element * | cf_ll_get_head (cf_ll *ll) |
|
static cf_ll_element * | cf_ll_get_next (cf_ll_element *e) |
|
static cf_ll_element * | cf_ll_get_prev (cf_ll_element *e) |
|
static cf_ll_element * | cf_ll_get_tail (cf_ll *ll) |
|
cf_ll_iterator * | cf_ll_getIterator (cf_ll *ll, bool forward) |
|
cf_ll_element * | cf_ll_getNext (cf_ll_iterator *iter) |
|
cf_ll_element * | cf_ll_index (cf_ll *ll, int index) |
|
int | cf_ll_init (cf_ll *ll, cf_ll_destructor destroy_fn, bool uselock) |
|
void | cf_ll_insert_after (cf_ll *ll, cf_ll_element *cur, cf_ll_element *ins) |
|
void | cf_ll_insert_before (cf_ll *ll, cf_ll_element *cur, cf_ll_element *ins) |
|
int | cf_ll_insert_reduce (cf_ll *ll, cf_ll_element *e, bool forward, cf_ll_reduce_fn fn, void *udata) |
|
void | cf_ll_prepend (cf_ll *ll, cf_ll_element *e) |
|
int | cf_ll_reduce (cf_ll *ll, bool forward, cf_ll_reduce_fn fn, void *udata) |
|
void | cf_ll_releaseIterator (cf_ll_iterator *iter) |
|
cf_ll_element * | cf_ll_search (cf_ll *ll, cf_ll_element *e, bool forward, cf_ll_reduce_fn fn) |
|
uint32_t | cf_ll_size (cf_ll *ll) |
|
#define CF_LL_REDUCE_DELETE (1) |
#define CF_LL_REDUCE_INSERT (2) |
#define CF_LL_REDUCE_MATCHED (3) |
#define CF_LL_REDUCE_NOT_MATCHED (4) |
typedef void(* cf_ll_destructor)(cf_ll_element *e) |
typedef int(* cf_ll_reduce_fn)(cf_ll_element *e, void *udata) |
void cf_ll_append |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
e |
|
) |
| |
void cf_ll_delete |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
e |
|
) |
| |
delete element - the real joy of a doubly linked list If a destructor function has been set, call it as well
static cf_ll_element* cf_ll_get_head |
( |
cf_ll * |
ll | ) |
|
|
inlinestatic |
static cf_ll_element* cf_ll_get_next |
( |
cf_ll_element * |
e | ) |
|
|
inlinestatic |
static cf_ll_element* cf_ll_get_prev |
( |
cf_ll_element * |
e | ) |
|
|
inlinestatic |
static cf_ll_element* cf_ll_get_tail |
( |
cf_ll * |
ll | ) |
|
|
inlinestatic |
cf_ll_iterator* cf_ll_getIterator |
( |
cf_ll * |
ll, |
|
|
bool |
forward |
|
) |
| |
cf_ll_element* cf_ll_getNext |
( |
cf_ll_iterator * |
iter | ) |
|
cf_ll_element* cf_ll_index |
( |
cf_ll * |
ll, |
|
|
int |
index |
|
) |
| |
Call this function on a head structure to initialize it to empty Call with whether you want a locked version of a lockfree version if you're handling your own locks
If you're using a standard delete methodology, then don't need a destructor function, and can leave it blank. But if you're using the reduce / delete pattern, then there's not an easy way for the application-level delete to occur, because you can't free the structure first then call delete. (you could insert the element on a queue, but it would have to carefully be a reference counted object, and then you'd still need the linked-list-reduceor to decrement the linked list....) In that case, you need to have a destructor function that gets fired every time a removal from the list occurs. even on explicit deletes it's called, just to be fancy.
Note that when the destructor is called, the lock for the linked list is held (if you've allocated the linked list with a lock)
void cf_ll_insert_after |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
cur, |
|
|
cf_ll_element * |
ins |
|
) |
| |
Insert after element !! warning! consider threadsafety before using this call!
void cf_ll_insert_before |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
cur, |
|
|
cf_ll_element * |
ins |
|
) |
| |
Insert before element !! warning! consider threadsafey before using this call!
int cf_ll_insert_reduce |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
e, |
|
|
bool |
forward, |
|
|
cf_ll_reduce_fn |
fn, |
|
|
void * |
udata |
|
) |
| |
Insert-before Sometimes you want to iterate a list, and insert before a certain element. Common when you're trying to keep a sorted list and you have some knowledge that either the list is short, or you're doing inserts of a particular pattern so that a sorted-table is not the right answer.
Similar to the reduce function: if you want to bail out of the insert, return a negative If you want to insert "here", return the special code At the end of the list, you will be passed a null element (thus meaning you'll always be called at least once)
void cf_ll_prepend |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
e |
|
) |
| |
int cf_ll_reduce |
( |
cf_ll * |
ll, |
|
|
bool |
forward, |
|
|
cf_ll_reduce_fn |
fn, |
|
|
void * |
udata |
|
) |
| |
The way these reduces work: ** If you're reducing and you want to delete this element, return CF_LL_REDUCE_DELETE and it'll be removed from the list - but iteration will not halt ** If you return a negative value, the reduction will terminate immediatly and that return value will be passed to the reducer ** The 'forward' parameter specifies whether you want to traverse from front to back, pass in 'false' to go tail-to-head
void cf_ll_releaseIterator |
( |
cf_ll_iterator * |
iter | ) |
|
cf_ll_element* cf_ll_search |
( |
cf_ll * |
ll, |
|
|
cf_ll_element * |
e, |
|
|
bool |
forward, |
|
|
cf_ll_reduce_fn |
fn |
|
) |
| |
uint32_t cf_ll_size |
( |
cf_ll * |
ll | ) |
|