1 | /* |
2 | * Copyright 2008-2018 Aerospike, Inc. |
3 | * |
4 | * Portions may be licensed to Aerospike, Inc. under one or more contributor |
5 | * license agreements. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
8 | * use this file except in compliance with the License. You may obtain a copy of |
9 | * the License at http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 | * License for the specific language governing permissions and limitations under |
15 | * the License. |
16 | */ |
17 | #pragma once |
18 | |
19 | //========================================================== |
20 | // Includes. |
21 | // |
22 | |
23 | #include <aerospike/as_std.h> |
24 | #include <pthread.h> |
25 | |
26 | #ifdef __cplusplus |
27 | extern "C" { |
28 | #endif |
29 | |
30 | |
31 | //========================================================== |
32 | // Constants & typedefs. |
33 | // |
34 | |
35 | // Deprecated - use cf_vector_element_size(). |
36 | #define VECTOR_ELEM_SZ(_v) ( _v->ele_sz ) |
37 | |
38 | // Public flags. |
39 | #define VECTOR_FLAG_BIGLOCK 0x01 |
40 | #define VECTOR_FLAG_INITZERO 0x02 // vector elements start cleared to 0 |
41 | |
42 | // Return this to delete element during reduce. |
43 | #define VECTOR_REDUCE_DELETE 1 |
44 | |
45 | // Private data. |
46 | typedef struct cf_vector_s { |
47 | uint8_t *vector; |
48 | uint32_t ele_sz; |
49 | uint32_t capacity; // number of elements currently allocated |
50 | uint32_t count; // number of elements in table, largest element set |
51 | uint32_t flags; |
52 | pthread_mutex_t LOCK; // mutable |
53 | } cf_vector; |
54 | |
55 | |
56 | //========================================================== |
57 | // Public API. |
58 | // |
59 | |
60 | cf_vector *cf_vector_create(uint32_t ele_sz, uint32_t capacity, uint32_t flags); |
61 | int cf_vector_init(cf_vector *v, uint32_t ele_sz, uint32_t capacity, uint32_t flags); |
62 | void cf_vector_init_with_buf(cf_vector *v, uint32_t ele_sz, uint32_t capacity, uint8_t *buf, uint32_t flags); |
63 | |
64 | // Deprecated - use cf_vector_init_with_buf(). |
65 | void cf_vector_init_smalloc(cf_vector *v, uint32_t ele_sz, uint8_t *sbuf, uint32_t sbuf_sz, uint32_t flags); |
66 | |
67 | int cf_vector_get(const cf_vector *v, uint32_t idx, void *val); |
68 | bool cf_vector_get_sized(const cf_vector *v, uint32_t idx, void *val, uint32_t sz); |
69 | int cf_vector_set(cf_vector *v, uint32_t idx, const void *val); |
70 | |
71 | void *cf_vector_getp(cf_vector *v, uint32_t val); |
72 | void *cf_vector_getp_vlock(cf_vector *v, uint32_t val, pthread_mutex_t **vlock); |
73 | |
74 | int cf_vector_append(cf_vector *v, const void *val); |
75 | // Adds a an element to the end, only if it doesn't exist already. O(N). |
76 | int cf_vector_append_unique(cf_vector *v, const void *val); |
77 | int cf_vector_pop(cf_vector *v, void *val); |
78 | |
79 | int cf_vector_delete(cf_vector *v, uint32_t val); |
80 | // Inclusive-exclusive, e.g. start 0 & end 3 removes indexes 0,1,2. |
81 | int cf_vector_delete_range(cf_vector *v, uint32_t start, uint32_t end); |
82 | void cf_vector_clear(cf_vector *v); |
83 | |
84 | // Realloc to minimal space needed. |
85 | void cf_vector_compact(cf_vector *v); |
86 | |
87 | void cf_vector_destroy(cf_vector *v); |
88 | |
89 | static inline uint32_t |
90 | cf_vector_size(const cf_vector *v) |
91 | { |
92 | return v->count; |
93 | } |
94 | |
95 | static inline uint32_t |
96 | cf_vector_element_size(const cf_vector *v) |
97 | { |
98 | return v->ele_sz; |
99 | } |
100 | |
101 | #define cf_vector_inita(_v, _ele_sz, _ele_cnt, _flags) \ |
102 | cf_vector_init_with_buf(_v, _ele_sz, _ele_cnt, alloca((_ele_sz) * (_ele_cnt)), _flags); |
103 | |
104 | #define cf_vector_define(_v, _ele_sz, _ele_cnt, _flags) \ |
105 | cf_vector _v; \ |
106 | uint8_t _v ## __mem[(_ele_sz) * (_ele_cnt)]; \ |
107 | cf_vector_init_with_buf(&_v, _ele_sz, _ele_cnt, _v ## __mem, _flags); |
108 | |
109 | //---------------------------------------------------------- |
110 | // Deprecated wrappers for helpers for a vector of pointers. |
111 | // |
112 | |
113 | // Deprecated - use cf_vector_create(). |
114 | static inline cf_vector * |
115 | cf_vector_pointer_create(uint32_t capacity, uint32_t flags) |
116 | { |
117 | return cf_vector_create(sizeof(void *), capacity, flags); |
118 | } |
119 | |
120 | // Deprecated - use cf_vector_init(v, sizeof(void *), ...). |
121 | static inline int |
122 | cf_vector_pointer_init(cf_vector *v, uint32_t capacity, uint32_t flags) |
123 | { |
124 | return cf_vector_init(v, sizeof(void *), capacity, flags); |
125 | } |
126 | |
127 | // Deprecated - use cf_vector_set_ptr(). |
128 | static inline int |
129 | cf_vector_pointer_set(cf_vector *v, uint32_t idx, const void *val) |
130 | { |
131 | return cf_vector_set(v, idx, &val); |
132 | } |
133 | |
134 | // Deprecated - use cf_vector_get_ptr(). |
135 | static inline void * |
136 | cf_vector_pointer_get(const cf_vector *v, uint32_t idx) |
137 | { |
138 | void *p; |
139 | |
140 | if (! cf_vector_get_sized(v, idx, &p, sizeof(void *))) { |
141 | return NULL; |
142 | } |
143 | |
144 | return p; |
145 | } |
146 | |
147 | // Deprecated - use cf_vector_append_ptr(). |
148 | static inline int |
149 | cf_vector_pointer_append(cf_vector *v, const void *val) |
150 | { |
151 | return cf_vector_append(v, &val); |
152 | } |
153 | |
154 | //---------------------------------------------------------- |
155 | // Helpers for a vector of pointers. |
156 | // |
157 | |
158 | static inline int |
159 | cf_vector_set_ptr(cf_vector *v, uint32_t idx, const void *val) |
160 | { |
161 | return cf_vector_set(v, idx, &val); |
162 | } |
163 | |
164 | static inline void * |
165 | cf_vector_get_ptr(const cf_vector *v, uint32_t idx) |
166 | { |
167 | void *p = NULL; |
168 | |
169 | cf_vector_get_sized(v, idx, &p, sizeof(void *)); |
170 | |
171 | return p; |
172 | } |
173 | |
174 | static inline int |
175 | cf_vector_append_ptr(cf_vector *v, const void *val) |
176 | { |
177 | return cf_vector_append(v, &val); |
178 | } |
179 | |
180 | //---------------------------------------------------------- |
181 | // Helpers for a vector of uint32_t's. |
182 | // |
183 | |
184 | static inline int |
185 | cf_vector_set_uint32(cf_vector *v, uint32_t idx, uint32_t val) |
186 | { |
187 | return cf_vector_set(v, idx, &val); |
188 | } |
189 | |
190 | static inline uint32_t |
191 | cf_vector_get_uint32(const cf_vector *v, uint32_t idx) |
192 | { |
193 | uint32_t val = 0; |
194 | |
195 | cf_vector_get_sized(v, idx, &val, sizeof(uint32_t)); |
196 | |
197 | return val; |
198 | } |
199 | |
200 | static inline int |
201 | cf_vector_append_uint32(cf_vector *v, uint32_t val) |
202 | { |
203 | return cf_vector_append(v, &val); |
204 | } |
205 | |
206 | |
207 | #ifdef __cplusplus |
208 | } // end extern "C" |
209 | #endif |
210 | |