Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added xbt_dynar_remove_n_at to remove an n-sized slice from a dynar
authorMaximiliano Geier <maximiliano.geier@loria.fr>
Thu, 31 Jan 2013 10:59:44 +0000 (11:59 +0100)
committerMaximiliano Geier <maximiliano.geier@loria.fr>
Thu, 31 Jan 2013 10:59:44 +0000 (11:59 +0100)
This function is used to speed up pulling out trace events from the buffer

include/xbt/dynar.h
src/instr/instr_paje_trace.c
src/xbt/dynar.c

index 79b590d..1e710f4 100644 (file)
@@ -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);
                                      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);
 
 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);
index 555ac02..e3d78b2 100644 (file)
@@ -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;
     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;
       }
       if (head_timestamp > TRACE_last_timestamp_to_dump){
         break;
       }
-      xbt_dynar_remove_at (buffer, 0, &event);
       event->print (event);
       event->free (event);
     }
       event->print (event);
       event->free (event);
     }
+    xbt_dynar_remove_n_at(buffer, cursor, 0);
   }
   XBT_DEBUG("%s: ends", __FUNCTION__);
 }
   }
   XBT_DEBUG("%s: ends", __FUNCTION__);
 }
index 0fa7f41..720b376 100644 (file)
@@ -425,6 +425,45 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar,
   dynar->used--;
 }
 
   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,
 /** @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,