aboutsummaryrefslogtreecommitdiff
path: root/src/set/set_api.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2015-08-30 00:44:11 +0000
committerFlorian Dold <florian.dold@gmail.com>2015-08-30 00:44:11 +0000
commit7936cab9bd741a9ff30362c8495daa29f1874b2e (patch)
tree33606962451dcb4b15dabff20f605a5c58f1cc72 /src/set/set_api.c
parent38963d1e81332032e0ac774f4f2c6b804c38802a (diff)
downloadgnunet-7936cab9bd741a9ff30362c8495daa29f1874b2e.tar.gz
gnunet-7936cab9bd741a9ff30362c8495daa29f1874b2e.zip
work in progress: fix set bug, implement lazy copy
Diffstat (limited to 'src/set/set_api.c')
-rw-r--r--src/set/set_api.c161
1 files changed, 132 insertions, 29 deletions
diff --git a/src/set/set_api.c b/src/set/set_api.c
index 04ae019d0..aadc93678 100644
--- a/src/set/set_api.c
+++ b/src/set/set_api.c
@@ -33,6 +33,17 @@
33 33
34#define LOG(kind,...) GNUNET_log_from (kind, "set-api",__VA_ARGS__) 34#define LOG(kind,...) GNUNET_log_from (kind, "set-api",__VA_ARGS__)
35 35
36struct SetCopyRequest
37{
38 struct SetCopyRequest *next;
39
40 struct SetCopyRequest *prev;
41
42 void *cls;
43
44 GNUNET_SET_CopyReadyCallback cb;
45};
46
36/** 47/**
37 * Opaque handle to a set. 48 * Opaque handle to a set.
38 */ 49 */
@@ -84,6 +95,21 @@ struct GNUNET_SET_Handle
84 * created so far to match replies with iterators. 95 * created so far to match replies with iterators.
85 */ 96 */
86 uint16_t iteration_id; 97 uint16_t iteration_id;
98
99 /**
100 * Configuration, needed when creating (lazy) copies.
101 */
102 const struct GNUNET_CONFIGURATION_Handle *cfg;
103
104 /**
105 * Doubly linked list of copy requests.
106 */
107 struct SetCopyRequest *copy_req_head;
108
109 /**
110 * Doubly linked list of copy requests.
111 */
112 struct SetCopyRequest *copy_req_tail;
87}; 113};
88 114
89 115
@@ -213,6 +239,55 @@ struct GNUNET_SET_ListenHandle
213}; 239};
214 240
215 241
242/* mutual recursion with handle_copy_lazy */
243static struct GNUNET_SET_Handle *
244create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
245 enum GNUNET_SET_OperationType op,
246 uint32_t *cookie);
247
248
249/**
250 * Handle element for iteration over the set. Notifies the
251 * iterator and sends an acknowledgement to the service.
252 *
253 * @param cls the `struct GNUNET_SET_Handle *`
254 * @param mh the message
255 */
256static void
257handle_copy_lazy (void *cls,
258 const struct GNUNET_MessageHeader *mh)
259{
260 struct GNUNET_SET_CopyLazyResponseMessage *msg;
261 struct GNUNET_SET_Handle *set = cls;
262 struct SetCopyRequest *req;
263 struct GNUNET_SET_Handle *new_set;
264
265 msg = (struct GNUNET_SET_CopyLazyResponseMessage *) mh;
266
267 req = set->copy_req_head;
268
269 if (NULL == req)
270 {
271 /* Service sent us unsolicited lazy copy response */
272 GNUNET_break (0);
273 return;
274 }
275
276 GNUNET_CONTAINER_DLL_remove (set->copy_req_head,
277 set->copy_req_tail,
278 req);
279
280
281 // We pass none as operation here, since it doesn't matter when
282 // cloning.
283 new_set = create_internal (set->cfg, GNUNET_SET_OPERATION_NONE, &msg->cookie);
284
285 req->cb (req->cls, new_set);
286
287 GNUNET_free (req);
288}
289
290
216/** 291/**
217 * Handle element for iteration over the set. Notifies the 292 * Handle element for iteration over the set. Notifies the
218 * iterator and sends an acknowledgement to the service. 293 * iterator and sends an acknowledgement to the service.
@@ -455,20 +530,10 @@ handle_client_set_error (void *cls,
455} 530}
456 531
457 532
458/** 533static struct GNUNET_SET_Handle *
459 * Create an empty set, supporting the specified operation. 534create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
460 * 535 enum GNUNET_SET_OperationType op,
461 * @param cfg configuration to use for connecting to the 536 uint32_t *cookie)
462 * set service
463 * @param op operation supported by the set
464 * Note that the operation has to be specified
465 * beforehand, as certain set operations need to maintain
466 * data structures spefific to the operation
467 * @return a handle to the set
468 */
469struct GNUNET_SET_Handle *
470GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
471 enum GNUNET_SET_OperationType op)
472{ 537{
473 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = { 538 static const struct GNUNET_MQ_MessageHandler mq_handlers[] = {
474 { &handle_result, 539 { &handle_result,
@@ -480,17 +545,22 @@ GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
480 { &handle_iter_done, 545 { &handle_iter_done,
481 GNUNET_MESSAGE_TYPE_SET_ITER_DONE, 546 GNUNET_MESSAGE_TYPE_SET_ITER_DONE,
482 sizeof (struct GNUNET_MessageHeader) }, 547 sizeof (struct GNUNET_MessageHeader) },
548 { &handle_copy_lazy,
549 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE,
550 sizeof (struct GNUNET_SET_CopyLazyResponseMessage) },
483 GNUNET_MQ_HANDLERS_END 551 GNUNET_MQ_HANDLERS_END
484 }; 552 };
485 struct GNUNET_SET_Handle *set; 553 struct GNUNET_SET_Handle *set;
486 struct GNUNET_MQ_Envelope *mqm; 554 struct GNUNET_MQ_Envelope *mqm;
487 struct GNUNET_SET_CreateMessage *msg; 555 struct GNUNET_SET_CreateMessage *create_msg;
556 struct GNUNET_SET_CopyLazyConnectMessage *copy_msg;
488 557
489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
490 "Creating new set (operation %u)\n", 559 "Creating new set (operation %u)\n",
491 op); 560 op);
492 set = GNUNET_new (struct GNUNET_SET_Handle); 561 set = GNUNET_new (struct GNUNET_SET_Handle);
493 set->client = GNUNET_CLIENT_connect ("set", cfg); 562 set->client = GNUNET_CLIENT_connect ("set", cfg);
563 set->cfg = cfg;
494 if (NULL == set->client) 564 if (NULL == set->client)
495 { 565 {
496 GNUNET_free (set); 566 GNUNET_free (set);
@@ -501,15 +571,44 @@ GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
501 &handle_client_set_error, 571 &handle_client_set_error,
502 set); 572 set);
503 GNUNET_assert (NULL != set->mq); 573 GNUNET_assert (NULL != set->mq);
504 mqm = GNUNET_MQ_msg (msg, 574
505 GNUNET_MESSAGE_TYPE_SET_CREATE); 575 if (NULL == cookie)
506 msg->operation = htonl (op); 576 {
577 mqm = GNUNET_MQ_msg (create_msg,
578 GNUNET_MESSAGE_TYPE_SET_CREATE);
579 create_msg->operation = htonl (op);
580 }
581 else
582 {
583 mqm = GNUNET_MQ_msg (copy_msg,
584 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT);
585 copy_msg->cookie = *cookie;
586 }
507 GNUNET_MQ_send (set->mq, mqm); 587 GNUNET_MQ_send (set->mq, mqm);
508 return set; 588 return set;
509} 589}
510 590
511 591
512/** 592/**
593 * Create an empty set, supporting the specified operation.
594 *
595 * @param cfg configuration to use for connecting to the
596 * set service
597 * @param op operation supported by the set
598 * Note that the operation has to be specified
599 * beforehand, as certain set operations need to maintain
600 * data structures spefific to the operation
601 * @return a handle to the set
602 */
603struct GNUNET_SET_Handle *
604GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
605 enum GNUNET_SET_OperationType op)
606{
607 return create_internal (cfg, op, NULL);
608}
609
610
611/**
513 * Add an element to the given set. After the element has been added 612 * Add an element to the given set. After the element has been added
514 * (in the sense of being transmitted to the set service), @a cont 613 * (in the sense of being transmitted to the set service), @a cont
515 * will be called. Multiple calls to GNUNET_SET_add_element() can be 614 * will be called. Multiple calls to GNUNET_SET_add_element() can be
@@ -976,19 +1075,23 @@ GNUNET_SET_iterate (struct GNUNET_SET_Handle *set,
976} 1075}
977 1076
978 1077
979/**
980 * Stop iteration over all elements in the given set. Can only
981 * be called before the iteration has "naturally" completed its
982 * turn.
983 *
984 * @param set the set to stop iterating over
985 */
986void 1078void
987GNUNET_SET_iterate_cancel (struct GNUNET_SET_Handle *set) 1079GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
1080 GNUNET_SET_CopyReadyCallback cb,
1081 void *cls)
988{ 1082{
989 GNUNET_assert (NULL != set->iterator); 1083 struct GNUNET_MQ_Envelope *ev;
990 set->iterator = NULL; 1084 struct SetCopyRequest *req;
991 set->iteration_id++; 1085
1086 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE);
1087 GNUNET_MQ_send (set->mq, ev);
1088
1089 req = GNUNET_new (struct SetCopyRequest);
1090 req->cb = cb;
1091 req->cls = cls;
1092 GNUNET_CONTAINER_DLL_insert (set->copy_req_head,
1093 set->copy_req_tail,
1094 req);
992} 1095}
993 1096
994 1097