gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28278 - gnunet/src/set


From: gnunet
Subject: [GNUnet-SVN] r28278 - gnunet/src/set
Date: Tue, 23 Jul 2013 19:26:35 +0200

Author: dold
Date: 2013-07-23 19:26:35 +0200 (Tue, 23 Jul 2013)
New Revision: 28278

Modified:
   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
Log:
- set iteration


Modified: gnunet/src/set/gnunet-service-set.c
===================================================================
--- gnunet/src/set/gnunet-service-set.c 2013-07-23 16:24:01 UTC (rev 28277)
+++ gnunet/src/set/gnunet-service-set.c 2013-07-23 17:26:35 UTC (rev 28278)
@@ -455,6 +455,32 @@
 
 
 /**
+ * Called when a client wants to iterate the elements of a set.
+ *
+ * @param cls unused
+ * @param client client that sent the message
+ * @param m message sent by the client
+ */
+static void
+handle_client_iterate (void *cls,
+                       struct GNUNET_SERVER_Client *client,
+                       const struct GNUNET_MessageHeader *m)
+{
+  struct Set *set;
+  
+  set = set_get (client);
+  if (NULL == set)
+  {
+    GNUNET_break (0);
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+
+  set->vt->iterate (set);
+}
+
+
+/**
  * Called when a client wants to create a new set.
  *
  * @param cls unused
@@ -939,6 +965,8 @@
     {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)},
+    {handle_client_iterate, NULL, GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST,
+        sizeof (struct GNUNET_MessageHeader)},
     {handle_client_evaluate, NULL, GNUNET_MESSAGE_TYPE_SET_EVALUATE, 0},
     {handle_client_listen, NULL, GNUNET_MESSAGE_TYPE_SET_LISTEN,
         sizeof (struct GNUNET_SET_ListenMessage)},

Modified: gnunet/src/set/gnunet-service-set.h
===================================================================
--- gnunet/src/set/gnunet-service-set.h 2013-07-23 16:24:01 UTC (rev 28277)
+++ gnunet/src/set/gnunet-service-set.h 2013-07-23 17:26:35 UTC (rev 28278)
@@ -170,6 +170,15 @@
 
 
 /**
+ * Signature of functions that implement sending all the set's
+ * elements to the client.
+ *
+ * @param set set that should be iterated over
+ */
+typedef void (*IterateImpl) (struct Set *set);
+
+
+/**
  * Dispatch table for a specific set operation.
  * Every set operation has to implement the callback
  * in this struct.
@@ -222,6 +231,11 @@
    * its ID.
    */
   CancelImpl cancel;
+
+  /**
+   * Callback for iterating over all set elements.
+   */
+  IterateImpl iterate;
 };
 
 

Modified: gnunet/src/set/gnunet-service-set_union.c
===================================================================
--- gnunet/src/set/gnunet-service-set_union.c   2013-07-23 16:24:01 UTC (rev 
28277)
+++ gnunet/src/set/gnunet-service-set_union.c   2013-07-23 17:26:35 UTC (rev 
28278)
@@ -1421,6 +1421,53 @@
 }
 
 
+/**
+ * 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_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 ()
 {
@@ -1433,7 +1480,8 @@
     .evaluate = &union_evaluate,
     .accept = &union_accept,
     .peer_disconnect = &union_peer_disconnect,
-    .cancel = &union_op_cancel
+    .cancel = &union_op_cancel,
+    .iterate = &union_iterate
   };
 
   return &union_vt;

Modified: gnunet/src/set/set.h
===================================================================
--- gnunet/src/set/set.h        2013-07-23 16:24:01 UTC (rev 28277)
+++ gnunet/src/set/set.h        2013-07-23 17:26:35 UTC (rev 28278)
@@ -211,7 +211,22 @@
   uint32_t request_id GNUNET_PACKED;
 };
 
+struct GNUNET_SET_IterResponseMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_ITER_RESPONSE
+   */
+  struct GNUNET_MessageHeader header;
 
