gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r28052 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r28052 - msh/src
Date: Mon, 15 Jul 2013 18:39:56 +0200

Author: harsha
Date: 2013-07-15 18:39:55 +0200 (Mon, 15 Jul 2013)
New Revision: 28052

Modified:
   msh/src/addressmap.c
   msh/src/addressmap.h
   msh/src/mtypes.h
   msh/src/test_addressmap.c
Log:
intersection of addresses


Modified: msh/src/addressmap.c
===================================================================
--- msh/src/addressmap.c        2013-07-15 15:19:46 UTC (rev 28051)
+++ msh/src/addressmap.c        2013-07-15 16:39:55 UTC (rev 28052)
@@ -7,6 +7,7 @@
 #include "common.h"
 #include "util.h"
 #include "addressmap.h"
+#include "mtypes.h"
 
 
 /**
@@ -136,6 +137,7 @@
       break;
     addr = addr->next;
   }
+  iainfo->naddrs++;
   if (NULL == addr)
   {
     DLL_insert_tail (iainfo->addr_head, iainfo->addr_tail, iaddr);
@@ -278,10 +280,11 @@
       if (instance_address_ip (new_ia) < instance_address_ip (old_ia))
         break;
       old_ia = old_ia->next;
-    }
+    }    
     iacpy = MSH_malloc (sizeof (struct InstanceAddr) + new_ia->addrlen);
     (void) memcpy (iacpy->saddr, new_ia->saddr, new_ia->addrlen);
     iacpy->addrlen = new_ia->addrlen;
+    old->naddrs++;
     if (NULL == old_ia)
     {
       DLL_insert_tail (old->addr_head, old->addr_tail, iacpy);
@@ -295,7 +298,61 @@
 }
 
 
+/**
+ * Removes the addresses which are present in the Addressmap but not in the
+ * given instance address information object
+ *
+ * @param m the addressmap
+ * @param new the instance address information object
+ * @return the number of addresses in common; MSH_SYSERR upon error
+ */
+int
+addressmap_intersect (AddressMap *m, struct InstanceAddrInfo *new)
+{
+  struct InstanceAddrInfo *old;
+  struct InstanceAddr *old_ia;
+  struct InstanceAddr *new_ia;
+  struct InstanceAddr *tmp;
+  unsigned int rank;
+  unsigned int n;
 
+  rank = new->rank;
+  MSH_assert (rank < m->size);
+  old = m->map[rank];
+  if (NULL == old)
+  {
+    m->map[rank] = new;
+    return MSH_SYSERR;
+  }
+  old_ia = old->addr_head;
+  new_ia = new->addr_head;
+  n = 0;
+  while (NULL != old_ia)
+  {
+    if ((NULL == new_ia) 
+        || (instance_address_ip (old_ia) < instance_address_ip (new_ia)) )
+    {
+      tmp = old_ia->next;
+      DLL_remove (old->addr_head, old->addr_tail, old_ia);
+      free (old_ia);
+      MSH_assert (old->naddrs > 0);
+      old->naddrs--;
+      old_ia = tmp;
+      continue;
+    }
+    if (instance_address_ip (old_ia) > instance_address_ip (new_ia))
+    {
+      new_ia = new_ia->next;
+      continue;
+    }
+    old_ia = old_ia->next;
+    new_ia = new_ia->next;
+    n++;
+  }
+  return n;
+}
+
+
 /**
  * Function to iterate over address of an instance in a given address map
  *
@@ -335,3 +392,114 @@
 }
 
 
+/**
+ * Serializes an address map into a message which can then be sent to an
+ * instance for merging into its address map
+ *
+ * @param m the address map
+ * @param map_msg the message describing the contents of the address map.  This
+ *          message is to be sent before sending the instance addresses in the
+ *          address map.  The memory allocated for the message is to be freed 
by
+ *          the caller after sending the message
+ * @param iaddr_msgs instance addresses.  The memory allocated for the instance
+ *          address messages is to be freed by the caller after sending the
+ *          messages
+ * @return MSH_OK upon successful completion; msh_syserr upon failure (the
+ *           contents of map_msg and iaddr_msgs are left unchanged)
+ */
+int
+addressmap_pack (AddressMap *m, struct MSH_MSG_AddressMap **map_msg,
+                 struct MSH_MSG_InstanceAdresses ***iaddr_msgs)
+{
+  struct MSH_MSG_AddressMap *_map_msg;
+  struct MSH_MSG_InstanceAdresses **_iaddr_msgs;
+  struct InstanceAddrInfo *iainfo;
+  struct InstanceAddr *iaddr;
+  uint16_t msize;
+  unsigned int cnt;
+  unsigned int n;
+  unsigned int nip;
+
+  n = 0;
+  for (cnt = 0; cnt < m->size; cnt++)
+  {
+    if (NULL == m->map[cnt])
+      continue;
+    n++;
+  }
+  cnt = n;
+  msize = sizeof (struct MSH_MSG_AddressMap);
+  _map_msg = MSH_malloc (msize);
+  _map_msg->header.size = htons (msize);
+  _map_msg->num = htons (n);
+  
+  _iaddr_msgs = MSH_malloc (sizeof (struct MSH_MSG_InstanceAdresses *) * n);
+  for (cnt = 0; cnt < m->size; cnt++)
+  {
+    if (NULL == (iainfo = m->map[cnt])) 
+      continue;
+    msize = sizeof (struct MSH_MSG_InstanceAdresses) 
+        + (sizeof (uint32_t) * iainfo->naddrs);
+    _iaddr_msgs[cnt] = MSH_malloc (msize);
+    _iaddr_msgs[cnt]->header.size = htons (msize);
+    _iaddr_msgs[cnt]->rank = htons (iainfo->rank);
+    _iaddr_msgs[cnt]->nips = htons (iainfo->naddrs);
+    iaddr = iainfo->addr_head;
+    for (nip = 0; nip < iainfo->naddrs; nip++, iaddr = iaddr->next)
+    {
+      MSH_assert (NULL != iaddr);
+      _iaddr_msgs[cnt]->ipaddrs[nip] = instance_address_ip (iaddr);
+    }
+  }  
+  *map_msg = _map_msg;
+  *iaddr_msgs = _iaddr_msgs;
+  return MSH_OK;
+}
+
+
+/**
+ * Modifies the given address map to contain the addresses present in it and in
+ * the given instance address message
+ *
+ * @param m the given address map
+ * @param iaddr_msg the message containing instance addresses
+ * @return the number of addresses present in the address map for this instance
+ *           after intersecting with the addresses from the given messager;
+ *           MSH_SYSERR if the given message is not successfully parsed
+ */
+int
+addressmap_intersect_msg (AddressMap *m, 
+                          struct MSH_MSG_InstanceAdresses *iaddr_msg)
+{
+  struct InstanceAddr *iaddr;
+  struct InstanceAddrInfo *iainfo;
+  unsigned int rank;
+  unsigned int n;
+  unsigned int cnt;
+  uint16_t size;
+
+  rank = (unsigned int) ntohs (iaddr_msg->rank);
+  n = (unsigned int) ntohs (iaddr_msg->nips);
+  size = ntohs (iaddr_msg->header.size);
+  if (size < (sizeof (struct MSH_MSG_InstanceAdresses)
+              + (sizeof (uint32_t) * n)) )
+  {
+    MSH_break (0);
+    return MSH_SYSERR;
+  }
+  if (n == 0)
+  {
+    MSH_break (0);
+    return MSH_SYSERR;
+  }
+  iainfo = instance_address_info_create (rank);
+  for (cnt = 0; cnt < n; cnt++)
+  {
+    iaddr = instance_address_create_sockaddr_in 
+        (0, (in_addr_t) iaddr_msg->ipaddrs[cnt]);
+    instance_address_info_add_address (iainfo, iaddr);
+  }
+  n = addressmap_intersect (m, iainfo);
+  instance_address_info_destroy (iainfo);
+  return n;
+}

