Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a function to merge 2 dynar to avoid xbt_dynar_push in a loop
authornavarro <navarro@caraja.(none)>
Wed, 7 Mar 2012 18:20:47 +0000 (19:20 +0100)
committernavarro <navarro@caraja.(none)>
Wed, 7 Mar 2012 18:21:27 +0000 (19:21 +0100)
include/xbt/dynar.h
src/surf/surf_routing.c
src/xbt/dynar.c

index 9e2a65d..382c643 100644 (file)
@@ -111,7 +111,7 @@ XBT_PUBLIC(void *) xbt_dynar_to_array (xbt_dynar_t dynar);
 XBT_PUBLIC(unsigned long) xbt_dynar_length(const xbt_dynar_t dynar);
 XBT_PUBLIC(int) xbt_dynar_is_empty(const xbt_dynar_t dynar);
 XBT_PUBLIC(void) xbt_dynar_reset(xbt_dynar_t const dynar);
-
+XBT_PUBLIC(void) xbt_dynar_merge(xbt_dynar_t *d1, xbt_dynar_t *d2);
 
 /** @} */
 /** @defgroup XBT_dynar_perl Perl-like use of dynars
index a0d7d02..96d3634 100644 (file)
@@ -504,8 +504,6 @@ static void elements_father(const char *src, const char *dst,
 static void _get_route_and_latency(const char *src, const char *dst,
                                    xbt_dynar_t * links, double *latency)
 {
-  void *link;
-  unsigned int cpt;
   s_route_t route;
   memset(&route,0,sizeof(route));
 
@@ -540,10 +538,7 @@ static void _get_route_and_latency(const char *src, const char *dst,
 
 //    // FIXME this path is never tested. I need examples to check the bypass mechanism...
 //    THROW_UNIMPLEMENTED; // let's warn the users of the problem
-    xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
-      xbt_dynar_push(*links, &link);
-    }
-
+    xbt_dynar_merge(links,&(e_route_bypass->link_list));
     generic_free_route(e_route_bypass);
     return;
   }
@@ -564,9 +559,7 @@ static void _get_route_and_latency(const char *src, const char *dst,
   if (strcmp(src, src_gateway))
     _get_route_and_latency(src, src_gateway, links, latency);
 
-  xbt_dynar_foreach(route.link_list, cpt, link) {
-    xbt_dynar_push(*links, &link);
-  }
+  xbt_dynar_merge(links,&(route.link_list));
 
   /* If dest gateway is not our destination, we have to recursively find our way from this point */
   // FIXME why can't I factorize it the same way than [src;src_gw] without breaking the examples??
@@ -612,25 +605,18 @@ static xbt_dynar_t recursive_get_onelink_routes(AS_t rc)
   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
 
   //adding my one link routes
-  unsigned int cpt;
-  void *link;
   xbt_dynar_t onelink_mine = rc->get_onelink_routes(rc);
-  if (onelink_mine) {
-    xbt_dynar_foreach(onelink_mine, cpt, link) {
-      xbt_dynar_push(ret, &link);
-    }
-  }
+  if (onelink_mine)
+    xbt_dynar_merge(&ret,&onelink_mine);
+
   //recursing
   char *key;
   xbt_dict_cursor_t cursor = NULL;
   AS_t rc_child;
   xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
     xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
-    if (onelink_child) {
-      xbt_dynar_foreach(onelink_child, cpt, link) {
-        xbt_dynar_push(ret, &link);
-      }
-    }
+    if (onelink_child)
+      xbt_dynar_merge(&ret,&onelink_child);
   }
   return ret;
 }
index 6bf067c..0574b41 100644 (file)
@@ -238,6 +238,28 @@ XBT_INLINE void xbt_dynar_reset(xbt_dynar_t const dynar)
   _dynar_unlock(dynar);
 }
 
+/** @brief Merge dynar d2 into d1
+ *
+ * \param d1 dynar to keep
+ * \param d2 dynar to merge into d1. This dynar is free at end.
+ */
+void xbt_dynar_merge(xbt_dynar_t *d1, xbt_dynar_t *d2)
+{
+  if((*d1)->elmsize != (*d2)->elmsize)
+    xbt_die("Element size must are not equal");
+
+  const unsigned long elmsize = (*d1)->elmsize;
+
+  void *ptr = _xbt_dynar_elm((*d2), 0);
+  _xbt_dynar_resize(*d1, (*d1)->size + (*d2)->size);
+  void *elm = _xbt_dynar_elm((*d1), (*d1)->used);
+
+  memcpy(elm, ptr, ((*d2)->size)*elmsize);
+  (*d1)->used += (*d2)->used;
+  (*d2)->used = 0;
+  xbt_dynar_free(d2);
+}
+
 /**
  * \brief Shrink the dynar by removing empty slots at the end of the internal array
  * \param dynar a dynar