gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28545 - in gnunet/src: include set util


From: gnunet
Subject: [GNUnet-SVN] r28545 - in gnunet/src: include set util
Date: Mon, 12 Aug 2013 20:00:44 +0200

Author: dold
Date: 2013-08-12 20:00:43 +0200 (Mon, 12 Aug 2013)
New Revision: 28545

Modified:
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/set/gnunet-service-set.c
   gnunet/src/set/gnunet-service-set.h
   gnunet/src/set/gnunet-service-set_union.c
   gnunet/src/set/set.h
   gnunet/src/set/set_api.c
   gnunet/src/set/test_set.conf
   gnunet/src/set/test_set_api.c
   gnunet/src/util/container_multihashmap.c
Log:
- correct iteraion in multihashmap
- iterate over elements with client ack in set


Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2013-08-12 17:45:22 UTC (rev 
28544)
+++ gnunet/src/include/gnunet_protocols.h       2013-08-12 18:00:43 UTC (rev 
28545)
@@ -1690,9 +1690,9 @@
 #define GNUNET_MESSAGE_TYPE_SET_CANCEL 570
 
 /**
- * Acknowledge results
+ * Acknowledge result from iteration
  */
-#define GNUNET_MESSAGE_TYPE_SET_ACK 571
+#define GNUNET_MESSAGE_TYPE_SET_ITER_ACK 571
 
 /**
  * Create an empty set

Modified: gnunet/src/set/gnunet-service-set.c
===================================================================
--- gnunet/src/set/gnunet-service-set.c 2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/gnunet-service-set.c 2013-08-12 18:00:43 UTC (rev 28545)
@@ -261,6 +261,28 @@
 
 
 /**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES if we should continue to
+ *         iterate,
+ *         GNUNET_NO if not.
+ */
+static int
+destroy_elements_iterator (void *cls,
+                           const struct GNUNET_HashCode * key,
+                           void *value)
+{
+  struct ElementEntry *ee = value;
+
+  GNUNET_free (ee);
+  return GNUNET_YES;
+}
+
+
+/**
  * Destroy a set, and free all resources associated with it.
  *
  * @param set the set to destroy
@@ -282,6 +304,18 @@
     GNUNET_MQ_destroy (set->client_mq);
     set->client_mq = NULL;
   }
+  if (NULL != set->elements)
+  {
+    GNUNET_CONTAINER_multihashmap_iterate (set->elements,
+                                           destroy_elements_iterator, NULL);
+    GNUNET_CONTAINER_multihashmap_destroy (set->elements);
+    set->elements = NULL;
+  }
+  if (NULL != set->iter)
+  {
+    GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
+    set->iter = NULL;
+  }
   GNUNET_assert (NULL != set->state);
   set->vt->destroy_set (set->state);
   set->state = NULL;
@@ -455,6 +489,32 @@
 }
 
 
+static void
+send_client_element (struct Set *set)
+{
+  int ret;
+  struct ElementEntry *ee;
+  struct GNUNET_MQ_Envelope *ev;
+
+  GNUNET_assert (NULL != set->iter);
+  ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter, NULL, (const 
void **) &ee);
+  if (GNUNET_NO == ret)
+  {
+    ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
+  }
+  else
+  {
+    struct GNUNET_SET_IterResponseMessage *msg;
+
+    GNUNET_assert (NULL != ee);
+    ev = GNUNET_MQ_msg_extra (msg, ee->element.size, 
GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT);
+    memcpy (&msg[1], ee->element.data, ee->element.size);
+    msg->element_type = ee->element.type;
+  }
+  GNUNET_MQ_send (set->client_mq, ev);
+}
+
+
 /**
  * Called when a client wants to iterate the elements of a set.
  *
@@ -477,8 +537,17 @@
     return;
   }
 
+  if (NULL != set->iter)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "iterating union set with %u 
elements\n",
+              GNUNET_CONTAINER_multihashmap_size (set->elements));
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  set->vt->iterate (set);
+  set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->elements);
+  send_client_element (set);
 }
 
 
@@ -525,6 +594,7 @@
   }
 
   set->state = set->vt->create ();
+  set->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
   set->client = client;
   set->client_mq = GNUNET_MQ_queue_for_server_client (client);
   GNUNET_CONTAINER_DLL_insert (sets_head, sets_tail, set);
@@ -633,6 +703,7 @@
   struct Set *set;
   const struct GNUNET_SET_ElementMessage *msg;
   struct GNUNET_SET_Element el;
+  struct ElementEntry *ee;
 
   set = set_get (client);
   if (NULL == set)
@@ -641,16 +712,55 @@
     GNUNET_SERVER_client_disconnect (client);
     return;
   }
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
   msg = (const struct GNUNET_SET_ElementMessage *) m;
   el.size = ntohs (m->size) - sizeof *msg;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
              "client ins/rem element of size %u\n", el.size);
   el.data = &msg[1];
   if (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (m->type))
-    set->vt->remove (set->state, &el);
+  {
+    struct GNUNET_HashCode hash;
+
+    GNUNET_CRYPTO_hash (el.data, el.size, &hash);
+    ee = GNUNET_CONTAINER_multihashmap_get (set->elements, &hash);
+    if (NULL == ee)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to remove 
non-existing element\n");
+      return;
+    }
+    if (GNUNET_YES == ee->removed)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to remove element 
twice\n");
+      return;
+    }
+    ee->removed = GNUNET_YES;
+    ee->generation_removed = set->current_generation;
+    set->vt->remove (set->state, ee);
+  }
   else
-    set->vt->add (set->state, &el);
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  {
+    struct ElementEntry *ee_dup;
+
+    ee = GNUNET_malloc (el.size + sizeof *ee);
+    ee->element.size = el.size;
+    memcpy (&ee[1], el.data, el.size);
+    ee->element.data = &ee[1];
+    ee->generation_added = set->current_generation;
+    ee->remote = GNUNET_NO;
+    GNUNET_CRYPTO_hash (ee->element.data, el.size, &ee->element_hash);
+    ee_dup = GNUNET_CONTAINER_multihashmap_get (set->elements,
+                                                &ee->element_hash);
+    if (NULL != ee_dup)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "element inserted twice, 
ignoring\n");
+      GNUNET_free (ee);
+      return;
+    }
+    GNUNET_CONTAINER_multihashmap_put (set->elements, &ee->element_hash, ee,
+                                       
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+    set->vt->add (set->state, ee);
+  }
 }
 
 
@@ -712,12 +822,29 @@
  * @param m the message
  */
 static void