Modified: msh/src/addressmap.h
===================================================================
--- msh/src/addressmap.h        2013-07-15 15:19:46 UTC (rev 28051)
+++ msh/src/addressmap.h        2013-07-15 16:39:55 UTC (rev 28052)
@@ -7,6 +7,9 @@
 #ifndef ADDRESSMAP_H_
 #define ADDRESSMAP_H_
 
+#include "common.h"
+#include "mtypes.h"
+
 /**
  * An address of an instance
  */
@@ -118,6 +121,16 @@
 
 
 /**
+ * Destroy the address map. Note that the instance address information object 
is
+ * not destroyed
+ *
+ * @param m the address map to destroy
+ */
+void
+addressmap_destroy (AddressMap *m);
+
+
+/**
  * Add an address to the address map
  *
  * @param m the address map
@@ -127,8 +140,72 @@
 addressmap_add (AddressMap *m, struct InstanceAddrInfo *new);
 
 
+/**
+ * Removes the addresses which are present in the Addressmap but not in the
+ * given instance address information object
+ *
+ * @param m the addressmap
+ * @param new the instance address information object
+ * @return the number of addresses in common; MSH_SYSERR upon error
+ */
+int
+addressmap_intersect (AddressMap *m, struct InstanceAddrInfo *new);
 
 
+/**
+ * Function to iterate over address of an instance in a given address map
+ *
+ * @param m the address map
+ * @param rank the instance rank
+ * @param cb the iterator callback
+ * @param cls the closure for the callback
+ * @return MSH_OK if the iteration was successfully completed; MSH_SYSERR if 
the
+ *           iteration was aborted in the iteration callback; MSH_NO if no
+ *           addresses were found in the address map
+ */
+int
+addressmap_iterate_instance_addresses (AddressMap *m, unsigned int rank,
+                                       instance_address_info_address_iterate_cb
+                                       cb, void *cls);
+
+
+/**
+ * Serializes an address map into a message which can then be sent to an
+ * instance for merging into its address map
+ *
+ * @param m the address map
+ * @param map_msg the message describing the contents of the address map.  This
+ *          message is to be sent before sending the instance addresses in the
+ *          address map.  The memory allocated for the message is to be freed 
by
+ *          the caller after sending the message
+ * @param iaddr_msgs instance addresses.  The memory allocated for the instance
+ *          address messages is to be freed by the caller after sending the
+ *          messages
+ * @return MSH_OK upon successful completion; msh_syserr upon failure (the
+ *           contents of map_msg and iaddr_msgs are left unchanged)
+ */
+int
+addressmap_pack (AddressMap *m, struct MSH_MSG_AddressMap **map_msg,
+                 struct MSH_MSG_InstanceAdresses ***iaddr_msgs);
+
+
+/**
+ * Modifies the given address map to contain the addresses present in it and in
+ * the given instance address message
+ *
+ * @param m the given address map
+ * @param iaddr_msg the message containing instance addresses
+ * @return the number of addresses present in the address map for this instance
+ *           after intersecting with the addresses from the given messager;
+ *           MSH_SYSERR if the given message is not successfully parsed
+ */
+int
+addressmap_intersect_msg (AddressMap *m, 
+                          struct MSH_MSG_InstanceAdresses *iaddr_msg);
+
+
+
+
 #endif  /* ADDRESSMAP_H_ */
 
 /* End of addressmap.h */

