Loading...
Searching...
No Matches
as_orderedmap.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
18#pragma once
19
20#include <aerospike/as_std.h>
21#include <aerospike/as_map.h>
22#include <aerospike/as_pair.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28
29/******************************************************************************
30 * TYPES
31 ******************************************************************************/
32
33/**
34 * Private helper structure.
35 */
36typedef struct map_entry_s {
39} map_entry;
40
41/**
42 * A sorted array based implementation of `as_map`.
43 *
44 * To use the map, you can either initialize a stack allocated map,
45 * using `as_orderedmap_init()`:
46 *
47 * ~~~~~~~~~~{.c}
48 * as_orderedmap map;
49 * as_orderedmap_init(&map, 256);
50 * ~~~~~~~~~~
51 *
52 * Or you can create a new heap allocated map using
53 * `as_orderedmap_new()`:
54 *
55 * ~~~~~~~~~~{.c}
56 * as_orderedmap* map = as_orderedmap_new(256);
57 * ~~~~~~~~~~
58 *
59 * When you are finished using the map, then you should release the
60 * map and associated resources, using `as_orderedmap_destroy()`:
61 *
62 * ~~~~~~~~~~{.c}
63 * as_orderedmap_destroy(map);
64 * ~~~~~~~~~~
65 *
66 *
67 * The `as_orderedmap` is a subtype of `as_map`. This allows you to
68 * alternatively use `as_map` functions, by typecasting `as_orderedmap` to
69 * `as_map`.
70 *
71 * ~~~~~~~~~~{.c}
72 * as_orderedmap map;
73 * as_map* l = (as_map*)as_orderedmap_init(&map, 4);
74 * as_stringmap_set_int64(l, "a", 1);
75 * as_stringmap_set_int64(l, "b", 2);
76 * as_stringmap_set_int64(l, "c", 3);
77 * as_stringmap_set_int64(l, "d", 4);
78 * as_map_destroy(l);
79 * ~~~~~~~~~~
80 *
81 * The `as_stringmap` functions are simplified functions for using string key.
82 *
83 * Each of the `as_map` functions proxy to the `as_orderedmap` functions.
84 * So, calling `as_map_destroy()` is equivalent to calling
85 * `as_orderedmap_destroy()`.
86 *
87 * Notes:
88 *
89 * This orderedmap implementation is NOT threadsafe.
90 *
91 * Internally, the orderedmap stores keys' and values' pointers - it does NOT
92 * copy the keys or values, so the caller must ensure these keys and values are
93 * not destroyed while the orderedmap is still in use.
94 *
95 * Further, the orderedmap does not increment ref-counts of the keys or values.
96 * However when an element is removed from the orderedmap, the orderedmap will
97 * call as_val_destroy() on both the key and value. And when the orderedmap is
98 * cleared or destroyed, as_val_destroy() will be called for all keys and
99 * values. Therefore if the caller inserts keys and values in the orderedmap
100 * without extra ref-counts, the caller is effectively handing off ownership of
101 * these objects to the orderedmap.
102 *
103 * @extends as_map
104 * @ingroup aerospike_t
105 */
106typedef struct as_orderedmap_s {
107 as_map _;
108
109 uint32_t count;
110 uint32_t capacity;
112
113 uint32_t hold_count;
115 uint32_t* hold_locations;
117
118/**
119 * Iterator for as_orderedmap.
120 *
121 * To use the iterator, you can either initialize a stack allocated variable,
122 * use `as_orderedmap_iterator_init()`:
123 *
124 * ~~~~~~~~~~{.c}
125 * as_orderedmap_iterator it;
126 * as_orderedmap_iterator_init(&it, &map);
127 * ~~~~~~~~~~
128 *
129 * Or you can create a new heap allocated variable using
130 * `as_orderedmap_iterator_new()`:
131 *
132 * ~~~~~~~~~~{.c}
133 * as_orderedmap_iterator* it = as_orderedmap_iterator_new(&map);
134 * ~~~~~~~~~~
135 *
136 * To iterate, use `as_orderedmap_iterator_has_next()` and
137 * `as_orderedmap_iterator_next()`:
138 *
139 * ~~~~~~~~~~{.c}
140 * while ( as_orderedmap_iterator_has_next(&it) ) {
141 * const as_val* val = as_orderedmap_iterator_next(&it);
142 * }
143 * ~~~~~~~~~~
144 *
145 * When you are finished using the iterator, then you should release the
146 * iterator and associated resources:
147 *
148 * ~~~~~~~~~~{.c}
149 * as_orderedmap_iterator_destroy(it);
150 * ~~~~~~~~~~
151 *
152 *
153 * The `as_orderedmap_iterator` is a subtype of `as_iterator`. This allows you
154 * to alternatively use `as_iterator` functions, by typecasting
155 * `as_orderedmap_iterator` to `as_iterator`.
156 *
157 * ~~~~~~~~~~{.c}
158 * as_orderedmap_iterator it;
159 * as_iterator* i = (as_iterator*)as_orderedmap_iterator_init(&it, &map);
160 *
161 * while (as_iterator_has_next(i)) {
162 * const as_val* as_iterator_next(i);
163 * }
164 *
165 * as_iterator_destroy(i);
166 * ~~~~~~~~~~
167 *
168 * Each of the `as_iterator` functions proxy to the `as_orderedmap_iterator`
169 * functions. So, calling `as_iterator_destroy()` is equivalent to calling
170 * `as_orderedmap_iterator_destroy()`.
171 *
172 * Notes:
173 *
174 * as_orderedmap_iterator_next() returns an as_pair pointer. The as_pair
175 * contains the key and value pointers of the current map element. This one
176 * as_pair "container" is re-used for all the iterations, i.e. the contents
177 * will be overwritten and are only valid until the next iteration.
178 *
179 * @extends as_iterator
180 */
181typedef struct as_orderedmap_iterator_s {
182 as_iterator _;
183
185 uint32_t ix;
188
189
190/*******************************************************************************
191 * INSTANCE FUNCTIONS
192 ******************************************************************************/
193
194/**
195 * Initialize a stack allocated orderedmap.
196 *
197 * @param map The map to initialize.
198 * @param capacity The number of entries (keys) to allocate for.
199 *
200 * @return On success, the initialized map. Otherwise NULL.
201 *
202 * @relatesalso as_orderedmap
203 */
205
206/**
207 * Creates a new map as an orderedmap.
208 *
209 * @param capacity The number of keys to allocate for.
210 *
211 * @return On success, the new map. Otherwise NULL.
212 *
213 * @relatesalso as_orderedmap
214 */
216
217/**
218 * Free the map and associated resources.
219 *
220 * @param map The map to destroy.
221 *
222 * @relatesalso as_orderedmap
223 */
225
226/**
227 * Get the number of entries in the map.
228 *
229 * @param map The map.
230 *
231 * @return The number of entries in the map.
232 *
233 * @relatesalso as_orderedmap
234 */
236
237/**
238 * Get the value for specified key.
239 *
240 * @param map The map.
241 * @param key The key.
242 *
243 * @return The value for the specified key. Otherwise NULL.
244 *
245 * @relatesalso as_orderedmap
246 */
248
249/**
250 * Set the value for specified key.
251 *
252 * @param map The map.
253 * @param key The key.
254 * @param val The value for the given key.
255 *
256 * @return 0 on success. Otherwise an error occurred.
257 *
258 * @relatesalso as_orderedmap
259 */
260AS_EXTERN int as_orderedmap_set(as_orderedmap* map, const as_val* key, const as_val* val);
261
262/**
263 * Remove all entries from the map.
264 *
265 * @param map The map.
266 *
267 * @return 0 on success. Otherwise an error occurred.
268 *
269 * @relatesalso as_orderedmap
270 */
272
273/**
274 * Remove the entry specified by the key.
275 *
276 * @param map The map to remove the entry from.
277 * @param key The key of the entry to be removed.
278 *
279 * @return 0 on success. Otherwise an error occurred.
280 *
281 * @relatesalso as_orderedmap
282 */
284
285/**
286 * Set map attributes.
287 *
288 * @relatesalso as_orderedmap
289 */
290static inline void
292{
293 map->_.flags = flags & AS_MAP_FLAGS_MASK;
294
295 // Ensure k-ordered is set when other bits require k-ordered to be set.
296 if (map->_.flags != 0) {
297 map->_.flags |= 1;
298 }
299}
300
301
302/******************************************************************************
303 * ITERATION FUNCTIONS
304 *****************************************************************************/
305
306/**
307 * Call the callback function for each entry in the map.
308 *
309 * @param map The map.
310 * @param callback The function to call for each entry.
311 * @param udata User-data to be passed to the callback.
312 *
313 * @return true if iteration completes fully. false if iteration was aborted.
314 *
315 * @relatesalso as_orderedmap
316 */
318
319/**
320 * Initializes a stack allocated as_iterator for the given as_orderedmap.
321 *
322 * @param it The iterator to initialize.
323 * @param map The map to iterate.
324 *
325 * @return On success, the initialized iterator. Otherwise NULL.
326 *
327 * @relatesalso as_orderedmap_iterator
328 */
330
331/**
332 * Creates a heap allocated as_iterator for the given as_orderedmap.
333 *
334 * @param map The map to iterate.
335 *
336 * @return On success, the new iterator. Otherwise NULL.
337 *
338 * @relatesalso as_orderedmap_iterator
339 */
341
342/**
343 * Destroy the iterator and releases resources used by the iterator.
344 *
345 * @param it The iterator to release
346 *
347 * @relatesalso as_orderedmap_iterator
348 */
350
351/**
352 * Tests if there are more values available in the iterator.
353 *
354 * @param it The iterator to be tested.
355 *
356 * @return true if there are more values. Otherwise false.
357 *
358 * @relatesalso as_orderedmap_iterator
359 */
361
362/**
363 * Attempts to get the next value from the iterator.
364 * This will return the next value, and iterate past the value.
365 *
366 * @param it The iterator to get the next value from.
367 *
368 * @return The next value in the list if available. Otherwise NULL.
369 *
370 * @relatesalso as_orderedmap_iterator
371 */
373
374#ifdef __cplusplus
375} // end extern "C"
376#endif
#define AS_MAP_FLAGS_MASK
Definition as_map.h:33
bool(* as_map_foreach_callback)(const as_val *key, const as_val *value, void *udata)
Definition as_map.h:49
#define AS_EXTERN
Definition as_std.h:25
uint32_t flags
Definition as_map.h:73
AS_EXTERN const as_val * as_orderedmap_iterator_next(as_orderedmap_iterator *it)
const as_orderedmap * map
AS_EXTERN as_orderedmap_iterator * as_orderedmap_iterator_new(const as_orderedmap *map)
AS_EXTERN as_orderedmap_iterator * as_orderedmap_iterator_init(as_orderedmap_iterator *it, const as_orderedmap *map)
AS_EXTERN bool as_orderedmap_iterator_has_next(const as_orderedmap_iterator *it)
AS_EXTERN void as_orderedmap_iterator_destroy(as_orderedmap_iterator *it)
AS_EXTERN uint32_t as_orderedmap_size(const as_orderedmap *map)
uint32_t * hold_locations
AS_EXTERN as_orderedmap * as_orderedmap_new(uint32_t capacity)
AS_EXTERN void as_orderedmap_destroy(as_orderedmap *map)
uint32_t hold_count
map_entry * hold_table
AS_EXTERN int as_orderedmap_clear(as_orderedmap *map)
AS_EXTERN int as_orderedmap_remove(as_orderedmap *map, const as_val *key)
AS_EXTERN int as_orderedmap_set(as_orderedmap *map, const as_val *key, const as_val *val)
AS_EXTERN as_val * as_orderedmap_get(const as_orderedmap *map, const as_val *key)
AS_EXTERN bool as_orderedmap_foreach(const as_orderedmap *map, as_map_foreach_callback callback, void *udata)
AS_EXTERN as_orderedmap * as_orderedmap_init(as_orderedmap *map, uint32_t capacity)
map_entry * table
uint32_t capacity
static void as_orderedmap_set_flags(as_orderedmap *map, uint32_t flags)
as_val * key
as_val * value