From: Maximiliano Geier Date: Thu, 31 Jan 2013 10:59:44 +0000 (+0100) Subject: Added xbt_dynar_remove_n_at to remove an n-sized slice from a dynar X-Git-Tag: v3_9_90~588 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2da2db01b8e191c17611482e5282f8a59dc18ecd Added xbt_dynar_remove_n_at to remove an n-sized slice from a dynar This function is used to speed up pulling out trace events from the buffer --- diff --git a/include/xbt/dynar.h b/include/xbt/dynar.h index 79b590d6d0..1e710f4493 100644 --- a/include/xbt/dynar.h +++ b/include/xbt/dynar.h @@ -92,6 +92,9 @@ XBT_PUBLIC(void) xbt_dynar_insert_at(xbt_dynar_t const dynar, const int idx, const void *src); XBT_PUBLIC(void) xbt_dynar_remove_at(xbt_dynar_t const dynar, const int idx, void *const dst); +XBT_PUBLIC(void) xbt_dynar_remove_n_at(xbt_dynar_t const dynar, + const unsigned int n, const int idx); + XBT_PUBLIC(unsigned int) xbt_dynar_search(xbt_dynar_t const dynar, void *elem); XBT_PUBLIC(signed int) xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const elem); diff --git a/src/instr/instr_paje_trace.c b/src/instr/instr_paje_trace.c index 555ac028e8..e3d78b2f0b 100644 --- a/src/instr/instr_paje_trace.c +++ b/src/instr/instr_paje_trace.c @@ -224,15 +224,16 @@ void TRACE_paje_dump_buffer (int force) buffer = xbt_dynar_new (sizeof(paje_event_t), NULL); }else{ paje_event_t event; - while (!xbt_dynar_is_empty(buffer)){ - double head_timestamp = (*(paje_event_t*)xbt_dynar_get_ptr(buffer, 0))->timestamp; + unsigned int cursor; + xbt_dynar_foreach(buffer, cursor, event) { + double head_timestamp = event->timestamp; if (head_timestamp > TRACE_last_timestamp_to_dump){ break; } - xbt_dynar_remove_at (buffer, 0, &event); event->print (event); event->free (event); } + xbt_dynar_remove_n_at(buffer, cursor, 0); } XBT_DEBUG("%s: ends", __FUNCTION__); } diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 0fa7f41328..720b376b89 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -425,6 +425,45 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, dynar->used--; } +/** @brief Remove a slice of the dynar, sliding the rest of the values to the left + * + * This function removes an n-sized slice that starts at element idx. It is equivalent + * to xbt_dynar_remove_at with a NULL object argument if n equals to 1. + * + * Each of the removed elements is freed using the free_f function passed at dynar + * creation. + */ +void +xbt_dynar_remove_n_at(xbt_dynar_t const dynar, + const unsigned int n, const int idx) +{ + unsigned long nb_shift; + unsigned long offset; + unsigned long cur; + + if (!n) return; + + _sanity_check_dynar(dynar); + _check_inbound_idx(dynar, idx); + _check_inbound_idx(dynar, idx + n - 1); + + if (dynar->free_f) { + for (cur = idx; cur < idx + n; cur++) { + dynar->free_f(_xbt_dynar_elm(dynar, cur)); + } + } + + nb_shift = dynar->used - n - idx; + + if (nb_shift) { + offset = nb_shift * dynar->elmsize; + memmove(_xbt_dynar_elm(dynar, idx), _xbt_dynar_elm(dynar, idx + n), + offset); + } + + dynar->used -= n; +} + /** @brief Returns the position of the element in the dynar * * Raises not_found_error if not found. If you have less than 2 millions elements,