This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/fix-array-list-initial-capability-bug
in repository https://gitbox.apache.org/repos/asf/celix.git

commit ebca40daf57c7cebbb168985fc51d54e36b4d1d3
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Dec 14 20:08:12 2025 +0100

    Use initialCapacity option in celix array list
---
 .../gtest/src/ArrayListErrorInjectionTestSuite.cc  | 15 ++++++
 libs/utils/include/celix_array_list.h              | 60 ++++++++++++----------
 libs/utils/src/array_list.c                        | 46 ++++++++---------
 3 files changed, 71 insertions(+), 50 deletions(-)

diff --git a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc 
b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
index 6f95a4a6d..6dd99e2b4 100644
--- a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
@@ -160,3 +160,18 @@ TEST_F(ArrayListErrorInjectionTestSuite, 
CopyArrayListFailureTest) {
     // And a celix_err is expected
     EXPECT_EQ(3, celix_err_getErrorCount());
 }
+
+
+TEST_F(ArrayListErrorInjectionTestSuite, InitialCapacityOptionUsed) {
+    celix_array_list_create_options_t opts{};
+    opts.elementType = CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING;
+    opts.initialCapacity = 1; // smaller than number of elements we will add
+    celix_autoptr(celix_array_list_t) list = 
celix_arrayList_createWithOptions(&opts);
+
+    // First add fits in initial capacity
+    EXPECT_EQ(CELIX_SUCCESS, celix_arrayList_addString(list, "v1"));
+
+    // Fail the next realloc to verify that a second add triggers a 
reallocation
+    celix_ei_expect_realloc((void*)celix_arrayList_addString, 2, nullptr, 1);
+    EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addString(list, "v2"));
+}
diff --git a/libs/utils/include/celix_array_list.h 
b/libs/utils/include/celix_array_list.h
index 8393bc238..bc78b216a 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -20,9 +20,9 @@
 #include <stdbool.h>
 
 #include "celix_array_list_type.h"
-#include "celix_utils_export.h"
 #include "celix_cleanup.h"
 #include "celix_errno.h"
+#include "celix_utils_export.h"
 #include "celix_version_type.h"
 
 #ifndef CELIX_ARRAY_LIST_H_
@@ -32,12 +32,13 @@
  * Init macro so that the opts are correctly initialized for C++ compilers
  */
 #ifdef __cplusplus
-#define CELIX_OPTS_INIT {}
+#define CELIX_OPTS_INIT                                                        
                                        \
+    {                                                                          
                                        \
+    }
 #else
 #define CELIX_OPTS_INIT
 #endif
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -57,7 +58,7 @@ typedef enum celix_array_list_element_type {
     CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING = 2, /**< Represents a string element 
type where the array list is the owner */
     CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG = 3,   /**< Represents a long integer 
element type. */
     CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE = 4, /**< Represents a double element 
type. */
-    CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL = 5,  /**< Represents a boolean element 
type. */
+    CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL = 5,   /**< Represents a boolean 
element type. */
     CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION = 6, /**< Represents a 
celix_version_t* element type. */
 } celix_array_list_element_type_t;
 
@@ -75,10 +76,10 @@ typedef union celix_array_list_entry {
                               CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING_REF or 
CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
     long int longVal;      /**< A long integer value when the element type is 
CELIX_ARRAY_LIST_ELEMENT_TYPE_LONG or
                               CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
-    double doubleVal;       /**< A double value when the element type is 
CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
-                               CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
-    bool boolVal;           /**< A boolean value when the element type is 
CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
-                               CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+    double doubleVal;      /**< A double value when the element type is 
CELIX_ARRAY_LIST_ELEMENT_TYPE_DOUBLE or
+                              CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
+    bool boolVal;          /**< A boolean value when the element type is 
CELIX_ARRAY_LIST_ELEMENT_TYPE_BOOL or
+                              CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
     const celix_version_t* versionVal; /**< A celix_version_t* value when the 
element type is
                                    CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION or 
CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED. */
 } celix_array_list_entry_t;