-handle_client_ack (void *cls,
+handle_client_iter_ack (void *cls,
                    struct GNUNET_SERVER_Client *client,
                    const struct GNUNET_MessageHeader *m)
 {
-  /* FIXME: implement */
+  struct Set *set;
+  
+  set = set_get (client);
+  if (NULL == set)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+
+  if (NULL == set->iter)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  send_client_element (set);
 }
 
 
@@ -976,7 +1103,7 @@
   static const struct GNUNET_SERVER_MessageHandler server_handlers[] = {
     {handle_client_accept, NULL, GNUNET_MESSAGE_TYPE_SET_ACCEPT,
         sizeof (struct GNUNET_SET_AcceptRejectMessage)},
-    {handle_client_ack, NULL, GNUNET_MESSAGE_TYPE_SET_ACK, 0},
+    {handle_client_iter_ack, NULL, GNUNET_MESSAGE_TYPE_SET_ITER_ACK, 0},
     {handle_client_add_remove, NULL, GNUNET_MESSAGE_TYPE_SET_ADD, 0},
     {handle_client_create, NULL, GNUNET_MESSAGE_TYPE_SET_CREATE,
         sizeof (struct GNUNET_SET_CreateMessage)},

Modified: gnunet/src/set/gnunet-service-set.h
===================================================================
--- gnunet/src/set/gnunet-service-set.h 2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/gnunet-service-set.h 2013-08-12 18:00:43 UTC (rev 28545)
@@ -57,6 +57,7 @@
 /* forward declarations */
 struct Set;
 struct TunnelContext;
+struct ElementEntry;
 
 
 /**
@@ -103,6 +104,8 @@
 };
 
 
+
+
 /**
  * Signature of functions that create the implementation-specific
  * state for a set supporting a specific operation.
@@ -119,7 +122,7 @@
  * @param set implementation-specific set state
  * @param msg element message from the client
  */
-typedef void (*AddRemoveImpl) (struct SetState *state, const struct 
GNUNET_SET_Element *element);
+typedef void (*AddRemoveImpl) (struct SetState *state, struct ElementEntry 
*ee);
 
 
 /**
@@ -240,6 +243,54 @@
 
 
 /**
+ * Information about an element element in the set.
+ * All elements are stored in a hash-table
+ * from their hash-code to their 'struct Element',
+ * so that the remove and add operations are reasonably
+ * fast.
+ */
+struct ElementEntry
+{
+  /**
+   * The actual element. The data for the element
+   * should be allocated at the end of this struct.
+   */
+  struct GNUNET_SET_Element element;
+
+  /**
+   * Hash of the element.
+   * Will be used to derive the different IBF keys
+   * for different salts.
+   */
+  struct GNUNET_HashCode element_hash;
+
+  /**
+   * Generation the element was added by the client.
+   * Operations of earlier generations will not consider the element.
+   */
+  unsigned int generation_added;
+
+  /**
+   * GNUNET_YES if the element has been removed in some generation.
+   */
+  int removed;
+
+  /**
+   * Generation the element was removed by the client. 
+   * Operations of later generations will not consider the element.
+   * Only valid if is_removed is GNUNET_YES.
+   */
+  unsigned int generation_removed;
+
+  /**
+   * GNUNET_YES if the element is a remote element, and does not belong
+   * to the operation's set.
+   */
+  int remote;
+};
+
+
+/**
  * A set that supports a specific operation
  * with other peers.
  */
@@ -281,6 +332,23 @@
    * Implementation-specific state.
    */
   struct SetState *state;
+
+  /**
+   * Current state of iterating elements for the client.
+   * NULL if we are not currently iterating.
+   */
+  struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
+
+  /**
+   * Maps 'struct GNUNET_HashCode' to 'struct ElementEntry'.
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *elements;
+
+  /**
+   * Current generation, that is, number of
+   * previously executed operations on this set
+   */
+  unsigned int current_generation;
 };
 
 

Modified: gnunet/src/set/gnunet-service-set_union.c
===================================================================
--- gnunet/src/set/gnunet-service-set_union.c   2013-08-12 17:45:22 UTC (rev 
28544)
+++ gnunet/src/set/gnunet-service-set_union.c   2013-08-12 18:00:43 UTC (rev 
28545)
@@ -167,7 +167,7 @@
    * Set state of the set that this operation
    * belongs to.
    */
-  struct SetState *set_state;
+  struct Set *set;
   
   /**
    * Evaluate operations are held in
@@ -184,54 +184,6 @@
 
 
 /**
- * Information about an element element in the set.
- * All elements are stored in a hash-table
- * from their hash-code to their 'struct Element',
- * so that the remove and add operations are reasonably
- * fast.
- */
-struct ElementEntry
-{
-  /**
-   * The actual element. The data for the element
-   * should be allocated at the end of this struct.
-   */
-  struct GNUNET_SET_Element element;
-
-  /**
-   * Hash of the element.
-   * Will be used to derive the different IBF keys
-   * for different salts.
-   */
-  struct GNUNET_HashCode element_hash;
-
-  /**
-   * Generation the element was added by the client.
-   * Operations of earlier generations will not consider the element.
-   */
-  unsigned int generation_added;
-
-  /**
-   * GNUNET_YES if the element has been removed in some generation.
-   */
-  int removed;
-
-  /**
-   * Generation the element was removed by the client. 
-   * Operations of later generations will not consider the element.
-   * Only valid if is_removed is GNUNET_YES.
-   */
-  unsigned int generation_removed;
-
-  /**
-   * GNUNET_YES if the element is a remote element, and does not belong
-   * to the operation's set.
-   */
-  int remote;
-};
-
-
-/**
  * The key entry is used to associate an ibf key with
  * an element.
  */
@@ -289,11 +241,6 @@
   struct StrataEstimator *se;
 
   /**
-   * Maps 'struct GNUNET_HashCode' to 'struct ElementEntry'.
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *elements;
-
-  /**
    * Evaluate operations are held in
    * a linked list.
    */
@@ -304,16 +251,9 @@
    * a linked list.
    */
   struct OperationState *ops_tail;
-
-  /**
-   * Current generation, that is, number of
-   * previously executed operations on this set
-   */
-  unsigned int current_generation;
 };
 
 
