diff options
Diffstat (limited to 'src/rps/rps-sampler_common.c')
-rw-r--r-- | src/rps/rps-sampler_common.c | 187 |
1 files changed, 183 insertions, 4 deletions
diff --git a/src/rps/rps-sampler_common.c b/src/rps/rps-sampler_common.c index f54de9014..adb69e1b5 100644 --- a/src/rps/rps-sampler_common.c +++ b/src/rps/rps-sampler_common.c | |||
@@ -116,6 +116,45 @@ struct RPS_SamplerRequestHandle | |||
116 | 116 | ||
117 | 117 | ||
118 | /** | 118 | /** |
119 | * Closure to _get_rand_peer_info() | ||
120 | */ | ||
121 | struct RPS_SamplerRequestHandleSingleInfo | ||
122 | { | ||
123 | /** | ||
124 | * DLL | ||
125 | */ | ||
126 | struct RPS_SamplerRequestHandleSingleInfo *next; | ||
127 | struct RPS_SamplerRequestHandleSingleInfo *prev; | ||
128 | |||
129 | /** | ||
130 | * Pointer to the id | ||
131 | */ | ||
132 | struct GNUNET_PeerIdentity *id; | ||
133 | |||
134 | /** | ||
135 | * Head and tail for the DLL to store the tasks for single requests | ||
136 | */ | ||
137 | struct GetPeerCls *gpc_head; | ||
138 | struct GetPeerCls *gpc_tail; | ||
139 | |||
140 | /** | ||
141 | * Sampler. | ||
142 | */ | ||
143 | struct RPS_Sampler *sampler; | ||
144 | |||
145 | /** | ||
146 | * Callback to be called when all ids are available. | ||
147 | */ | ||
148 | RPS_sampler_sinlge_info_ready_cb callback; | ||
149 | |||
150 | /** | ||
151 | * Closure given to the callback | ||
152 | */ | ||
153 | void *cls; | ||
154 | }; | ||
155 | |||
156 | |||
157 | /** | ||
119 | * @brief Update the current estimate of the network size stored at the sampler | 158 | * @brief Update the current estimate of the network size stored at the sampler |
120 | * | 159 | * |
121 | * Used for computing the condition when to return elements to the client | 160 | * Used for computing the condition when to return elements to the client |
@@ -415,12 +454,20 @@ sampler_empty (struct RPS_Sampler *sampler) | |||
415 | /** | 454 | /** |
416 | * Callback to _get_rand_peer() used by _get_n_rand_peers(). | 455 | * Callback to _get_rand_peer() used by _get_n_rand_peers(). |
417 | * | 456 | * |
457 | * Implements #RPS_sampler_rand_peer_ready_cont | ||
458 | * | ||
418 | * Checks whether all n peers are available. If they are, | 459 | * Checks whether all n peers are available. If they are, |
419 | * give those back. | 460 | * give those back. |
461 | * @param cls Closure | ||
462 | * @param id Peer ID | ||
463 | * @param probability The probability with which this sampler has seen all ids | ||
464 | * @param num_observed How many ids this sampler has observed | ||
420 | */ | 465 | */ |
421 | static void | 466 | static void |
422 | check_n_peers_ready (void *cls, | 467 | check_n_peers_ready (void *cls, |
423 | const struct GNUNET_PeerIdentity *id) | 468 | const struct GNUNET_PeerIdentity *id, |
469 | double probability, | ||
470 | uint32_t num_observed) | ||
424 | { | 471 | { |
425 | struct RPS_SamplerRequestHandle *req_handle = cls; | 472 | struct RPS_SamplerRequestHandle *req_handle = cls; |
426 | (void) id; | 473 | (void) id; |
@@ -428,6 +475,8 @@ check_n_peers_ready (void *cls, | |||
428 | struct GNUNET_PeerIdentity *peers; | 475 | struct GNUNET_PeerIdentity *peers; |
429 | uint32_t num_peers; | 476 | uint32_t num_peers; |
430 | void *cb_cls; | 477 | void *cb_cls; |
478 | (void) probability; | ||
479 | (void) num_observed; | ||
431 | 480 | ||
432 | req_handle->cur_num_peers++; | 481 | req_handle->cur_num_peers++; |
433 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 482 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -460,6 +509,53 @@ check_n_peers_ready (void *cls, | |||
460 | 509 | ||
461 | 510 | ||
462 | /** | 511 | /** |
512 | * Callback to _get_rand_peer() used by _get_rand_peer_info(). | ||
513 | * | ||
514 | * Implements #RPS_sampler_rand_peer_ready_cont | ||
515 | * | ||
516 | * @param cls Closure | ||
517 | * @param id Peer ID | ||
518 | * @param probability The probability with which this sampler has seen all ids | ||
519 | * @param num_observed How many ids this sampler has observed | ||
520 | */ | ||
521 | static void | ||
522 | check_peer_info_ready (void *cls, | ||
523 | const struct GNUNET_PeerIdentity *id, | ||
524 | double probability, | ||
525 | uint32_t num_observed) | ||
526 | { | ||
527 | struct RPS_SamplerRequestHandleSingleInfo *req_handle = cls; | ||
528 | (void) id; | ||
529 | RPS_sampler_sinlge_info_ready_cb tmp_cb; | ||
530 | struct GNUNET_PeerIdentity *peer; | ||
531 | void *cb_cls; | ||
532 | (void) probability; | ||
533 | (void) num_observed; | ||
534 | |||
535 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
536 | "Got single peer with additional info\n"); | ||
537 | |||
538 | GNUNET_assert (NULL != req_handle->callback); | ||
539 | |||
540 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
541 | "returning single peer with info to the client\n"); | ||
542 | |||
543 | /* Copy pointers and peers temporarily as they | ||
544 | * might be deleted from within the callback */ | ||
545 | tmp_cb = req_handle->callback; | ||
546 | peer = GNUNET_new (struct GNUNET_PeerIdentity); | ||
547 | GNUNET_memcpy (peer, | ||
548 | req_handle->id, | ||
549 | sizeof (struct GNUNET_PeerIdentity)); | ||
550 | cb_cls = req_handle->cls; | ||
551 | RPS_sampler_request_single_info_cancel (req_handle); | ||
552 | req_handle = NULL; | ||
553 | tmp_cb (peer, cb_cls, probability, num_observed); | ||
554 | GNUNET_free (peer); | ||
555 | } | ||
556 | |||
557 | |||
558 | /** | ||
463 | * Get n random peers out of the sampled peers. | 559 | * Get n random peers out of the sampled peers. |
464 | * | 560 | * |
465 | * We might want to reinitialise this sampler after giving the | 561 | * We might want to reinitialise this sampler after giving the |
@@ -469,8 +565,6 @@ check_n_peers_ready (void *cls, | |||
469 | * @param sampler the sampler to get peers from. | 565 | * @param sampler the sampler to get peers from. |
470 | * @param cb callback that will be called once the ids are ready. | 566 | * @param cb callback that will be called once the ids are ready. |
471 | * @param cls closure given to @a cb | 567 | * @param cls closure given to @a cb |
472 | * @param for_client #GNUNET_YES if result is used for client, | ||
473 | * #GNUNET_NO if used internally | ||
474 | * @param num_peers the number of peers requested | 568 | * @param num_peers the number of peers requested |
475 | */ | 569 | */ |
476 | struct RPS_SamplerRequestHandle * | 570 | struct RPS_SamplerRequestHandle * |
@@ -506,6 +600,7 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler, | |||
506 | { | 600 | { |
507 | gpc = GNUNET_new (struct GetPeerCls); | 601 | gpc = GNUNET_new (struct GetPeerCls); |
508 | gpc->req_handle = req_handle; | 602 | gpc->req_handle = req_handle; |
603 | gpc->req_single_info_handle = NULL; | ||
509 | gpc->cont = check_n_peers_ready; | 604 | gpc->cont = check_n_peers_ready; |
510 | gpc->cont_cls = req_handle; | 605 | gpc->cont_cls = req_handle; |
511 | gpc->id = &req_handle->ids[i]; | 606 | gpc->id = &req_handle->ids[i]; |
@@ -515,11 +610,56 @@ RPS_sampler_get_n_rand_peers (struct RPS_Sampler *sampler, | |||
515 | gpc); | 610 | gpc); |
516 | // maybe add a little delay | 611 | // maybe add a little delay |
517 | gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers, | 612 | gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers, |
518 | gpc); | 613 | gpc); |
519 | } | 614 | } |
520 | return req_handle; | 615 | return req_handle; |
521 | } | 616 | } |
522 | 617 | ||
618 | |||
619 | /** | ||
620 | * Get one random peer with additional information. | ||
621 | * | ||
622 | * @param sampler the sampler to get peers from. | ||
623 | * @param cb callback that will be called once the ids are ready. | ||
624 | * @param cls closure given to @a cb | ||
625 | */ | ||
626 | struct RPS_SamplerRequestHandleSingleInfo * | ||
627 | RPS_sampler_get_rand_peer_info (struct RPS_Sampler *sampler, | ||
628 | RPS_sampler_sinlge_info_ready_cb cb, | ||
629 | void *cls) | ||
630 | { | ||
631 | struct RPS_SamplerRequestHandleSingleInfo *req_handle; | ||
632 | struct GetPeerCls *gpc; | ||
633 | |||
634 | GNUNET_assert (0 != sampler->sampler_size); | ||
635 | |||
636 | // TODO check if we have too much (distinct) sampled peers | ||
637 | req_handle = GNUNET_new (struct RPS_SamplerRequestHandleSingleInfo); | ||
638 | req_handle->id = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | ||
639 | req_handle->sampler = sampler; | ||
640 | req_handle->callback = cb; | ||
641 | req_handle->cls = cls; | ||
642 | GNUNET_CONTAINER_DLL_insert (sampler->req_handle_single_head, | ||
643 | sampler->req_handle_single_tail, | ||
644 | req_handle); | ||
645 | |||
646 | gpc = GNUNET_new (struct GetPeerCls); | ||
647 | gpc->req_handle = NULL; | ||
648 | gpc->req_single_info_handle = req_handle; | ||
649 | gpc->cont = check_peer_info_ready; | ||
650 | gpc->cont_cls = req_handle; | ||
651 | gpc->id = req_handle->id; | ||
652 | |||
653 | GNUNET_CONTAINER_DLL_insert (req_handle->gpc_head, | ||
654 | req_handle->gpc_tail, | ||
655 | gpc); | ||
656 | // maybe add a little delay | ||
657 | gpc->get_peer_task = GNUNET_SCHEDULER_add_now (sampler->get_peers, | ||
658 | gpc); | ||
659 | return req_handle; | ||
660 | } | ||
661 | |||
662 | |||
523 | /** | 663 | /** |
524 | * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb. | 664 | * Cancle a request issued through #RPS_sampler_n_rand_peers_ready_cb. |
525 | * | 665 | * |
@@ -559,6 +699,45 @@ RPS_sampler_request_cancel (struct RPS_SamplerRequestHandle *req_handle) | |||
559 | 699 | ||
560 | 700 | ||
561 | /** | 701 | /** |
702 | * Cancle a request issued through #RPS_sampler_sinlge_info_ready_cb. | ||
703 | * | ||
704 | * @param req_handle the handle to the request | ||
705 | */ | ||
706 | void | ||
707 | RPS_sampler_request_single_info_cancel ( | ||
708 | struct RPS_SamplerRequestHandleSingleInfo *req_single_info_handle) | ||
709 | { | ||
710 | struct GetPeerCls *i; | ||
711 | |||
712 | while (NULL != (i = req_single_info_handle->gpc_head) ) | ||
713 | { | ||
714 | GNUNET_CONTAINER_DLL_remove (req_single_info_handle->gpc_head, | ||
715 | req_single_info_handle->gpc_tail, | ||
716 | i); | ||
717 | if (NULL != i->get_peer_task) | ||
718 | { | ||
719 | GNUNET_SCHEDULER_cancel (i->get_peer_task); | ||
720 | } | ||
721 | if (NULL != i->notify_ctx) | ||
722 | { | ||
723 | GNUNET_CONTAINER_DLL_remove (req_single_info_handle->sampler->notify_ctx_head, | ||
724 | req_single_info_handle->sampler->notify_ctx_tail, | ||
725 | i->notify_ctx); | ||
726 | GNUNET_free (i->notify_ctx); | ||
727 | i->notify_ctx = NULL; | ||
728 | } | ||
729 | GNUNET_free (i); | ||
730 | } | ||
731 | GNUNET_free (req_single_info_handle->id); | ||
732 | req_single_info_handle->id = NULL; | ||
733 | GNUNET_CONTAINER_DLL_remove (req_single_info_handle->sampler->req_handle_single_head, | ||
734 | req_single_info_handle->sampler->req_handle_single_tail, | ||
735 | req_single_info_handle); | ||
736 | GNUNET_free (req_single_info_handle); | ||
737 | } | ||
738 | |||
739 | |||
740 | /** | ||
562 | * Cleans the sampler. | 741 | * Cleans the sampler. |
563 | */ | 742 | */ |
564 | void | 743 | void |