aboutsummaryrefslogtreecommitdiff
path: root/src/rps/rps-sampler_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rps/rps-sampler_common.c')
-rw-r--r--src/rps/rps-sampler_common.c187
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 */
121struct 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 */
421static void 466static void
422check_n_peers_ready (void *cls, 467check_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 */
521static void
522check_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 */
476struct RPS_SamplerRequestHandle * 570struct 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 */
626struct RPS_SamplerRequestHandleSingleInfo *
627RPS_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 */
706void
707RPS_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