@@ -252,9 +253,14 @@ typedef struct celix_array_list_create_options {
  */
 #define CELIX_EMPTY_ARRAY_LIST_CREATE_OPTIONS                                  
                                        \
     {                                                                          
                                        \
-        .elementType = CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED, 
.simpleRemovedCallback = NULL,                         \
-        .removedCallbackData = NULL, .removedCallback = NULL, .equalsCallback 
= NULL,                                  \
-        .compareCallback = NULL, .copyCallback = NULL,                         
                                        \
+        .elementType = CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED,                
                                        \
+        .simpleRemovedCallback = NULL,                                         
                                        \
+        .removedCallbackData = NULL,                                           
                                        \
+        .removedCallback = NULL,                                               
                                        \
+        .equalsCallback = NULL,                                                
                                        \
+        .compareCallback = NULL,                                               
                                        \
+        .copyCallback = NULL,                                                  
                                        \
+        .initialCapacity = 0,                                                  
                                        \
     }
 #endif
 
@@ -280,7 +286,7 @@ celix_array_list_t* celix_arrayList_createWithOptions(const 
celix_array_list_cre
  * @note If a (simple) removed callback is configured, the callback will be 
called for every array list entry.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_destroy(celix_array_list_t *list);
+void celix_arrayList_destroy(celix_array_list_t* list);
 
 CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_array_list_t, celix_arrayList_destroy)
 
@@ -288,13 +294,13 @@ CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_array_list_t, 
celix_arrayList_destroy)
  * @brief Return the element type of the array list.
  */
 CELIX_UTILS_EXPORT
-celix_array_list_element_type_t celix_arrayList_getElementType(const 
celix_array_list_t *list);
+celix_array_list_element_type_t celix_arrayList_getElementType(const 
celix_array_list_t* list);
 
 /**
  * @brief Returns the size of the array list.
  */
 CELIX_UTILS_EXPORT
-int celix_arrayList_size(const celix_array_list_t *list);
+int celix_arrayList_size(const celix_array_list_t* list);
 
 /**
  * @brief Returns the value for the provided index.
@@ -307,7 +313,7 @@ int celix_arrayList_size(const celix_array_list_t *list);
  * @return Returns the pointer value for the index. Returns NULL if index is 
out of bound.
  */
 CELIX_UTILS_EXPORT
-void* celix_arrayList_get(const celix_array_list_t *list, int index);
+void* celix_arrayList_get(const celix_array_list_t* list, int index);
 
 /**
  * @brief Returns the value for the provided index.
@@ -320,7 +326,7 @@ void* celix_arrayList_get(const celix_array_list_t *list, 
int index);
  * @return Returns the string value for the index. Returns NULL if index is 
out of bound.
  */
 CELIX_UTILS_EXPORT
-const char* celix_arrayList_getString(const celix_array_list_t *list, int 
index);
+const char* celix_arrayList_getString(const celix_array_list_t* list, int 
index);
 
 /**
  * @brief Returns the value for the provided index.
@@ -333,7 +339,7 @@ const char* celix_arrayList_getString(const 
celix_array_list_t *list, int index)
  * @return Returns the long value for the index. Returns 0 if index is out of 
bound.
  */
 CELIX_UTILS_EXPORT
-long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
+long int celix_arrayList_getLong(const celix_array_list_t* list, int index);
 
 /**
  * @brief Returns the value for the provided index.
@@ -346,7 +352,7 @@ long int celix_arrayList_getLong(const celix_array_list_t 
*list, int index);
  * @return Returns the double value for the index. Returns 0 if index is out 
of bound.
  */
 CELIX_UTILS_EXPORT
-double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
+double celix_arrayList_getDouble(const celix_array_list_t* list, int index);
 
 /**
  * @brief Returns the value for the provided index.
@@ -359,7 +365,7 @@ double celix_arrayList_getDouble(const celix_array_list_t 
*list, int index);
  * @return Returns the bool value for the index. Returns false if index is out 
of bound.
  */
 CELIX_UTILS_EXPORT
-bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
+bool celix_arrayList_getBool(const celix_array_list_t* list, int index);
 
 /**
  * @brief Returns the value for the provided index.
@@ -372,7 +378,7 @@ bool celix_arrayList_getBool(const celix_array_list_t 
*list, int index);
  * @return Returns the version value for the index. Returns NULL if index is 
out of bound.
  */
 CELIX_UTILS_EXPORT
-const celix_version_t* celix_arrayList_getVersion(const celix_array_list_t 
*list, int index);
+const celix_version_t* celix_arrayList_getVersion(const celix_array_list_t* 
list, int index);
 
 /**
  * @brief Returns the entry for the provided index.
@@ -382,7 +388,7 @@ const celix_version_t* celix_arrayList_getVersion(const 
celix_array_list_t *list
  * @return Returns the entry for the index. Returns NULL if index is out of 
bound.
  */
 CELIX_UTILS_EXPORT
-celix_array_list_entry_t celix_arrayList_getEntry(const celix_array_list_t 
*list, int index);
+celix_array_list_entry_t celix_arrayList_getEntry(const celix_array_list_t* 
list, int index);
 
 /**
  * @brief add pointer entry to the back of the array list.
@@ -529,14 +535,14 @@ celix_status_t 
celix_arrayList_assignVersion(celix_array_list_t* list, celix_ver
  * @return The index of the entry or -1 if the entry is not found.
  */
 CELIX_UTILS_EXPORT
-int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t 
entry);
+int celix_arrayList_indexOf(celix_array_list_t* list, celix_array_list_entry_t 
entry);
 
 /**
  * @brief Removes an entry at the provided index.
  * If the provided index < 0 or out of bound, nothing will be removed.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_removeAt(celix_array_list_t *list, int index);
+void celix_arrayList_removeAt(celix_array_list_t* list, int index);
 
 /**
  * @brief Clear all entries in the array list.
@@ -544,7 +550,7 @@ void celix_arrayList_removeAt(celix_array_list_t *list, int 
index);
  * @note If a (simple) removed callback is configured, the callback will be 
called for every array list entry.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_clear(celix_array_list_t *list);
+void celix_arrayList_clear(celix_array_list_t* list);
 
 /**
  * @brief Remove the first entry from array list which matches the provided 
value.
@@ -556,7 +562,7 @@ void celix_arrayList_clear(celix_array_list_t *list);
  * If there was no equals callback provided a direct memory compare will be 
done.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_removeEntry(celix_array_list_t *list, 
celix_array_list_entry_t entry);
+void celix_arrayList_removeEntry(celix_array_list_t* list, 
celix_array_list_entry_t entry);
 
 /**
  * @brief Remove the first pointer entry from array list which matches the 
provided value.
@@ -634,14 +640,14 @@ void celix_arrayList_removeVersion(celix_array_list_t* 
list, const celix_version
  * @brief Sort the array list using the provided sort function.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_sortEntries(celix_array_list_t *list, 
celix_array_list_compare_entries_fp compare);
+void celix_arrayList_sortEntries(celix_array_list_t* list, 
celix_array_list_compare_entries_fp compare);
 
 /**
  * @brief Sort the array list using the array list configured compare function.
  * Note that undefined the array list compare function can be NULL and in that 
case the array list will not be sorted.
  */
 CELIX_UTILS_EXPORT
