All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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
25 extern "C" {
26 #endif
27 
28 
29 /******************************************************************************
30  * TYPES
31  ******************************************************************************/
32 
33 /**
34  * Private helper structure.
35  */
36 typedef 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  */
106 typedef 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;
116 } as_orderedmap;
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  */
181 typedef 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  */
204 AS_EXTERN as_orderedmap* as_orderedmap_init(as_orderedmap* map, uint32_t capacity);
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  */
215 AS_EXTERN as_orderedmap* as_orderedmap_new(uint32_t capacity);
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  */
235 AS_EXTERN uint32_t as_orderedmap_size(const as_orderedmap* map);
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  */
247 AS_EXTERN as_val* as_orderedmap_get(const as_orderedmap* map, const as_val* key);
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  */
260 AS_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  */
283 AS_EXTERN int as_orderedmap_remove(as_orderedmap* map, const as_val* key);
284 
285 /**
286  * Set map attributes.
287  *
288  * @relatesalso as_orderedmap
289  */
290 static 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  */
317 AS_EXTERN bool as_orderedmap_foreach(const as_orderedmap* map, as_map_foreach_callback callback, void* udata);
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
AS_EXTERN void as_orderedmap_iterator_destroy(as_orderedmap_iterator *it)
bool(* as_map_foreach_callback)(const as_val *key, const as_val *value, void *udata)
Definition: as_map.h:49
#define AS_MAP_FLAGS_MASK
Definition: as_map.h:33
Definition: as_map.h:61
AS_EXTERN int as_orderedmap_clear(as_orderedmap *map)
uint32_t count
AS_EXTERN void as_orderedmap_destroy(as_orderedmap *map)
AS_EXTERN as_orderedmap * as_orderedmap_init(as_orderedmap *map, uint32_t capacity)
AS_EXTERN as_orderedmap_iterator * as_orderedmap_iterator_new(const as_orderedmap *map)
Definition: as_val.h:61
#define AS_EXTERN
Definition: as_std.h:25
as_val * value
Definition: as_orderedmap.h:38
AS_EXTERN const as_val * as_orderedmap_iterator_next(as_orderedmap_iterator *it)
uint32_t flags
Definition: as_map.h:73
uint32_t * hold_locations
uint32_t hold_count
static void as_orderedmap_set_flags(as_orderedmap *map, uint32_t flags)
AS_EXTERN int as_orderedmap_remove(as_orderedmap *map, const as_val *key)
AS_EXTERN as_orderedmap_iterator * as_orderedmap_iterator_init(as_orderedmap_iterator *it, const as_orderedmap *map)
as_val * key
Definition: as_orderedmap.h:37
AS_EXTERN bool as_orderedmap_iterator_has_next(const as_orderedmap_iterator *it)
AS_EXTERN as_val * as_orderedmap_get(const as_orderedmap *map, const as_val *key)
const as_orderedmap * map
AS_EXTERN bool as_orderedmap_foreach(const as_orderedmap *map, as_map_foreach_callback callback, void *udata)
AS_EXTERN int as_orderedmap_set(as_orderedmap *map, const as_val *key, const as_val *val)
AS_EXTERN uint32_t as_orderedmap_size(const as_orderedmap *map)
AS_EXTERN as_orderedmap * as_orderedmap_new(uint32_t capacity)
uint32_t capacity
Definition: as_orderedmap.h:36
map_entry * hold_table
map_entry * table