-
 /**
  * Iterator over hash map entries.
  *
@@ -325,28 +265,6 @@
  *         GNUNET_NO if not.
  */
 static int
-destroy_elements_iterator (void *cls,
-                           const struct GNUNET_HashCode * key,
-                           void *value)
-{
-  struct ElementEntry *ee = value;
-
-  GNUNET_free (ee);
-  return GNUNET_YES;
-}
-
-
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- *         iterate,
- *         GNUNET_NO if not.
- */
-static int
 destroy_key_to_element_iter (void *cls,
                              uint32_t key,
                              void *value)
@@ -378,8 +296,8 @@
 union_operation_destroy (struct OperationState *eo)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying union op\n");
-  GNUNET_CONTAINER_DLL_remove (eo->set_state->ops_head,
-                               eo->set_state->ops_tail,
+  GNUNET_CONTAINER_DLL_remove (eo->set->state->ops_head,
+                               eo->set->state->ops_tail,
                                eo);
   if (NULL != eo->mq)
   {
@@ -647,9 +565,9 @@
   if (NULL == eo->key_to_element)
   {
     unsigned int len;
-    len = GNUNET_CONTAINER_multihashmap_size (eo->set_state->elements);
+    len = GNUNET_CONTAINER_multihashmap_size (eo->set->elements);
     eo->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1);
-    GNUNET_CONTAINER_multihashmap_iterate (eo->set_state->elements,
+    GNUNET_CONTAINER_multihashmap_iterate (eo->set->elements,
                                            init_key_to_element_iterator, eo);
   }
   if (NULL != eo->local_ibf)
@@ -720,7 +638,7 @@
   ev = GNUNET_MQ_msg_header_extra (strata_msg,
                                    SE_STRATA_COUNT * IBF_BUCKET_SIZE * 
SE_IBF_SIZE,
                                    GNUNET_MESSAGE_TYPE_SET_P2P_SE);
-  strata_estimator_write (eo->set_state->se, &strata_msg[1]);
+  strata_estimator_write (eo->set->state->se, &strata_msg[1]);
   GNUNET_MQ_send (eo->mq, ev);
   eo->phase = PHASE_EXPECT_IBF;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent SE, expecting IBF\n");
@@ -1218,7 +1136,7 @@
   tc->vt = _GSS_union_vt ();
   tc->op = eo;
   eo->se = strata_estimator_dup (spec->set->state->se);
-  eo->set_state = spec->set->state;
+  eo->set = spec->set;
   eo->spec = spec;
   eo->tunnel = tunnel;
   eo->mq = GNUNET_MESH_mq_create (tunnel);
@@ -1230,8 +1148,8 @@
   /* we started the operation, thus we have to send the operation request */
   eo->phase = PHASE_EXPECT_SE;
 
-  GNUNET_CONTAINER_DLL_insert (eo->set_state->ops_head,
-                               eo->set_state->ops_tail,
+  GNUNET_CONTAINER_DLL_insert (eo->set->state->ops_head,
+                               eo->set->state->ops_tail,
                                eo);
 
   send_operation_request (eo);
@@ -1259,15 +1177,15 @@
   eo = GNUNET_new (struct OperationState);
   tc->vt = _GSS_union_vt ();
   tc->op = eo;
-  eo->set_state = spec->set->state;
-  eo->generation_created = eo->set_state->current_generation++;
+  eo->set = spec->set;
+  eo->generation_created = eo->set->current_generation++;
   eo->spec = spec;
   eo->tunnel = tunnel;
   eo->mq = GNUNET_MESH_mq_create (tunnel);
-  eo->se = strata_estimator_dup (eo->set_state->se);
+  eo->se = strata_estimator_dup (eo->set->state->se);
   /* transfer ownership of mq and socket from incoming to eo */
-  GNUNET_CONTAINER_DLL_insert (eo->set_state->ops_head,
-                               eo->set_state->ops_tail,
+  GNUNET_CONTAINER_DLL_insert (eo->set->state->ops_head,
+                               eo->set->state->ops_tail,
                                eo);
   /* kick off the operation */
   send_strata_estimator (eo);
@@ -1287,9 +1205,6 @@
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "union set created\n");
   
   set_state = GNUNET_new (struct SetState);
-  /* keys of the hash map are stored in the element entrys, thus we do not
-   * want the hash map to copy them */
-  set_state->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
   set_state->se = strata_estimator_create (SE_STRATA_COUNT,
                                               SE_IBF_SIZE, SE_IBF_HASH_NUM);  
   return set_state;
@@ -1303,30 +1218,8 @@
  * @param element the element to add to the set
  */
 static void
-union_add (struct SetState *set_state, const struct GNUNET_SET_Element 
*element)
+union_add (struct SetState *set_state, struct ElementEntry *ee)
 {
-  struct ElementEntry *ee;
-  struct ElementEntry *ee_dup;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding union element of size %u\n", 
element->size);
-
-  ee = GNUNET_malloc (element->size + sizeof *ee);
-  ee->element.size = element->size;
-  memcpy (&ee[1], element->data, element->size);
-  ee->element.data = &ee[1];
-  ee->generation_added = set_state->current_generation;
-  ee->remote = GNUNET_NO;
-  GNUNET_CRYPTO_hash (ee->element.data, element->size, &ee->element_hash);
-  ee_dup = GNUNET_CONTAINER_multihashmap_get (set_state->elements,
-                                              &ee->element_hash);
-  if (NULL != ee_dup)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "element inserted twice, ignoring\n");
-    GNUNET_free (ee);
-    return;
-  }
-  GNUNET_CONTAINER_multihashmap_put (set_state->elements, &ee->element_hash, 
ee,
-                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
   strata_estimator_insert (set_state->se, get_ibf_key (&ee->element_hash, 0));
 }
 
@@ -1348,17 +1241,10 @@
     strata_estimator_destroy (set_state->se);
     set_state->se = NULL;
   }
