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
27extern "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.
46typedef 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
60cf_vector *cf_vector_create(uint32_t ele_sz, uint32_t capacity, uint32_t flags);
61int cf_vector_init(cf_vector *v, uint32_t ele_sz, uint32_t capacity, uint32_t flags);
62void 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().
65void cf_vector_init_smalloc(cf_vector *v, uint32_t ele_sz, uint8_t *sbuf, uint32_t sbuf_sz, uint32_t flags);
66
67int cf_vector_get(const cf_vector *v, uint32_t idx, void *val);
68bool cf_vector_get_sized(const cf_vector *v, uint32_t idx, void *val, uint32_t sz);
69int cf_vector_set(cf_vector *v, uint32_t idx, const void *val);
70
71void *cf_vector_getp(cf_vector *v, uint32_t val);
72void *cf_vector_getp_vlock(cf_vector *v, uint32_t val, pthread_mutex_t **vlock);
73
74int 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).
76int cf_vector_append_unique(cf_vector *v, const void *val);
77int cf_vector_pop(cf_vector *v, void *val);
78
79int cf_vector_delete(cf_vector *v, uint32_t val);
80// Inclusive-exclusive, e.g. start 0 & end 3 removes indexes 0,1,2.
81int cf_vector_delete_range(cf_vector *v, uint32_t start, uint32_t end);
82void cf_vector_clear(cf_vector *v);
83
84// Realloc to minimal space needed.
85void cf_vector_compact(cf_vector *v);
86
87void cf_vector_destroy(cf_vector *v);
88
89static inline uint32_t
90cf_vector_size(const cf_vector *v)
91{
92 return v->count;
93}
94
95static inline uint32_t
96cf_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().
114static inline cf_vector *
115cf_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 *), ...).
121static inline int
122cf_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().
128static inline int
129cf_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().
135static inline void *
136cf_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().
148static inline int
149cf_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
158static inline int
159cf_vector_set_ptr(cf_vector *v, uint32_t idx, const void *val)
160{
161 return cf_vector_set(v, idx, &val);
162}
163
164static inline void *
165cf_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
174static inline int
175cf_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
184static inline int
185cf_vector_set_uint32(cf_vector *v, uint32_t idx, uint32_t val)
186{
187 return cf_vector_set(v, idx, &val);
188}
189
190static inline uint32_t
191cf_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
200static inline int
201cf_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