+static void
+execute_add (struct Set *set,
+ const struct GNUNET_MessageHeader *m)
+{
+ const struct GNUNET_SET_ElementMessage *msg;
+ struct GNUNET_SET_Element el;
+ struct ElementEntry *ee;
+ struct GNUNET_HashCode hash;
+
+ GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_ADD == ntohs (m->type));
+
+ msg = (const struct GNUNET_SET_ElementMessage *) m;
+ el.size = ntohs (m->size) - sizeof *msg;
+ el.data = &msg[1];
+ el.element_type = ntohs (msg->element_type);
+ GNUNET_SET_element_hash (&el, &hash);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client inserts element %s of size %u\n",
+ GNUNET_h2s (&hash),
+ el.size);
+
+ ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
+ &hash);
+
+ if (NULL == ee)
+ {
+ 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->element.element_type = el.element_type;
+ ee->remote = GNUNET_NO;
+ ee->mutations = NULL;
+ ee->mutations_size = 0;
+ ee->element_hash = hash;
+ GNUNET_break (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_put (set->content->elements,
+ &ee->element_hash,
+ ee,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ }
+ else if (GNUNET_YES == _GSS_is_element_of_set (ee, set))
+ {
+ /* same element inserted twice */
+ return;
+ }
+
+ {
+ struct MutationEvent mut = {
+ .generation = set->current_generation,
+ .added = GNUNET_YES
+ };
+ GNUNET_array_append (ee->mutations, ee->mutations_size, mut);
+ }
+
+ set->vt->add (set->state, ee);
+}
+
+
+static void
+execute_remove (struct Set *set,
+ const struct GNUNET_MessageHeader *m)
+{
+ const struct GNUNET_SET_ElementMessage *msg;
+ struct GNUNET_SET_Element el;
+ struct ElementEntry *ee;
+ struct GNUNET_HashCode hash;
+
+ GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (m->type));
+
+ msg = (const struct GNUNET_SET_ElementMessage *) m;
+ el.size = ntohs (m->size) - sizeof *msg;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client removes element of size %u\n",
+ el.size);
+ el.data = &msg[1];
+ el.element_type = ntohs (msg->element_type);
+ GNUNET_SET_element_hash (&el, &hash);
+ ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
+ &hash);
+ if (NULL == ee)
+ {
+ /* Client tried to remove non-existing element. */
+ return;
+ }
+ if (GNUNET_NO == _GSS_is_element_of_set (ee, set))
+ {
+ /* Client tried to remove element twice */
+ return;
+ }
+ else
+ {
+ struct MutationEvent mut = {
+ .generation = set->current_generation,
+ .added = GNUNET_NO
+ };
+ GNUNET_array_append (ee->mutations, ee->mutations_size, mut);
+ }
+ set->vt->remove (set->state, ee);
+}
+
+
+
+static void
+execute_mutation (struct Set *set,
+ const struct GNUNET_MessageHeader *m)
+{
+ switch (ntohs (m->type))
+ {
+ case GNUNET_MESSAGE_TYPE_SET_ADD:
+ execute_add (set, m);
+ break;
+ case GNUNET_MESSAGE_TYPE_SET_REMOVE:
+ execute_remove (set, m);
+ break;
+ default:
+ GNUNET_break (0);
+ }
+}
+
+
+