-  if (NULL != set_state->elements)
-  {
-    GNUNET_CONTAINER_multihashmap_iterate (set_state->elements,
-                                           destroy_elements_iterator, NULL);
-    GNUNET_CONTAINER_multihashmap_destroy (set_state->elements);
-    set_state->elements = NULL;
-  }
-
   GNUNET_free (set_state);
 }
 
+
 /**
  * Remove the element given in the element message from the set.
  * Only marks the element as removed, so that older set operations can still 
exchange it.
@@ -1367,25 +1253,9 @@
  * @param element set element to remove
  */
 static void
-union_remove (struct SetState *set_state, const struct GNUNET_SET_Element 
*element)
+union_remove (struct SetState *set_state, struct ElementEntry *element)
 {
-  struct GNUNET_HashCode hash;
-  struct ElementEntry *ee;
-
-  GNUNET_CRYPTO_hash (element->data, element->size, &hash);
-  ee = GNUNET_CONTAINER_multihashmap_get (set_state->elements, &hash);
-  if (NULL == ee)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to remove 
non-existing element\n");
-    return;
-  }
-  if (GNUNET_YES == ee->removed)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "client tried to remove element 
twice\n");
-    return;
-  }
-  ee->removed = GNUNET_YES;
-  ee->generation_removed = set_state->current_generation;
+  /* FIXME: remove from strata estimator */
 }
 
 