-void celix_arrayList_sort(celix_array_list_t *list);
+void celix_arrayList_sort(celix_array_list_t* list);
 
 /**
  * @brief Check if the array list are equal.
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index 361525f2e..ea49c85ce 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -41,7 +41,7 @@ struct celix_array_list {
     celix_array_list_entry_t* elementData;
     size_t size;
     size_t capacity;
-    celix_arrayList_equals_fp  equalsCallback;
+    celix_arrayList_equals_fp equalsCallback;
     celix_array_list_compare_entries_fp compareCallback;
     celix_array_list_copy_entry_fp copyCallback;
     void (*simpleRemovedCallback)(void* value);
@@ -101,7 +101,8 @@ static bool 
celix_arrayList_versionEquals(celix_array_list_entry_t a, celix_arra
     return celix_arrayList_compareVersionEntries(a, b) == 0;
 }
 
-inline static bool celix_arrayList_equalsForElement(celix_array_list_t *list, 
celix_array_list_entry_t a, celix_array_list_entry_t b) {
+inline static bool
+celix_arrayList_equalsForElement(celix_array_list_t* list, 
celix_array_list_entry_t a, celix_array_list_entry_t b) {
     // by class invariant, equalsCallback is never NULL
     return list->equalsCallback(a, b);
 }
@@ -129,7 +130,7 @@ static void celix_arrayList_destroyVersion(void* v) {
     celix_version_destroy(version);
 }
 
-static void celix_arrayList_callRemovedCallback(celix_array_list_t *list, int 
index) {
+static void celix_arrayList_callRemovedCallback(celix_array_list_t* list, int 
index) {
     celix_array_list_entry_t entry = list->elementData[index];
     if (list->simpleRemovedCallback != NULL) {
         list->simpleRemovedCallback(entry.voidPtrVal);
@@ -139,7 +140,7 @@ static void 
celix_arrayList_callRemovedCallback(celix_array_list_t *list, int in
 }
 
 static celix_status_t celix_arrayList_ensureCapacity(celix_array_list_t* list, 
size_t capacity) {
-    celix_array_list_entry_t *newList;
+    celix_array_list_entry_t* newList;
     size_t oldCapacity = list->capacity;
     if (capacity > oldCapacity) {
         size_t newCapacity = (oldCapacity * 3) / 2 + 1;
@@ -192,13 +193,14 @@ static void 
celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) {
 }
 
 celix_array_list_t* celix_arrayList_createWithOptions(const 
celix_array_list_create_options_t* opts) {
-    celix_autofree celix_array_list_t *list = calloc(1, sizeof(*list));
+    celix_autofree celix_array_list_t* list = calloc(1, sizeof(*list));
     if (!list) {
         celix_err_push("Failed to allocate memory for list");
         return NULL;
     }
 
-    list->capacity = 10;
+    size_t initialCap = opts->initialCapacity > 0 ? opts->initialCapacity : 10;
+    list->capacity = initialCap;
     list->elementData = calloc(list->capacity, 
sizeof(celix_array_list_entry_t));
     if (!list->elementData) {
         celix_err_push("Failed to allocate memory for elementData");
@@ -208,7 +210,7 @@ celix_array_list_t* celix_arrayList_createWithOptions(const 
celix_array_list_cre
     list->elementType = opts->elementType;
     celix_arrayList_setTypeSpecificCallbacks(list);
 
-    //if opts contains callbacks, use them and override the default ones
+    // if opts contains callbacks, use them and override the default ones
     if (opts->simpleRemovedCallback) {
         list->simpleRemovedCallback = opts->simpleRemovedCallback;
     }
@@ -262,7 +264,7 @@ celix_array_list_t* celix_arrayList_createVersionArray() {
     return 
celix_arrayList_createTypedArray(CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION);
 }
 
-void celix_arrayList_destroy(celix_array_list_t *list) {
+void celix_arrayList_destroy(celix_array_list_t* list) {
     if (list != NULL) {
         celix_arrayList_clear(list);
         free(list->elementData);
@@ -270,15 +272,13 @@ void celix_arrayList_destroy(celix_array_list_t *list) {
     }
 }
 
-celix_array_list_element_type_t celix_arrayList_getElementType(const 
celix_array_list_t *list) {
+celix_array_list_element_type_t celix_arrayList_getElementType(const 
celix_array_list_t* list) {
     return list->elementType;
 }
 
-int celix_arrayList_size(const celix_array_list_t *list) {
-    return (int)list->size;
-}
+int celix_arrayList_size(const celix_array_list_t* list) { return 
(int)list->size; }
 
-static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t 
*list, int index) {
+static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t* 
list, int index) {
     celix_array_list_entry_t entry;
     memset(&entry, 0, sizeof(entry));
     if (index < list->size) {
@@ -287,7 +287,7 @@ static celix_array_list_entry_t arrayList_getEntry(const 
celix_array_list_t *lis
     return entry;
 }
 
-celix_array_list_entry_t celix_arrayList_getEntry(const celix_array_list_t 
*list, int index) {
+celix_array_list_entry_t celix_arrayList_getEntry(const celix_array_list_t* 
list, int index) {
     return arrayList_getEntry(list, index);
 }
 
@@ -429,11 +429,11 @@ celix_status_t 
celix_arrayList_assignVersion(celix_array_list_t* list, celix_ver
     return celix_arrayList_addEntry(list, entry);
 }
 
-int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t 
entry) {
+int celix_arrayList_indexOf(celix_array_list_t* list, celix_array_list_entry_t 
entry) {
     size_t size = celix_arrayList_size(list);
     int i;
     int index = -1;
-    for (i = 0 ; i < size ; ++i) {
+    for (i = 0; i < size; ++i) {
         bool eq = celix_arrayList_equalsForElement(list, entry, 
list->elementData[i]);
         if (eq) {
             index = i;
@@ -442,16 +442,16 @@ int celix_arrayList_indexOf(celix_array_list_t *list, 
celix_array_list_entry_t e
     }
     return index;
 }
-void celix_arrayList_removeAt(celix_array_list_t *list, int index) {
+void celix_arrayList_removeAt(celix_array_list_t* list, int index) {
     if (index >= 0 && index < list->size) {
         celix_arrayList_callRemovedCallback(list, index);
         size_t numMoved = list->size - index - 1;
-        memmove(list->elementData+index, list->elementData+index+1, 
sizeof(celix_array_list_entry_t) * numMoved);
+        memmove(list->elementData + index, list->elementData + index + 1, 
sizeof(celix_array_list_entry_t) * numMoved);
         memset(&list->elementData[--list->size], 0, 
sizeof(celix_array_list_entry_t));
     }
 }
 
-void celix_arrayList_removeEntry(celix_array_list_t *list, 
celix_array_list_entry_t entry) {
+void celix_arrayList_removeEntry(celix_array_list_t* list, 
celix_array_list_entry_t entry) {
     int index = celix_arrayList_indexOf(list, entry);
     celix_arrayList_removeAt(list, index);
 }
@@ -510,7 +510,7 @@ void celix_arrayList_removeVersion(celix_array_list_t* 
list, const celix_version
     celix_arrayList_removeEntry(list, entry);
 }
 
-void celix_arrayList_clear(celix_array_list_t *list) {
+void celix_arrayList_clear(celix_array_list_t* list) {
     for (int i = 0; i < list->size; ++i) {
         celix_arrayList_callRemovedCallback(list, i);
         memset(&list->elementData[i], 0, sizeof(celix_array_list_entry_t));
@@ -529,7 +529,7 @@ static int celix_arrayList_compareEntries(const void* 
voidA, const void* voidB,
     return compare(*a, *b);
 }
 
-void celix_arrayList_sort(celix_array_list_t *list) {
+void celix_arrayList_sort(celix_array_list_t* list) {
     if (list->compareCallback) {
         celix_arrayList_sortEntries(list, list->compareCallback);
     }
@@ -592,7 +592,7 @@ celix_array_list_t* celix_arrayList_copy(const 
celix_array_list_t* list) {
                 return NULL;
             }
         } else {
-            entry = list->elementData[i]; //shallow copy
+            entry = list->elementData[i]; // shallow copy
         }
 
         (void)celix_arrayList_addEntry(copy, entry); // Cannot fail, because 
ensureCapacity is already called to
@@ -602,7 +602,7 @@ celix_array_list_t* celix_arrayList_copy(const 
celix_array_list_t* list) {
     return celix_steal_ptr(copy);
 }
 
-void celix_arrayList_sortEntries(celix_array_list_t *list, 
celix_array_list_compare_entries_fp compare) {
+void celix_arrayList_sortEntries(celix_array_list_t* list, 
celix_array_list_compare_entries_fp compare) {
 #if defined(__APPLE__)
     qsort_r(list->elementData, list->size, sizeof(celix_array_list_entry_t), 
compare, celix_arrayList_compareEntries);
 #else

Reply via email to