Modified: msh/src/mtypes.h
===================================================================
--- msh/src/mtypes.h    2013-07-15 15:19:46 UTC (rev 28051)
+++ msh/src/mtypes.h    2013-07-15 16:39:55 UTC (rev 28052)
@@ -1,6 +1,14 @@
+/**
+ * @file mtypes.h
+ * @brief message formats
+ * @author Sree Harsha Totakura <address@hidden> 
+ */
+
+#ifndef MTYPES_H_
+#define MTYPES_H_
+
 #include "common.h"
 
-
 /**
  * gcc-ism to get packed structs.  This won't work on W32 but then do we use 
W32
  * for HPC? ;)
@@ -90,8 +98,13 @@
  * denote a message but is used in @see MSH_MSG_AddressMap
  */
 struct MSH_MSG_InstanceAdresses
-{  
+{
   /**
+   * Header for this message
+   */
+  struct MSH_MessageHeader header;
+
+  /**
    * The rank of the instance
    */
   uint16_t rank MSH_PACKED;
@@ -117,5 +130,9 @@
 
 #define MSH_MTYPE_VERIFY_ADDRESSES 100
 
+#define MSH_MTYPE_ADDRESS_MAP 101
 
+#define MSH_MTYPE_INSTANCE_ADDRESS 102
 
+
+#endif  /* MTYPES_H_ */

Modified: msh/src/test_addressmap.c
===================================================================
--- msh/src/test_addressmap.c   2013-07-15 15:19:46 UTC (rev 28051)
+++ msh/src/test_addressmap.c   2013-07-15 16:39:55 UTC (rev 28052)
@@ -7,10 +7,12 @@
 #include "common.h"
 #include "util.h"
 #include "addressmap.h"
+#include "mtypes.h"
 
 
 static unsigned int cnt;
 
+
 /**
  * Callback for iterating all the instance addresses present in an instance
  * address info object
@@ -28,6 +30,98 @@
 }
 
 
+static void
+test_serialization (AddressMap *m)
+{
+  struct MSH_MSG_AddressMap *map_msg;
+  struct MSH_MSG_InstanceAdresses **iaddr_msgs;
+  unsigned int n;
+  unsigned int cnt;
+
+  MSH_assert (MSH_OK == addressmap_pack (m, &map_msg, &iaddr_msgs));
+  n = ntohs (map_msg->num);
+  for (cnt = 0; cnt < n; cnt++)
+  {
+    free (iaddr_msgs[cnt]);
+  }
+  free (iaddr_msgs);
+  free (map_msg);
+}
+
+
+static void
+test_deserialization ()
+{
+  AddressMap *m;
+  struct InstanceAddrInfo *iainfo1;
+  struct InstanceAddr *addr;
+  struct MSH_MSG_InstanceAdresses **iaddr_msgs;
+  
+  iainfo1 = instance_address_info_create (1);
+  addr = instance_address_create_sockaddr_in (0, 12);
+  instance_address_info_add_address (iainfo1, addr);
+  addr = instance_address_create_sockaddr_in (0, 2);
+  instance_address_info_add_address (iainfo1, addr);
+  addr = instance_address_create_sockaddr_in (0, 7);
+  instance_address_info_add_address (iainfo1, addr);
+  addr = instance_address_create_sockaddr_in (0, 14);
+  instance_address_info_add_address (iainfo1, addr);
+  m = addressmap_create (2);
+  addressmap_add (m, iainfo1);
+  cnt = 0;
+  MSH_assert (MSH_OK == 
+              addressmap_iterate_instance_addresses (m, 1, &iterator_cb, 
NULL));
+  MSH_assert (4 == cnt);
+
+  /* prepare a second addressmap */
+  {
+    AddressMap *m2;
+    struct InstanceAddrInfo *iainfo1;
+    struct InstanceAddrInfo *iainfo2;
+    struct InstanceAddr *addr;
+    struct MSH_MSG_AddressMap *map_msg;
+    
+    iainfo1 = instance_address_info_create (1);
+    addr = instance_address_create_sockaddr_in (0, 2);
+    instance_address_info_add_address (iainfo1, addr);
+    addr = instance_address_create_sockaddr_in (0, 7);
+    instance_address_info_add_address (iainfo1, addr);
+    addr = instance_address_create_sockaddr_in (0, 14);
+    instance_address_info_add_address (iainfo1, addr);
+    iainfo2 = instance_address_info_create (0);
+    addr = instance_address_create_sockaddr_in (0, 3);
+    instance_address_info_add_address (iainfo2, addr);
+    m2 = addressmap_create (2);
+    addressmap_add (m2, iainfo1);
+    addressmap_add (m2, iainfo2);
+    cnt = 0;
+    MSH_assert (MSH_OK == 
+                addressmap_iterate_instance_addresses (m2, 1, &iterator_cb, 
NULL));
+    MSH_assert (3 == cnt);
+    MSH_assert (MSH_OK == addressmap_pack (m2, &map_msg, &iaddr_msgs));
+    cnt = 0;
+    MSH_assert (MSH_OK == 
+                addressmap_iterate_instance_addresses (m2, 0, &iterator_cb, 
NULL));
+    MSH_assert (1 == cnt);
+    addressmap_destroy (m2);
+    instance_address_info_destroy (iainfo1);
+    instance_address_info_destroy (iainfo2);
+    free (map_msg);
+  }
+  /* check intersection of the message with the first addressmap */
+  MSH_assert (3 == addressmap_intersect_msg (m, iaddr_msgs[1]));
+  cnt = 0;
+  MSH_assert (MSH_OK == 
+              addressmap_iterate_instance_addresses (m, 1, &iterator_cb, 
NULL));
+  MSH_assert (3 == cnt);
+  instance_address_info_destroy (iainfo1);
+  addressmap_destroy (m);
+  free (iaddr_msgs[1]);
+  free (iaddr_msgs[0]);
+  free (iaddr_msgs);  
+}
+
+
 int
 main ()
 {
@@ -67,8 +161,29 @@
   MSH_assert (MSH_OK == 
               addressmap_iterate_instance_addresses (m, 0, &iterator_cb, 
NULL));
   MSH_assert (4 == cnt);
-  addressmap_destroy (m);
+  instance_address_info_destroy (iainfo2);
+
+  /* test address map intersections */
+  iainfo2 = instance_address_info_create (0);
+  addr1 = instance_address_create_sockaddr_in (0, 12);
+  instance_address_info_add_address (iainfo2, addr1);
+  addr2 = instance_address_create_sockaddr_in (0, 19);
+  instance_address_info_add_address (iainfo2, addr2);  
+  addr3 = instance_address_create_sockaddr_in (0, 3);
+  instance_address_info_add_address (iainfo2, addr3);
+  addressmap_intersect (m, iainfo2);
+  cnt = 0;
+  MSH_assert (MSH_OK == 
+              addressmap_iterate_instance_addresses (m, 0, &iterator_cb, 
NULL));
+  MSH_assert (2 == cnt);
+  instance_address_info_destroy (iainfo2);
+  
+  /* test message serialization of the addressmap */
+  test_serialization (m);
+  addressmap_destroy (m);  
   instance_address_info_destroy (iainfo);
-  instance_address_info_destroy (iainfo2);
+
+  /* test message deserialization of the addressmap */
+  test_deserialization ();
   return 0;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]