All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
target/Linux-x86_64/include/citrusleaf/cf_vector.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2008-2013 by Aerospike.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  *****************************************************************************/
22 #pragma once
23 
24 /*
25  * A general purpose vector
26  * Uses locks, so only moderately fast
27  * If you need to deal with sparse data, really sparse data,
28  * use a hash table. This assumes that packed data is a good idea.
29  * Does the fairly trivial realloc thing for extension, so
30  * and you can keep adding cool things to it
31  */
32 
33 
34 #include <pthread.h>
35 #include <stdint.h>
36 
37 #include <citrusleaf/cf_types.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /******************************************************************************
44  * CONSTANTS
45  ******************************************************************************/
46 
47 #define VECTOR_ELEM_SZ(_v) ( _h->value_len )
48 
49 /**
50  * support multithreaded access with a single big lock
51  */
52 #define VECTOR_FLAG_BIGLOCK 0x01
53 
54 /**
55  * internally init the vector objects to 0
56  */
57 #define VECTOR_FLAG_INITZERO 0x02
58 
59 /**
60  * appends will be common - speculatively allocate extra memory
61  */
62 #define VECTOR_FLAG_BIGRESIZE 0x04
63 
64 /**
65  * indicate that a delete should be done during the reduction
66  */
67 #define VECTOR_REDUCE_DELETE (1)
68 
69 
70 /******************************************************************************
71  * TYPES
72  ******************************************************************************/
73 
74 typedef struct cf_vector_s cf_vector;
75 
76 struct cf_vector_s {
77  uint32_t value_len;
78  uint flags;
79  uint alloc_len; // number of elements currently allocated
80  uint len; // number of elements in table, largest element set
81  uint8_t * vector;
82  bool stack_struct;
83  bool stack_vector;
84 #ifdef EXTERNAL_LOCKS
85  void * LOCK; // the lock object
86 #else
87  pthread_mutex_t LOCK; // the mutex lock
88 #endif // EXTERNAL_LOCKS
89 };
90 
91 /******************************************************************************
92  * FUNCTIONS
93  ******************************************************************************/
94 
95 /**
96  * Create a vector with malloc for handing around
97  */
98 cf_vector * cf_vector_create(uint32_t value_len, uint32_t init_sz, uint flags);
99 
100 /**
101  * create a stack vector, but with an allocated internal-vector-bit
102  */
103 int cf_vector_init(cf_vector *v, uint32_t value_len, uint32_t init_sz, uint flags);
104 
105 void cf_vector_init_smalloc(cf_vector *v, uint32_t value_len, uint8_t *sbuf, int sbuf_sz, uint flags);
106 
107 /**
108  * Place a value into the vector
109  * Value will be copied into the vector
110  */
111 extern int cf_vector_get(cf_vector *v, uint32_t index, void *value);
112 
113 /**
114  * Retrieve a value from the vector
115  */
116 extern int cf_vector_set(cf_vector *v, uint32_t index, void *value);
117 
118 /**
119  * this is very dangerous if it's a multithreaded vector. Use _vlock if multithrad.
120  */
121 extern void * cf_vector_getp(cf_vector *v, uint32_t index);
122 extern void * cf_vector_getp_vlock(cf_vector *v, uint32_t index, pthread_mutex_t **vlock);
123 extern int cf_vector_append(cf_vector *v, void *value);
124 
125 /**
126  * Adds a an element to the end, only if it doesn't exist already
127  * uses a bit-by-bit compare, thus is O(N) against the current length
128  * of the vector
129  */
130 extern int cf_vector_append_unique(cf_vector *v, void *value);
131 
132 /**
133  * Deletes an element by moving all the remaining elements down by one
134  */
135 extern int cf_vector_delete(cf_vector *v, uint32_t index);
136 
137 /**
138  * Delete a range in the vector. Inclusive. Thus:
139  * a vector with len 5, you could delete start=0, end=3, leaving one element at the beginning (slot 0)
140  * don't set start and end the same, that's a single element delete, use vector_delete instead
141  * (or change the code to support that!)
142  * returns -1 on bad ranges
143  */
144 extern int cf_vector_delete_range(cf_vector *v, uint32_t start_index, uint32_t end_index);
145 
146 /**
147  * There may be more allocated than you need. Fix that.
148  */
149 extern void cf_vector_compact(cf_vector *v);
150 
151 /**
152  * Destroy the entire hash - all memory will be freed
153  */
154 extern void cf_vector_destroy(cf_vector *v);
155 
156 /******************************************************************************
157  * INLINE FUNCTIONS
158  ******************************************************************************/
159 
160 /**
161  * Get the number of elements currently in the vector
162  */
163 static inline uint32_t cf_vector_size(cf_vector *v) {
164  return(v->len);
165 }
166 
167 
168 /**
169  * nice wrapper functions
170  * very common vector types are pointers, and integers
171  */
172 static inline cf_vector * cf_vector_pointer_create(uint32_t init_sz, uint32_t flags) {
173  return(cf_vector_create(sizeof(void *), init_sz, flags));
174 }
175 
176 static inline int cf_vector_pointer_init(cf_vector *v, uint32_t init_sz, uint32_t flags) {
177  return(cf_vector_init(v, sizeof(void *), init_sz, flags));
178 }
179 
180 static inline int cf_vector_pointer_set(cf_vector *v, uint32_t index, void *p) {
181  return(cf_vector_set(v, index, &p));
182 }
183 
184 static inline void * cf_vector_pointer_get(cf_vector *v, uint32_t index) {
185  void *p;
186  cf_vector_get(v, index, &p);
187  return(p);
188 }
189 
190 static inline int cf_vector_pointer_append(cf_vector *v, void *p) {
191  return(cf_vector_append(v, &p));
192 }
193 
194 /**
195  * integer vectors!
196  */
197 
198 static inline cf_vector * cf_vector_integer_create(uint32_t init_sz, uint32_t flags) {
199  return(cf_vector_create(sizeof(int), init_sz, flags));
200 }
201 
202 static inline int cf_vector_integer_init(cf_vector *v, uint32_t init_sz, uint32_t flags) {
203  return(cf_vector_init(v, sizeof(int), init_sz, flags));
204 }
205 
206 static inline int cf_vector_integer_set(cf_vector *v, uint32_t index, int i) {
207  return(cf_vector_set(v, index, &i));
208 }
209 
210 static inline int cf_vector_integer_get(cf_vector *v, uint32_t index) {
211  int i;
212  cf_vector_get(v, index, &i);
213  return(i);
214 }
215 
216 static inline int cf_vector_integer_append(cf_vector *v, int i) {
217  return(cf_vector_append(v, &i));
218 }
219 
220 /******************************************************************************
221  * MACROS
222  ******************************************************************************/
223 
224 #define cf_vector_define(__x, __value_len, __flags) \
225  uint8_t cf_vector##__x[1024]; cf_vector __x; cf_vector_init_smalloc(&__x, __value_len, cf_vector##__x, sizeof(cf_vector##__x), __flags);
226 
227 #define cf_vector_reset( __v ) (__v)->len = 0; if ( (__v)->flags & VECTOR_FLAG_INITZERO) memset( (__v)->vector, 0, (__v)->alloc_len * (__v)->value_len);
228 
229 /******************************************************************************/
230 
231 #ifdef __cplusplus
232 } // end extern "C"
233 #endif
static int cf_vector_integer_append(cf_vector *v, int i)
void cf_vector_compact(cf_vector *v)
static uint32_t cf_vector_size(cf_vector *v)
static int cf_vector_integer_get(cf_vector *v, uint32_t index)
static int cf_vector_pointer_append(cf_vector *v, void *p)
void * cf_vector_getp_vlock(cf_vector *v, uint32_t index, pthread_mutex_t **vlock)
int cf_vector_get(cf_vector *v, uint32_t index, void *value)
int cf_vector_delete_range(cf_vector *v, uint32_t start_index, uint32_t end_index)
static cf_vector * cf_vector_integer_create(uint32_t init_sz, uint32_t flags)
static int cf_vector_integer_set(cf_vector *v, uint32_t index, int i)
int cf_vector_append(cf_vector *v, void *value)
void cf_vector_init_smalloc(cf_vector *v, uint32_t value_len, uint8_t *sbuf, int sbuf_sz, uint flags)
int cf_vector_set(cf_vector *v, uint32_t index, void *value)
static int cf_vector_pointer_init(cf_vector *v, uint32_t init_sz, uint32_t flags)
int cf_vector_delete(cf_vector *v, uint32_t index)
static int cf_vector_pointer_set(cf_vector *v, uint32_t index, void *p)
static void * cf_vector_pointer_get(cf_vector *v, uint32_t index)
static int cf_vector_integer_init(cf_vector *v, uint32_t init_sz, uint32_t flags)
void * cf_vector_getp(cf_vector *v, uint32_t index)
int cf_vector_append_unique(cf_vector *v, void *value)
void cf_vector_destroy(cf_vector *v)
int cf_vector_init(cf_vector *v, uint32_t value_len, uint32_t init_sz, uint flags)
cf_vector * cf_vector_create(uint32_t value_len, uint32_t init_sz, uint flags)
static cf_vector * cf_vector_pointer_create(uint32_t init_sz, uint32_t flags)