@@ -1466,55 +1336,6 @@
 }
 
 
-/**
- * Iterator over hash map entries.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- *         iterate,
- *         GNUNET_NO if not.
- */
-static int
-send_iter_element_iter (void *cls,
-                        const struct GNUNET_HashCode *key,
-                        void *value)
-{
-  struct ElementEntry *ee = value;
-  struct Set *set = cls;
-  struct GNUNET_SET_IterResponseMessage *m;
-  struct GNUNET_MQ_Envelope *ev;
-
-  ev = GNUNET_MQ_msg_extra (m, ee->element.size,
-                            GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT);
-
-  m->element_type = ee->element.type;
-  memcpy (&m[1], ee->element.data, ee->element.size);
-  GNUNET_MQ_send (set->client_mq, ev);
-
-  return GNUNET_YES;
-}
-
-
-/**
- * Send all elements of the union set to the client.
- *
- * @param set set to iterate over
- */
-static void
-union_iterate (struct Set *set)
-{
-  struct GNUNET_MQ_Envelope *ev;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "iterating union set with %u 
elements\n",
-              GNUNET_CONTAINER_multihashmap_size (set->state->elements));
-  GNUNET_CONTAINER_multihashmap_iterate (set->state->elements, 
send_iter_element_iter, set);
-  ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
-  GNUNET_MQ_send (set->client_mq, ev);
-}
-
-
 const struct SetVT *
 _GSS_union_vt ()
 {
@@ -1528,7 +1349,6 @@
     .accept = &union_accept,
     .peer_disconnect = &union_peer_disconnect,
     .cancel = &union_op_cancel,
-    .iterate = &union_iterate
   };
 
   return &union_vt;

Modified: gnunet/src/set/set.h
===================================================================
--- gnunet/src/set/set.h        2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/set.h        2013-08-12 18:00:43 UTC (rev 28545)
@@ -227,6 +227,19 @@
   /* rest: element */
 };
 
+struct GNUNET_SET_IterAckMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_ITER_ACK
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Non-zero if the service should continue sending elements.
+   */
+  uint32_t send_more;
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 #endif

