/** @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)
{
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)
{
int_f_pvoid_t color)
{
_dynar_lock(dynar);
- unsigned long size = xbt_dynar_length(dynar);
- void *data = dynar->data;
unsigned long int i;
unsigned long int p = -1;
- unsigned long int q = size;
- unsigned long elmsize = dynar->elmsize;
+ unsigned long int q = dynar->used;
+ const unsigned long elmsize = dynar->elmsize;
void *tmp = xbt_malloc(elmsize);
-
-#define swap(a,b) do { \
- memcpy(tmp, a , elmsize); \
- memcpy( a , b , elmsize); \
- memcpy( b , tmp, elmsize); \
- } while(0)
+ void *elm;
for (i = 0; i < q;) {
- unsigned long int datai = ((unsigned long int) data) + i*elmsize;
- int colori = color((void *) datai);
+ void *elmi = _xbt_dynar_elm(dynar, i);
+ int colori = color(elmi);
- if(colori==0) {
- unsigned long int datap = ((unsigned long int) data) + (++p)*elmsize;
- swap((void *) datai, (void *) datap);
+ if (colori == 1) {
++i;
- } else if (colori==2) {
- unsigned long int dataq = ((unsigned long int) data) + (--q)*elmsize;
- swap((void *) datai, (void *) 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);
+ }
}
}
_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)
* 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;i<size;i++)
- {
- void *data1 = xbt_dynar_get_as(d1, i, void *);
- void *data2 = xbt_dynar_get_as(d2, i, void *);
- XBT_DEBUG("link[%d] d1=%p d2=%p",i,data1,data2);
- if(compar(data1,data2)){
- xbt_dynar_free(&d2);
- return 1;
- }
- }
- xbt_dynar_free(&d2);
- return 0;
+ 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;i<size;i++)
+ {
+ void *data1 = xbt_dynar_get_as(d1, i, void *);
+ void *data2 = xbt_dynar_get_as(d2, i, void *);
+ XBT_DEBUG("link[%d] d1=%p d2=%p",i,data1,data2);
+ if(compar(data1,data2)){
+ xbt_dynar_free(&d2);
+ return 1;
+ }
+ }
+ xbt_dynar_free(&d2);
+ return 0;
}
#ifdef SIMGRID_TEST