+  /**
+   * Type of the element attachted to the message,
+   * if any.
+   */
+  uint16_t element_type GNUNET_PACKED;
+
+  /* rest: element */
+};
+
 GNUNET_NETWORK_STRUCT_END
 
 #endif

Modified: gnunet/src/set/set_api.c
===================================================================
--- gnunet/src/set/set_api.c    2013-07-23 16:24:01 UTC (rev 28277)
+++ gnunet/src/set/set_api.c    2013-07-23 17:26:35 UTC (rev 28278)
@@ -67,6 +67,17 @@
    * Has the set become invalid (e.g. service died)?
    */
   int invalid;
+
+  /**
+   * Callback for the current iteration over the set,
+   * NULL if no iterator is active.
+   */
+  GNUNET_SET_ElementIterator iterator;
+
+  /**
+   * Closure for 'iterator'
+   */
+  void *iterator_cls;
 };
 
 
@@ -171,6 +182,47 @@
 
 
 /**
+ * Handle element for iteration over the set.
+ *
+ * @param cls the set
+ * @param mh the message
+ */
+static void
+handle_iter_element (void *cls, const struct GNUNET_MessageHeader *mh)
+{
+  struct GNUNET_SET_Handle *set = cls;
+  struct GNUNET_SET_Element element;
+  const struct GNUNET_SET_IterResponseMessage *msg =
+    (const struct GNUNET_SET_IterResponseMessage *) mh;
+
+  if (NULL == set->iterator)
+    return;
+
+  element.type = htons (mh->type);
+  element.data = &msg[1];
+  set->iterator (set->iterator_cls, &element);
+}
+
+
+/**
+ * Handle element for iteration over the set.
+ *
+ * @param cls the set
+ * @param mh the message
+ */
+static void
+handle_iter_done (void *cls, const struct GNUNET_MessageHeader *mh)
+{
+  struct GNUNET_SET_Handle *set = cls;
+
+  if (NULL == set->iterator)
+    return;
+
+  set->iterator (set->iterator_cls, NULL);
+}
+
+
+/**
  * Handle result message for a set operation.
  *
  * @param cls the set
@@ -302,6 +354,8 @@
   struct GNUNET_SET_CreateMessage *msg;
   static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
     {handle_result, GNUNET_MESSAGE_TYPE_SET_RESULT, 0},
+    {handle_iter_element, GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT, 0},
+    {handle_iter_done, GNUNET_MESSAGE_TYPE_SET_ITER_DONE, 0},
     GNUNET_MQ_HANDLERS_END
   };
 
@@ -623,3 +677,36 @@
   return GNUNET_OK;
 }
 
+
+
+/**
+ * Iterate over all elements in the given set.
+ * Note that this operation involves transferring every element of the set
+ * from the service to the client, and is thus costly.
+ *
+ * @param set the set to iterate over
+ * @param iter the iterator to call for each element
+ * @param cls closure for 'iter'
+ * @return GNUNET_YES if the iteration started successfuly,
+ *         GNUNET_NO if another iteration is active
+ *         GNUNET_SYSERR if the set is invalid (e.g. the server crashed, 
disconnected)
+ */
+int
+GNUNET_SET_iterate (struct GNUNET_SET_Handle *set, GNUNET_SET_ElementIterator 
iter, void *cls)
+{
+  struct GNUNET_MQ_Envelope *ev;
+
+  GNUNET_assert (NULL != iter);
+
+  if (GNUNET_YES == set->invalid)
+    return GNUNET_SYSERR;
+  if (NULL != set->iterator)
+    return GNUNET_NO;
+
+  set->iterator = iter;
+  set->iterator_cls = cls;
+  ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_REQUEST);
+  GNUNET_MQ_send (set->mq, ev);
+  return GNUNET_YES;
+}
+




reply via email to

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