Modified: gnunet/src/set/set_api.c
===================================================================
--- gnunet/src/set/set_api.c    2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/set_api.c    2013-08-12 18:00:43 UTC (rev 28545)
@@ -222,6 +222,8 @@
   struct GNUNET_SET_Element element;
   const struct GNUNET_SET_IterResponseMessage *msg =
     (const struct GNUNET_SET_IterResponseMessage *) mh;
+  struct GNUNET_SET_IterAckMessage *ack_msg;
+  struct GNUNET_MQ_Envelope *ev;
 
   if (NULL == set->iterator)
     return;
@@ -230,6 +232,9 @@
   element.type = htons (msg->element_type);
   element.data = &msg[1];
   set->iterator (set->iterator_cls, &element);
+  ev = GNUNET_MQ_msg (ack_msg, GNUNET_MESSAGE_TYPE_SET_ITER_ACK);
+  ack_msg->send_more = htonl (1);
+  GNUNET_MQ_send (set->mq, ev);
 }
 
 

Modified: gnunet/src/set/test_set.conf
===================================================================
--- gnunet/src/set/test_set.conf        2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/test_set.conf        2013-08-12 18:00:43 UTC (rev 28545)
@@ -8,7 +8,7 @@
 HOSTNAME = localhost
 HOME = $SERVICEHOME
 BINARY = gnunet-service-set
-#PREFIX = valgrind --leak-check=full
+PREFIX = valgrind
 #PREFIX = gdbserver :1234
 ACCEPT_FROM = 127.0.0.1;
 ACCEPT_FROM6 = ::1;

Modified: gnunet/src/set/test_set_api.c
===================================================================
--- gnunet/src/set/test_set_api.c       2013-08-12 17:45:22 UTC (rev 28544)
+++ gnunet/src/set/test_set_api.c       2013-08-12 18:00:43 UTC (rev 28545)
@@ -36,7 +36,7 @@
 static struct GNUNET_SET_ListenHandle *listen_handle;
 const static struct GNUNET_CONFIGURATION_Handle *config;
 
-int num_done;
+static int iter_count;
 
 
 static void
@@ -144,6 +144,9 @@
   GNUNET_SET_add_element (set2, &element, NULL, NULL);
   element.data = "quux";
   element.size = strlen(element.data);
+  GNUNET_SET_add_element (set2, &element, NULL, NULL);
+  element.data = "baz";
+  element.size = strlen(element.data);
   GNUNET_SET_add_element (set2, &element, start, NULL);
 }
 
@@ -167,6 +170,44 @@
 }
 
 
+static int
+iter_cb (void *cls,
+         const struct GNUNET_SET_Element *element)
+{
+  if (NULL == element)
+  {
+    GNUNET_assert (iter_count == 3);
+    GNUNET_SET_destroy (cls);
+    return GNUNET_YES;
+  }
+  printf ("iter: got element\n");
+  iter_count++;
+  return GNUNET_YES;
+}
+
+
+static void
+test_iter ()
+{
+  struct GNUNET_SET_Element element;
+  struct GNUNET_SET_Handle *iter_set;
+
+  iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
+
+  element.data = "hello";
+  element.size = strlen(element.data);
+  GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
+  element.data = "bar";
+  element.size = strlen(element.data);
+  GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
+  element.data = "quux";
+  element.size = strlen(element.data);
+  GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
+
+  GNUNET_SET_iterate (iter_set, iter_cb, iter_set);
+}
+
+
 /**
  * Signature of the 'main' function for a (single-peer) testcase that
  * is run using 'GNUNET_TESTING_peer_run'.
@@ -188,6 +229,10 @@
   printf ("my id (from CRYPTO): %s\n", GNUNET_h2s (&local_id.hashPubKey));
   GNUNET_TESTING_peer_get_identity (peer, &local_id);
   printf ("my id (from TESTING): %s\n", GNUNET_h2s (&local_id.hashPubKey));
+
+  test_iter ();
+
+  return;
   set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
   set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id);

Modified: gnunet/src/util/container_multihashmap.c
===================================================================
--- gnunet/src/util/container_multihashmap.c    2013-08-12 17:45:22 UTC (rev 
28544)
+++ gnunet/src/util/container_multihashmap.c    2013-08-12 18:00:43 UTC (rev 
28545)
@@ -872,7 +872,9 @@
         return GNUNET_YES;
       }
     }
-    iter->idx++;
+    iter->idx += 1;
+    if (iter->idx < iter->map->map_length)
+      iter->me = iter->map->map[iter->idx];
   }
 }
 




reply via email to

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