All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_arraylist.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2014 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_integer.h>
21 #include <aerospike/as_string.h>
22 #include <aerospike/as_bytes.h>
23 #include <aerospike/as_list.h>
24 #include <aerospike/as_map.h>
25 #include <aerospike/as_val.h>
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 
30 /******************************************************************************
31  * TYPES
32  *****************************************************************************/
33 
34 /**
35  * An dynamic array implementation for as_list.
36  *
37  * as_arryalist can either be initialize on the stack or the heap.
38  *
39  * For stack allocation, you have two choices:
40  * - `as_arraylist_init()` - uses `cf_malloc()` to initialize the internal storage
41  * on the heap.
42  * - `as_arraylist_inita()` - uses `alloca()` to initialize the internal storage
43  * on the stack.
44  *
45  * The key differences between the two is `as_arraylist_inita()` can't be
46  * dynamically resized and is solely on the stack.
47  *
48  * The following is using a `as_arraylist_inita()`:
49  * ~~~~~~~~~~{.c}
50  * as_arraylist list;
51  * as_arraylist_inita(&list, 2);
52  * ~~~~~~~~~~
53  *
54  * You will notice that the code is quite similar to `as_arraylist_init()`:
55  * ~~~~~~~~~~{.c}
56  * as_arraylist list;
57  * as_arraylist_init(&list, 2, 0);
58  * ~~~~~~~~~~
59  *
60  * If you need a new heap allocated list, then use `as_arraylist_new()`:
61  *
62  * ~~~~~~~~~~{.c}
63  * as_arraylist * list = as_arraylist_new(2, 0);
64  * ~~~~~~~~~~
65  *
66  * When you are finished using the list, then you should release the list and
67  * associated resources, using `as_arraylist_destroy()`:
68  *
69  * ~~~~~~~~~~{.c}
70  * as_arraylist_destroy(list);
71  * ~~~~~~~~~~
72  *
73  *
74  * The `as_arraylist` is a subtype of `as_list`. This allows you to
75  * alternatively use `as_list` functions, by typecasting `as_arraylist` to
76  * `as_list`.
77  *
78  * ~~~~~~~~~~{.c}
79  * as_arraylist list;
80  * as_list * l = (as_list *) as_arraylist_init(&list, 3, 0);
81  * as_list_append_int64(l, 1);
82  * as_list_append_int64(l, 2);
83  * as_list_append_int64(l, 3);
84  * as_list_destroy(l);
85  * ~~~~~~~~~~
86  *
87  * Each of the `as_list` functions proxy to the `as_arraylist` functions.
88  * So, calling `as_list_destroy()` is equivalent to calling
89  * `as_arraylist_destroy()`.
90  *
91  * @extends as_list
92  * @ingroup aerospike_t
93  */
94 typedef struct as_arraylist_s {
95 
96  /**
97  * @private
98  * as_arraylist is an as_list.
99  * You can cast as_arraylist to as_list.
100  */
102 
103  /**
104  * Number of elements to add, when capacity is reached.
105  * If 0 (zero), then capacity can't be expanded.
106  */
107  uint32_t block_size;
108 
109  /**
110  * The total number elements allocated.
111  */
112  uint32_t capacity;
113 
114  /**
115  * The number of elements used.
116  */
117  uint32_t size;
118 
119  /**
120  * The elements of the list.
121  */
123 
124  /**
125  * If true, then as_arraylist.elements will be freed when
126  * as_arraylist_destroy() is called.
127  */
128  bool free;
129 
130 } as_arraylist;
131 
132 /**
133  * Status codes for various as_arraylist operations.
134  */
135 typedef enum as_arraylist_status_e {
136 
137  /**
138  * Normal operation.
139  */
141 
142  /**
143  * Unable to expand capacity, because cf_realloc() failed.
144  */
146 
147  /**
148  * Unable to expand capacity, because as_arraylist.block_size is 0.
149  */
151 
153 
154 /******************************************************************************
155  * MACROS
156  ******************************************************************************/
157 
158 /**
159  * Initialize a stack allocated as_arraylist, with element storage on
160  * the stack.
161  *
162  * This differs from as_arraylist_init(), in that as_arraylist_init()
163  * allocates element storage on the heap.
164  *
165  * @param __list The as_list to initialize
166  * @param __n The number of elements to allocate to the list.
167  *
168  * @return On success, the initialize list. Otherwise NULL.
169  * @relatesalso as_arraylist
170  */
171 #define as_arraylist_inita(__list, __n)\
172  as_arraylist_init((__list), 0, 0);\
173  (__list)->free = false;\
174  (__list)->capacity = __n;\
175  (__list)->size = 0;\
176  (__list)->elements = (as_val **) alloca(sizeof(as_val *) * __n);
177 
178 /*******************************************************************************
179  * INSTANCE FUNCTIONS
180  ******************************************************************************/
181 
182 /**
183  * Initialize a stack allocated as_arraylist, with element storage on the
184  * heap.
185  *
186  * This differs from as_arraylist_inita(), in that as_arraylist_inita()
187  * allocates element storage on the stack.
188  *
189  * @param list The as_list to initialize
190  * @param capacity The number of elements to allocate to the list.
191  * @param block_size The number of elements to grow the list by, when the
192  * capacity has been reached.
193  *
194  * @return On success, the initialize list. Otherwise NULL.
195  * @relatesalso as_arraylist
196  */
197 as_arraylist * as_arraylist_init(as_arraylist * list, uint32_t capacity, uint32_t block_size);
198 
199 /**
200  * Create and initialize a heap allocated list as as_arraylist.
201  *
202  * @param capacity The number of elements to allocate to the list.
203  * @param block_size The number of elements to grow the list by, when the
204  * capacity has been reached.
205  *
206  * @return On success, the new list. Otherwise NULL.
207  * @relatesalso as_arraylist
208  */
209 as_arraylist * as_arraylist_new(uint32_t capacity, uint32_t block_size);
210 
211 /**
212  * Destoy the list and release resources.
213  *
214  * @param list The list to destroy.
215  * @relatesalso as_arraylist
216  */
218 
219 /*******************************************************************************
220  * VALUE FUNCTIONS
221  ******************************************************************************/
222 
223 /**
224  * The hash value of the list.
225  *
226  * @param list The list.
227  *
228  * @return The hash value of the list.
229  * @relatesalso as_arraylist
230  */
231 uint32_t as_arraylist_hashcode(const as_arraylist * list);
232 
233 /**
234  * The number of elements in the list.
235  *
236  * @param list The list.
237  *
238  * @return The number of elements in the list.
239  * @relatesalso as_arraylist
240  */
241 uint32_t as_arraylist_size(const as_arraylist * list);
242 
243 /*******************************************************************************
244  * ACCESSOR AND MODIFIER FUNCTIONS
245  ******************************************************************************/
246 
247 /**
248  * Get the first element of the list.
249  *
250  * @param list The list to get the first element from.
251  *
252  * @return The first element of the list. Otherwise NULL.
253  * @relatesalso as_arraylist
254  */
255 as_val * as_arraylist_head(const as_arraylist * list);
256 
257 /**
258  * Returns a new list containing all elements other than the head
259  *
260  * @param list The list to get the elements from.
261  *
262  * @return A new list of all elements after the first element.
263  * @relatesalso as_arraylist
264  */
266 
267 /**
268  * Return a new list with the first n elements removed.
269  *
270  * @param list The list.
271  * @param n The number of elements to remove.
272  *
273  * @return A new list of all elements after the first n elements.
274  * @relatesalso as_arraylist
275  */
276 as_arraylist * as_arraylist_drop(const as_arraylist * list, uint32_t n);
277 
278 /**
279  * Return a new list containing the first n elements.
280  *
281  * @param list The list.
282  * @param n The number of elements to take.
283  *
284  * @return A new list of the first n elements.
285  * @relatesalso as_arraylist
286  */
287 as_arraylist * as_arraylist_take(const as_arraylist * list, uint32_t n);
288 
289 /******************************************************************************
290  * GET FUNCTIONS
291  ******************************************************************************/
292 
293 /**
294  * Return the value at the specified index.
295  *
296  * @param list The list.
297  * @param index The index of the element.
298  *
299  * @return The value at given index, if it exists. Otherwise NULL.
300  * @relatesalso as_arraylist
301  */
302 as_val * as_arraylist_get(const as_arraylist * list, const uint32_t index);
303 
304 /**
305  * Return an int64_t value at the specified index of the list.
306  *
307  * @param list The list.
308  * @param index The index of the element.
309  *
310  * @return The value at given index, if it exists. Otherwise NULL.
311  * @relatesalso as_arraylist
312  */
313 int64_t as_arraylist_get_int64(const as_arraylist * list, const uint32_t index);
314 
315 /**
316  * Return a NULL-terminated value at the specified index of the list.
317  *
318  * @param list The list.
319  * @param index The index of the element.
320  *
321  * @return The value at given index, if it exists. Otherwise NULL.
322  * @relatesalso as_arraylist
323  */
324 char * as_arraylist_get_str(const as_arraylist * list, const uint32_t index);
325 
326 /**
327  * Return an as_integer value at the specified index of the list.
328  *
329  * @param list The list.
330  * @param index The index of the element.
331  *
332  * @return The value at given index, if it exists. Otherwise NULL.
333  * @relatesalso as_arraylist
334  */
335 static inline as_integer * as_arraylist_get_integer(const as_arraylist * list, const uint32_t index)
336 {
337  return as_integer_fromval(as_arraylist_get(list, index));
338 }
339 
340 /**
341  * Return an as_string value at the specified index of the list.
342  *
343  * @param list The list.
344  * @param index The index of the element.
345  *
346  * @return The value at given index, if it exists. Otherwise NULL.
347  * @relatesalso as_arraylist
348  */
349 static inline as_string * as_arraylist_get_string(const as_arraylist * list, const uint32_t index)
350 {
351  return as_string_fromval(as_arraylist_get(list, index));
352 }
353 
354 /**
355  * Return an as_bytes value at the specified index of the list.
356  *
357  * @param list The list.
358  * @param index The index of the element.
359  *
360  * @return The value at given index, if it exists. Otherwise NULL.
361  * @relatesalso as_arraylist
362  */
363 static inline as_bytes * as_arraylist_get_bytes(const as_arraylist * list, const uint32_t index)
364 {
365  return as_bytes_fromval(as_arraylist_get(list, index));
366 }
367 
368 /**
369  * Return an as_list value at the specified index of the list.
370  *
371  * @param list The list.
372  * @param index The index of the element.
373  *
374  * @return The value at given index, if it exists. Otherwise NULL.
375  * @relatesalso as_arraylist
376  */
377 static inline as_list * as_arraylist_get_list(const as_arraylist * list, const uint32_t index)
378 {
379  return as_list_fromval(as_arraylist_get(list, index));
380 }
381 
382 /**
383  * Return an as_map value at the specified index of the list.
384  *
385  * @param list The list.
386  * @param index The index of the element.
387  *
388  * @return The value at given index, if it exists. Otherwise NULL.
389  * @relatesalso as_arraylist
390  */
391 static inline as_map * as_arraylist_get_map(const as_arraylist * list, const uint32_t index)
392 {
393  return as_map_fromval(as_arraylist_get(list, index));
394 }
395 
396 /******************************************************************************
397  * SET FUNCTIONS
398  ******************************************************************************/
399 
400 /**
401  * Set a value at the specified index of the list.
402  *
403  * Notice that in order to maintain proper object/memory management, we
404  * just first destroy (as_val_destroy()) the old object at element position(i)
405  * before assigning the new element. Also note that the object at element
406  * position (i) is assumed to exist, so all element positions must be
407  * appropriately initialized to zero.
408  *
409  * @param list The list.
410  * @param index Position in the list.
411  * @param value The value to set at the given index.
412  *
413  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
414  * @relatesalso as_arraylist
415  */
416 int as_arraylist_set(as_arraylist * list, const uint32_t index, as_val * value);
417 
418 /**
419  * Set an int64_t value at the specified index of the list.
420  *
421  * @param list The list.
422  * @param index Position in the list.
423  * @param value The value to set at the given index.
424  *
425  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
426  * @relatesalso as_arraylist
427  */
428 int as_arraylist_set_int64(as_arraylist * list, const uint32_t index, int64_t value);
429 
430 /**
431  * Set a NULL-terminated string value at the specified index of the list.
432  *
433  * @param list The list.
434  * @param index Position in the list.
435  * @param value The value to set at the given index.
436  *
437  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
438  * @relatesalso as_arraylist
439  */
440 int as_arraylist_set_str(as_arraylist * list, const uint32_t index, const char * value);
441 
442 /**
443  * Set an as_integer value at the specified index of the list.
444  *
445  * @param list The list.
446  * @param index Position in the list.
447  * @param value The value to set at the given index.
448  *
449  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
450  * @relatesalso as_arraylist
451  */
452 static inline int as_arraylist_set_integer(as_arraylist * list, const uint32_t index, as_integer * value)
453 {
454  return as_arraylist_set(list, index, (as_val *) value);
455 }
456 
457 /**
458  * Set an as_string value at the specified index of the list.
459  *
460  * @param list The list.
461  * @param index Position in the list.
462  * @param value The value to set at the given index.
463  *
464  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
465  * @relatesalso as_arraylist
466  */
467 static inline int as_arraylist_set_string(as_arraylist * list, const uint32_t index, as_string * value)
468 {
469  return as_arraylist_set(list, index, (as_val *) value);
470 }
471 
472 /**
473  * Set an as_bytes value at the specified index of the list.
474  *
475  * @param list The list.
476  * @param index Position in the list.
477  * @param value The value to set at the given index.
478  *
479  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
480  * @relatesalso as_arraylist
481  */
482 static inline int as_arraylist_set_bytes(as_arraylist * list, const uint32_t index, as_bytes * value)
483 {
484  return as_arraylist_set(list, index, (as_val *) value);
485 }
486 
487 /**
488  * Set an as_list value at the specified index of the list.
489  *
490  * @param list The list.
491  * @param index Position in the list.
492  * @param value The value to set at the given index.
493  *
494  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
495  * @relatesalso as_arraylist
496  */
497 static inline int as_arraylist_set_list(as_arraylist * list, const uint32_t index, as_list * value)
498 {
499  return as_arraylist_set(list, index, (as_val *) value);
500 }
501 
502 /**
503  * Set an as_map value at the specified index of the list.
504  *
505  * @param list The list.
506  * @param index Position in the list.
507  * @param value The value to set at the given index.
508  *
509  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
510  * @relatesalso as_arraylist
511  */
512 static inline int as_arraylist_set_map(as_arraylist * list, const uint32_t index, as_map * value)
513 {
514  return as_arraylist_set(list, index, (as_val *) value);
515 }
516 
517 /******************************************************************************
518  * APPEND FUNCTIONS
519  ******************************************************************************/
520 
521 /**
522  * Add the value to the end of the list.
523  *
524  * @param list The list.
525  * @param value The value to prepend.
526  *
527  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
528  * @relatesalso as_arraylist
529  */
530 int as_arraylist_append(as_arraylist * list, as_val * value);
531 
532 /**
533  * Add an int64_t to the end of the list.
534  *
535  * @param list The list.
536  * @param value The value to prepend.
537  *
538  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
539  * @relatesalso as_arraylist
540  */
541 int as_arraylist_append_int64(as_arraylist * list, int64_t value);
542 
543 /**
544  * Add a NULL-terminated string to the end of the list.
545  *
546  * @param list The list.
547  * @param value The value to prepend.
548  *
549  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
550  * @relatesalso as_arraylist
551  */
552 int as_arraylist_append_str(as_arraylist * list, const char * value);
553 
554 /**
555  * Add an as_integer to the end of the list.
556  *
557  * @param list The list.
558  * @param value The value to prepend.
559  *
560  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
561  * @relatesalso as_arraylist
562  */
563 static inline int as_arraylist_append_integer(as_arraylist * list, as_integer * value)
564 {
565  return as_arraylist_append(list, (as_val *) value);
566 }
567 
568 /**
569  * Add an as_string to the end of the list.
570  *
571  * @param list The list.
572  * @param value The value to prepend.
573  *
574  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
575  * @relatesalso as_arraylist
576  */
577 static inline int as_arraylist_append_string(as_arraylist * list, as_string * value)
578 {
579  return as_arraylist_append(list, (as_val *) value);
580 }
581 
582 /**
583  * Add an as_bytes to the end of the list.
584  *
585  * @param list The list.
586  * @param value The value to prepend.
587  *
588  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
589  * @relatesalso as_arraylist
590  */
591 static inline int as_arraylist_append_bytes(as_arraylist * list, as_bytes * value)
592 {
593  return as_arraylist_append(list, (as_val *) value);
594 }
595 
596 /**
597  * Add an as_list to the end of the list.
598  *
599  * @param list The list.
600  * @param value The value to prepend.
601  *
602  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
603  * @relatesalso as_arraylist
604  */
605 static inline int as_arraylist_append_list(as_arraylist * list, as_list * value)
606 {
607  return as_arraylist_append(list, (as_val *) value);
608 }
609 
610 /**
611  * Add an as_map to the end of the list.
612  *
613  * @param list The list.
614  * @param value The value to prepend.
615  *
616  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
617  * @relatesalso as_arraylist
618  */
619 static inline int as_arraylist_append_map(as_arraylist * list, as_map * value)
620 {
621  return as_arraylist_append(list, (as_val *) value);
622 }
623 
624 /******************************************************************************
625  * PREPEND FUNCTIONS
626  ******************************************************************************/
627 
628 /**
629  * Add the value to the beginning of the list.
630  *
631  * @param list The list.
632  * @param value The value to prepend.
633  *
634  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
635  * @relatesalso as_arraylist
636  */
637 int as_arraylist_prepend(as_arraylist * list, as_val * value);
638 
639 /**
640  * Add an int64_t to the beginning of the list.
641  *
642  * @param list The list.
643  * @param value The value to prepend.
644  *
645  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
646  * @relatesalso as_arraylist
647  */
648 int as_arraylist_prepend_int64(as_arraylist * list, int64_t value);
649 
650 /**
651  * Add a NULL-terminated string to the beginning of the list.
652  *
653  * @param list The list.
654  * @param value The value to prepend.
655  *
656  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
657  * @relatesalso as_arraylist
658  */
659 int as_arraylist_prepend_str(as_arraylist * list, const char * value);
660 
661 /**
662  * Add an as_integer to the beginning of the list.
663  *
664  * @param list The list.
665  * @param value The value to prepend.
666  *
667  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
668  * @relatesalso as_arraylist
669  */
670 static inline int as_arraylist_prepend_integer(as_arraylist * list, as_integer * value)
671 {
672  return as_arraylist_prepend(list, (as_val *) value);
673 }
674 
675 /**
676  * Add an as_string to the beginning of the list.
677  *
678  * @param list The list.
679  * @param value The value to prepend.
680  *
681  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
682  * @relatesalso as_arraylist
683  */
684 static inline int as_arraylist_prepend_string(as_arraylist * list, as_string * value)
685 {
686  return as_arraylist_prepend(list, (as_val *) value);
687 }
688 
689 /**
690  * Add an as_bytes to the beginning of the list.
691  *
692  * @param list The list.
693  * @param value The value to prepend.
694  *
695  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
696  * @relatesalso as_arraylist
697  */
698 static inline int as_arraylist_prepend_bytes(as_arraylist * list, as_bytes * value)
699 {
700  return as_arraylist_prepend(list, (as_val *) value);
701 }
702 
703 /**
704  * Add an as_list to the beginning of the list.
705  *
706  * @param list The list.
707  * @param value The value to prepend.
708  *
709  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
710  * @relatesalso as_arraylist
711  */
712 static inline int as_arraylist_prepend_list(as_arraylist * list, as_list * value)
713 {
714  return as_arraylist_prepend(list, (as_val *) value);
715 }
716 
717 /**
718  * Add an as_map to the beginning of the list.
719  *
720  * @param list The list.
721  * @param value The value to prepend.
722  *
723  * @return AS_ARRAYLIST_OK on success. Otherwise an error occurred.
724  * @relatesalso as_arraylist
725  */
726 static inline int as_arraylist_prepend_map(as_arraylist * list, as_map * value)
727 {
728  return as_arraylist_prepend(list, (as_val *) value);
729 }
730 
731 /******************************************************************************
732  * ITERATION FUNCTIONS
733  ******************************************************************************/
734 
735 /**
736  * Call the callback function for each element in the list.
737  *
738  * @param list The list to iterate.
739  * @param callback The function to call for each element in the list.
740  * @param udata User-data to be sent to the callback.
741  *
742  * @return true if iteration completes fully. false if iteration was aborted.
743  *
744  * @relatesalso as_arraylist
745  */
746 bool as_arraylist_foreach(const as_arraylist * list, as_list_foreach_callback callback, void * udata);
747