X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/c6d610b3ae7344e3f209515558daf0b4a8667824..c49140baf3058c9e38e1c5cc38140d676012ac0a:/src/xbt/dynar.c diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 513fc13602..21dd9c49f0 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -523,7 +523,9 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, /** @brief Returns the position of the element in the dynar * - * Raises not_found_error if not found. + * Raises not_found_error if not found. If you have less than 2 millions elements, + * you probably want to use #xbt_dynar_search_or_negative() instead, so that you + * don't have to TRY/CATCH on element not found. */ unsigned int xbt_dynar_search(xbt_dynar_t const dynar, void *const elem) { @@ -541,6 +543,26 @@ unsigned int xbt_dynar_search(xbt_dynar_t const dynar, void *const elem) dynar); } +/** @brief Returns the position of the element in the dynar (or -1 if not found) + * + * Note that usually, the dynar indices are unsigned integers. If you have more + * than 2 million elements in your dynar, this very function will not work (but the other will). + */ +signed int xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const elem) +{ + unsigned long it; + + _dynar_lock(dynar); + for (it = 0; it < dynar->used; it++) + if (!memcmp(_xbt_dynar_elm(dynar, it), elem, dynar->elmsize)) { + _dynar_unlock(dynar); + return it; + } + + _dynar_unlock(dynar); + return -1; +} + /** @brief Returns a boolean indicating whether the element is part of the dynar */ int xbt_dynar_member(xbt_dynar_t const dynar, void *const elem) { @@ -736,41 +758,39 @@ XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar, int_f_pvoid_t color) { _dynar_lock(dynar); - unsigned long size = xbt_dynar_length(dynar); - char *data = (char *) dynar->data; unsigned long int i; unsigned long int p = -1; - unsigned long int q = size; + unsigned long int q = dynar->used; const unsigned long elmsize = dynar->elmsize; - char *tmp = xbt_malloc(elmsize); - -#define swap(a,b) do { \ - memcpy(tmp, a , elmsize); \ - memcpy( a , b , elmsize); \ - memcpy( b , tmp, elmsize); \ - } while(0) + void *tmp = xbt_malloc(elmsize); + void *elm; for (i = 0; i < q;) { - char *datai = data + i*elmsize; - int colori = color(datai); + void *elmi = _xbt_dynar_elm(dynar, i); + int colori = color(elmi); - if(colori==0) { - char *datap = data + (++p)*elmsize; - swap(datai, datap); + if (colori == 1) { ++i; - } else if (colori==2) { - char *dataq = data + (--q)*elmsize; - swap(datai, dataq); } else { - ++i; + if (colori == 0) { + elm = _xbt_dynar_elm(dynar, ++p); + ++i; + } else { /* colori == 2 */ + elm = _xbt_dynar_elm(dynar, --q); + } + if (elm != elmi) { + memcpy(tmp, elm, elmsize); + memcpy(elm, elmi, elmsize); + memcpy(elmi, tmp, elmsize); + } } } - xbt_free(tmp); _dynar_unlock(dynar); + xbt_free(tmp); } -/** @brief Transform a dynar into a NULL terminated array - * +/** @brief Transform a dynar into a NULL terminated array. + * The dynar won't be usable afterwards. * \param dynar the dynar to transform */ XBT_INLINE void * xbt_dynar_to_array (xbt_dynar_t dynar) @@ -789,43 +809,43 @@ XBT_INLINE void * xbt_dynar_to_array (xbt_dynar_t dynar) * Return 0 if d1 and d2 are equal and 1 if not equal */ XBT_INLINE int xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, - int(*compar)(const void *, const void *)) + int(*compar)(const void *, const void *)) { - int i ; - int size; - if((!d1) && (!d2)) return 0; - if((!d1) || (!d2)) - { - XBT_DEBUG("NULL dynar d1=%p d2=%p",d1,d2); - xbt_dynar_free(&d2); - return 1; - } - if((d1->elmsize)!=(d2->elmsize)) - { - XBT_DEBUG("Size of elmsize d1=%lu d2=%lu",d1->elmsize,d2->elmsize); - xbt_dynar_free(&d2); - return 1; // xbt_die - } - if(xbt_dynar_length(d1) != xbt_dynar_length(d2)) - { - XBT_DEBUG("Size of dynar d1=%lu d2=%lu",xbt_dynar_length(d1),xbt_dynar_length(d2)); - xbt_dynar_free(&d2); - return 1; - } - - size = xbt_dynar_length(d1); - for(i=0;ielmsize)!=(d2->elmsize)) + { + XBT_DEBUG("Size of elmsize d1=%lu d2=%lu",d1->elmsize,d2->elmsize); + xbt_dynar_free(&d2); + return 1; // xbt_die + } + if(xbt_dynar_length(d1) != xbt_dynar_length(d2)) + { + XBT_DEBUG("Size of dynar d1=%lu d2=%lu",xbt_dynar_length(d1),xbt_dynar_length(d2)); + xbt_dynar_free(&d2); + return 1; + } + + size = xbt_dynar_length(d1); + for(i=0;i