#include "xbt/dynar_private.h" /* type definition, which we share with the
code in charge of sending this across the net */
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(dynar,xbt,"Dynamic arrays");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_dyn,xbt,"Dynamic arrays");
#define __sanity_check_dynar(dynar) \
xbt_assert1(dynar->used, \
"dynar %p contains nothing",(void*)dynar)
-static _XBT_INLINE
+static XBT_INLINE
void _xbt_clear_mem(void * const ptr,
const unsigned long length) {
memset(ptr, 0, length);
}
-static _XBT_INLINE
+static XBT_INLINE
void
_xbt_dynar_expand(xbt_dynar_t const dynar,
const int nb) {
}
}
-static _XBT_INLINE
+static XBT_INLINE
void *
_xbt_dynar_elm(const xbt_dynar_t dynar,
const unsigned long idx) {
return data + idx*elmsize;
}
-static _XBT_INLINE
+static XBT_INLINE
void
_xbt_dynar_get_elm(void * const dst,
const xbt_dynar_t dynar,
memcpy(dst, elm, dynar->elmsize);
}
-static _XBT_INLINE
+static XBT_INLINE
void
_xbt_dynar_put_elm(const xbt_dynar_t dynar,
const unsigned long idx,
* types (int, char, double, etc) or pointer of pointers (struct **).
*/
xbt_dynar_t
-xbt_dynar_new(const unsigned long elmsize,
+xbt_dynar_new(const unsigned long elmsize,
void_f_pvoid_t * const free_f) {
xbt_dynar_t dynar = xbt_new0(s_xbt_dynar_t,1);
/* dynar->data = NULL;*/
}
+/**
+ * \brief Shrink the dynar by removing empty slots at the end of the internal array
+ * \param dynar a dynar
+ * \param empty_slots_wanted number of empty slots you want to keep at the end of the
+ * internal array for further insertions
+ *
+ * Reduces the internal array size of the dynar to the number of elements plus
+ * \a empty_slots_wanted.
+ * After removing elements from the dynar, you can call this function to make
+ * the dynar use less memory.
+ * Set \a empty_slots_wanted to zero to reduce the dynar internal array as much
+ * as possible.
+ * Note that if \a empty_slots_wanted is greater than the array size, the internal
+ * array is not expanded and nothing is done.
+ */
+void xbt_dynar_shrink(xbt_dynar_t dynar, int empty_slots_wanted) {
+ int size_wanted = dynar->used + empty_slots_wanted;
+ if (size_wanted < dynar->size) {
+ dynar->size = size_wanted;
+ dynar->data = xbt_realloc(dynar->data, sizeof(void*) * dynar->size);
+ }
+}
+
/** @brief Destructor
*
* \param dynar poor victim
*
* Get the Nth element of a dynar, removing it from the dynar and moving
* all subsequent values to one position left in the dynar.
+ *
+ * If the object argument of this function is a non-null pointer, the removed
+ * element is copied to this address. If not, the element is freed using the
+ * free_f function passed at dynar creation.
*/
void
xbt_dynar_remove_at(xbt_dynar_t const dynar,
if (object) {
_xbt_dynar_get_elm(object, dynar, idx);
} else if (dynar->free_f) {
- char elm[SIZEOF_MAX];
- _xbt_dynar_get_elm(elm, dynar, idx);
- (*dynar->free_f)(elm);
+ if (dynar->elmsize <= SIZEOF_MAX) {
+ char elm[SIZEOF_MAX];
+ _xbt_dynar_get_elm(elm, dynar, idx);
+ (*dynar->free_f)(elm);
+ } else {
+ char *elm=malloc(dynar->elmsize);
+ _xbt_dynar_get_elm(elm, dynar, idx);
+ (*dynar->free_f)(elm);
+ free(elm);
+ }
}
nb_shift = dynar->used-1 - idx;
void *const elem) {
int it;
- for (it=0; it< dynar->size; it++)
+ for (it=0; it< dynar->used; it++)
if (!memcmp(_xbt_dynar_elm(dynar, it),elem,dynar->elmsize))
return it;
*/
void xbt_dynar_cursor_rm(xbt_dynar_t dynar,
int * const cursor) {
- void *dst;
-
- if (dynar->elmsize > sizeof(void*)) {
- DEBUG0("Elements too big to fit into a pointer");
- if (dynar->free_f) {
- dst=xbt_malloc(dynar->elmsize);
- xbt_dynar_remove_at(dynar,(*cursor)--,dst);
- (dynar->free_f)(dst);
- free(dst);
- } else {
- DEBUG0("Ok, we dont care about the element without free function");
- xbt_dynar_remove_at(dynar,(*cursor)--,NULL);
- }
-
- } else {
- xbt_dynar_remove_at(dynar,(*cursor)--,&dst);
- if (dynar->free_f)
- (dynar->free_f)(dst);
- }
+
+ xbt_dynar_remove_at(dynar,(*cursor)--,NULL);
}
#ifdef SIMGRID_TEST
#define NB_ELEM 5000
XBT_TEST_SUITE("dynar","Dynar data container");
-XBT_LOG_EXTERNAL_CATEGORY(dynar);
-XBT_LOG_DEFAULT_CATEGORY(dynar);
+XBT_LOG_EXTERNAL_CATEGORY(xbt_dyn);
+XBT_LOG_DEFAULT_CATEGORY(xbt_dyn);
XBT_TEST_UNIT("int",test_dynar_int,"Dyars of integers") {
/* Vars_decl [doxygen cruft] */