+/**
+ * Initialize this neighbors 'my_set' and when done give
+ * it to the pending set operation for execution.
+ *
+ * Add a single element to the set per call:
+ *
+ * If we reached the last element of a consensus element: increase distance
+ *
+ *
+ * @param cls the neighbor for which we are building the set
+ */
+static void
+build_set (void *cls)
+{
+ struct DirectNeighbor *neighbor = cls;
+ struct GNUNET_SET_Element element;
+ struct Target *target;
+ target = NULL;
+ while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) &&
+ (consensi[neighbor->consensus_insertion_distance].array_length == neighbor->consensus_insertion_offset) )
+ {
+ /* If we reached the last element of a consensus array element: increase distance and start with next array */
+ neighbor->consensus_insertion_offset = 0;
+ neighbor->consensus_insertion_distance++;
+ /* skip over NULL entries */
+ while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) &&
+ (consensi[neighbor->consensus_insertion_distance].array_length > neighbor->consensus_insertion_offset) &&
+ (NULL == consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]) )
+ neighbor->consensus_insertion_offset++;
+ }
+ if (DEFAULT_FISHEYE_DEPTH - 1 == neighbor->consensus_insertion_distance)
+ {
+ /* we have added all elements to the set, run the operation */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished building my SET for peer `%s' with %u elements, committing\n",
+ GNUNET_i2s(&neighbor->peer),
+ neighbor->consensus_elements);
+ GNUNET_SET_commit (neighbor->set_op,
+ neighbor->my_set);
+ GNUNET_SET_destroy (neighbor->my_set);
+ neighbor->my_set = NULL;
+ return;
+ }
+
+ target = &consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]->target;
+ element.size = sizeof (struct Target);
+ element.type = htons (0); /* do we need this? */
+ element.data = target;
+
+ /* Find next non-NULL entry */
+ neighbor->consensus_insertion_offset++;
+ /* skip over NULL entries */
+ while ( (DEFAULT_FISHEYE_DEPTH - 1 > neighbor->consensus_insertion_distance) &&
+ (consensi[neighbor->consensus_insertion_distance].array_length > neighbor->consensus_insertion_offset) &&
+ (NULL == consensi[neighbor->consensus_insertion_distance].targets[neighbor->consensus_insertion_offset]) )
+ {
+ neighbor->consensus_insertion_offset++;
+ }
+
+ if ( (0 != memcmp(&target->peer, &my_identity, sizeof (my_identity))) &&
+ (0 != memcmp(&target->peer, &neighbor->peer, sizeof (neighbor->peer))) )
+ {
+ /* Add target if it is not the neighbor or this peer */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding peer `%s' with distance %u to SET\n",
+ GNUNET_i2s (&target->peer),
+ ntohl (target->distance));
+ GNUNET_SET_add_element (neighbor->my_set,
+ &element,
+ &build_set, neighbor);
+ neighbor->consensus_elements++;
+ }
+ else
+ build_set(neighbor);
+}
+
+