hce-node application
1.4.3
HCE Hierarchical Cluster Engine node application
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
cf_ll.h
Go to the documentation of this file.
1
/*
2
* Citrusleaf Foundation
3
* include/ll.h - linked list functionality
4
*
5
* Copyright 2008 by Citrusleaf. All rights reserved.
6
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE. THE COPYRIGHT NOTICE
7
* ABOVE DOES NOT EVIDENCE ANY ACTUAL OR INTENDED PUBLICATION.
8
*/
9
#pragma once
10
11
#include <pthread.h>
12
#include <stdint.h>
13
14
#include "
citrusleaf/cf_base_types.h
"
15
16
/* SYNOPSIS
17
* LinkedList
18
* Sometimes the answer is a doubly linked list. It's not that frequent, but
19
* all the corner cases in a double linked list can be annoying.
20
*
21
* the current use pattern is the caller creates a structure that starts with a 'cf_ll_element',
22
* ie, can be cast to a cf_ll_element. The caller allocates and frees the memory.
23
* (There are far cooler ways to do this, so if you want to improve this, go ahead!
24
*
25
*/
26
27
#ifdef __cplusplus
28
extern
"C"
{
29
#endif
30
31
//
32
// Callbacks in use!
33
// These function expose functional programming paradigms across linked
34
// lists
35
36
37
#define CF_LL_REDUCE_DELETE (1)
38
#define CF_LL_REDUCE_INSERT (2)
39
40
struct
cf_ll_element_s
;
41
typedef
int (*
cf_ll_reduce_fn
) (
struct
cf_ll_element_s
*e,
void
*udata);
42
typedef
void (*
cf_ll_destructor
) (
struct
cf_ll_element_s
*e);
43
44
45
/* cf_ll_element
46
* The element that must be included in structures
47
* This element should be the FIRST element in the structure where it is being included
48
*/
49
50
typedef
struct
cf_ll_element_s
{
51
struct
cf_ll_element_s
*
next
;
52
struct
cf_ll_element_s
*
prev
;
53
}
cf_ll_element
;
54
55
/* cf_ll
56
** the linked list container
57
*/
58
59
60
61
typedef
struct
cf_ll_s
{
62
struct
cf_ll_element_s
*
head
;
63
struct
cf_ll_element_s
*
tail
;
64
cf_ll_destructor
destroy_fn
;
65
uint32_t
sz
;
66
bool
uselock
;
67
#ifdef EXTERNAL_LOCKS
68
void
*
LOCK
;
69
#else
70
pthread_mutex_t
LOCK
;
71
#endif //EXTERNAL_LOCKS
72
}
cf_ll
;
73
74
// Insert to head
75
extern
void
cf_ll_prepend
(
cf_ll
*ll,
cf_ll_element
*e );
76
// Insert to tail
77
extern
void
cf_ll_append
(
cf_ll
*ll,
cf_ll_element
*e );
78
79
// Insert after element !! warning! consider threadsafety before using this call!
80
extern
void
cf_ll_insert_after
(
cf_ll
*ll,
cf_ll_element
*cur,
cf_ll_element
*ins);
81
// Insert before element !! warning! consider threadsafey before using this call!
82
extern
void
cf_ll_insert_before
(
cf_ll
*ll,
cf_ll_element
*cur,
cf_ll_element
*ins);
83
84
static
inline
cf_ll_element
*cf_ll_get_head(
cf_ll
*ll)
85
{
86
return
(ll->
head
);
87
}
88
89
static
inline
cf_ll_element
*cf_ll_get_tail(
cf_ll
*ll)
90
{
91
return
(ll->
tail
);
92
}
93
94
static
inline
cf_ll_element
*cf_ll_get_next(
cf_ll_element
*e)
95
{
96
return
(e->
next
);
97
}
98
99
static
inline
cf_ll_element
*cf_ll_get_prev(
cf_ll_element
*e)
100
{
101
return
(e->
prev
);
102
}
103
104
// delete element - the real joy of a doubly linked list
105
// If a destructor function has been set, call it as well
106
extern
void
cf_ll_delete
(
cf_ll
*ll,
cf_ll_element
*e );
107
108
extern
uint32_t
cf_ll_size
(
cf_ll
*ll);
109
110
//
111
// The way these reduces work:
112
// ** If you're reducing and you want to delete this element, return CF_LL_REDUCE_DELETE
113
// and it'll be removed from the list - but iteration will not halt
114
// ** If you return a negative value, the reduction will terminate immediatly and that
115
// return value will be passed to the reducer
116
// ** The 'forward' parameter specifies whether you want to traverse from front to back,
117
// pass in 'false' to go tail-to-head
118
119
120
extern
int
cf_ll_reduce
(
cf_ll
*ll,
bool
forward,
cf_ll_reduce_fn
fn,
void
*udata);
121
122
//
123
// Insert-before
124
// Sometimes you want to iterate a list, and insert before a certain element.
125
// Common when you're trying to keep a sorted list and you have some knowledge
126
// that either the list is short, or you're doing inserts of a particular pattern
127
// so that a sorted-table is not the right answer.
128
//
129
// Similar to the reduce function: if you want to bail out of the insert, return a negative
130
// If you want to insert "here", return the special code
131
// At the end of the list, you will be passed a null element (thus meaning you'll always
132
// be called at least once)
133
134
135
extern
int
cf_ll_insert_reduce
(
cf_ll
*ll,
cf_ll_element
*e,
bool
forward,
cf_ll_reduce_fn
fn,
void
*udata);
136
137
138
/* Call this function on a head structure to initialize it to empty
139
** Call with whether you want a locked version of a lockfree version
140
** if you're handling your own locks
141
*/
142
143
/*
144
** If you're using a standard delete methodology, then don't need a destructor function,
145
** and can leave it blank. But if you're using the reduce / delete pattern, then
146
** there's not an easy way for the application-level delete to occur, because you can't
147
** free the structure first then call delete. (you could insert the element on a queue,
148
** but it would have to carefully be a reference counted object, and then you'd still
149
** need the linked-list-reduceor to decrement the linked list....)
150
** In that case, you need to have a destructor
151
** function that gets fired every time a removal from the list occurs. even on explicit
152
** deletes it's called, just to be fancy.
153
**
154
** Note that when the destructor is called, the lock for the linked list is held
155
** (if you've allocated the linked list with a lock)
156
*/
157
158
159
extern
int
cf_ll_init
(
cf_ll
*ll,
cf_ll_destructor
destroy_fn,
bool
uselock);
160
161
#ifdef __cplusplus
162
}
// end extern "C"
163
#endif
164
165
sources
utils
kvdb
src
citrusleaf
cf_ll.h
Generated on Tue Jun 30 2015 19:42:13 for hce-node application by
1.8.1.2