aboutsummaryrefslogtreecommitdiff
path: root/src/rps/gnunet-service-rps_sampler.c
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2015-01-22 00:18:44 +0000
committerJulius Bünger <buenger@mytum.de>2015-01-22 00:18:44 +0000
commit5883a1ad9483eba3871968d9b8c5dfd9c3db12c1 (patch)
tree8a4861b1f8a93e52f3cf60261e9f8e6aca7b2586 /src/rps/gnunet-service-rps_sampler.c
parentebbd29b689e43fe5c4cc83074fb366b71fdcff85 (diff)
downloadgnunet-5883a1ad9483eba3871968d9b8c5dfd9c3db12c1.tar.gz
gnunet-5883a1ad9483eba3871968d9b8c5dfd9c3db12c1.zip
restructured service and sampler
Diffstat (limited to 'src/rps/gnunet-service-rps_sampler.c')
-rw-r--r--src/rps/gnunet-service-rps_sampler.c171
1 files changed, 69 insertions, 102 deletions
diff --git a/src/rps/gnunet-service-rps_sampler.c b/src/rps/gnunet-service-rps_sampler.c
index 85d8d532b..b2ee5fb21 100644
--- a/src/rps/gnunet-service-rps_sampler.c
+++ b/src/rps/gnunet-service-rps_sampler.c
@@ -151,7 +151,7 @@ struct RPS_Sampler
151/** 151/**
152 * Closure to _get_n_rand_peers_ready_cb() 152 * Closure to _get_n_rand_peers_ready_cb()
153 */ 153 */
154struct RPS_GetNRandPeersReadyCls 154struct NRandPeersReadyCls
155{ 155{
156 /** 156 /**
157 * Number of peers we are waiting for. 157 * Number of peers we are waiting for.
@@ -255,15 +255,15 @@ static uint32_t client_get_index;
255 * give those back. 255 * give those back.
256 */ 256 */
257 void 257 void
258RPS_sampler_get_n_rand_peers_ready_cb (void *cls, 258check_n_peers_ready (void *cls,
259 const struct GNUNET_PeerIdentity *id) 259 const struct GNUNET_PeerIdentity *id)
260{ 260{
261 struct RPS_GetNRandPeersReadyCls *n_peers_cls; 261 struct NRandPeersReadyCls *n_peers_cls;
262 262
263 n_peers_cls = (struct RPS_GetNRandPeersReadyCls *) cls; 263 n_peers_cls = (struct NRandPeersReadyCls *) cls;
264 264
265 LOG (GNUNET_ERROR_TYPE_DEBUG, 265 LOG (GNUNET_ERROR_TYPE_DEBUG,
266 "SAMPLER: Got %" PRIX32 "th of %" PRIX32 " peers\n", 266 "SAMPLER: Got %" PRIX32 ". of %" PRIX32 " peers\n",
267 n_peers_cls->cur_num_peers, n_peers_cls->num_peers); 267 n_peers_cls->cur_num_peers, n_peers_cls->num_peers);
268 268
269 if (n_peers_cls->num_peers - 1 == n_peers_cls->cur_num_peers) 269 if (n_peers_cls->num_peers - 1 == n_peers_cls->cur_num_peers)
@@ -297,12 +297,6 @@ RPS_sampler_elem_reinit (struct RPS_SamplerElement *sampler_el)
297 297
298 sampler_el->last_client_request = GNUNET_TIME_UNIT_FOREVER_ABS; 298 sampler_el->last_client_request = GNUNET_TIME_UNIT_FOREVER_ABS;
299 299
300 /* We might want to keep the previous peer */
301
302 //GNUNET_CRYPTO_hmac(&sampler_el->auth_key, sampler_el->peer_id,
303 // sizeof(struct GNUNET_PeerIdentity),
304 // &sampler_el->peer_id_hash);
305
306 sampler_el->birth = GNUNET_TIME_absolute_get (); 300 sampler_el->birth = GNUNET_TIME_absolute_get ();
307 sampler_el->num_peers = 0; 301 sampler_el->num_peers = 0;
308 sampler_el->num_change = 0; 302 sampler_el->num_change = 0;
@@ -479,7 +473,6 @@ RPS_sampler_resize (unsigned int new_size)
479 * Initialise a tuple of sampler elements. 473 * Initialise a tuple of sampler elements.
480 * 474 *
481 * @param init_size the size the sampler is initialised with 475 * @param init_size the size the sampler is initialised with
482 * @param id with which all newly created sampler elements are initialised
483 * @param ins_cb the callback that will be called on every PeerID that is 476 * @param ins_cb the callback that will be called on every PeerID that is
484 * newly inserted into a sampler element 477 * newly inserted into a sampler element
485 * @param ins_cls the closure given to #ins_cb 478 * @param ins_cls the closure given to #ins_cb
@@ -489,7 +482,6 @@ RPS_sampler_resize (unsigned int new_size)
489 */ 482 */
490 void 483 void
491RPS_sampler_init (size_t init_size, 484RPS_sampler_init (size_t init_size,
492 const struct GNUNET_PeerIdentity *id,
493 struct GNUNET_TIME_Relative max_round_interval, 485 struct GNUNET_TIME_Relative max_round_interval,
494 RPS_sampler_insert_cb ins_cb, void *ins_cls, 486 RPS_sampler_insert_cb ins_cb, void *ins_cls,
495 RPS_sampler_remove_cb rem_cb, void *rem_cls) 487 RPS_sampler_remove_cb rem_cb, void *rem_cls)
@@ -513,7 +505,6 @@ RPS_sampler_init (size_t init_size,
513 //sampler->sampler_elements = GNUNET_new_array(init_size, struct GNUNET_PeerIdentity); 505 //sampler->sampler_elements = GNUNET_new_array(init_size, struct GNUNET_PeerIdentity);
514 //GNUNET_array_grow (sampler->sampler_elements, sampler->sampler_size, min_size); 506 //GNUNET_array_grow (sampler->sampler_elements, sampler->sampler_size, min_size);
515 RPS_sampler_resize (init_size); 507 RPS_sampler_resize (init_size);
516 RPS_sampler_update_list (id); // no super nice desing but ok for the moment
517 508
518 client_get_index = 0; 509 client_get_index = 0;
519 510
@@ -568,13 +559,14 @@ RPS_sampler_reinitialise_by_value (const struct GNUNET_PeerIdentity *id)
568 * corrsponding peer to the client. 559 * corrsponding peer to the client.
569 * Only used internally 560 * Only used internally
570 */ 561 */
571 const struct GNUNET_PeerIdentity * 562 void
572RPS_sampler_get_rand_peer_ () 563RPS_sampler_get_rand_peer_ (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
573{ 564{
565 struct GetPeerCls *gpc;
574 uint32_t r_index; 566 uint32_t r_index;
575 const struct GNUNET_PeerIdentity *peer; // do we have to malloc that? 567 struct GNUNET_HashCode *hash;
576 568
577 // TODO implement extra logic 569 gpc = (struct GetPeerCls *) cls;
578 570
579 /**; 571 /**;
580 * Choose the r_index of the peer we want to return 572 * Choose the r_index of the peer we want to return
@@ -583,50 +575,25 @@ RPS_sampler_get_rand_peer_ ()
583 r_index = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG, 575 r_index = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_STRONG,
584 sampler->sampler_size); 576 sampler->sampler_size);
585 577
586 //if ( EMPTY == sampler->sampler_elements[r_index]->is_empty ) 578 if ( EMPTY == sampler->sampler_elements[r_index]->is_empty )
587 // // TODO schedule for later
588 // peer = NULL;
589 //else
590 peer = &(sampler->sampler_elements[r_index]->peer_id);
591 //sampler->sampler_elements[r_index]->last_client_request = GNUNET_TIME_absolute_get();
592 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sgrp: Returning PeerID %s\n", GNUNET_i2s(peer));
593
594 return peer;
595}
596
597
598/**
599 * Get n random peers out of the sampled peers.
600 *
601 * We might want to reinitialise this sampler after giving the
602 * corrsponding peer to the client.
603 * Random with or without consumption?
604 * Only used internally
605 */
606 const struct GNUNET_PeerIdentity *
607RPS_sampler_get_n_rand_peers_ (uint32_t n)
608{
609 if ( 0 == sampler->sampler_size )
610 { 579 {
611 LOG (GNUNET_ERROR_TYPE_DEBUG, 580 gpc->get_peer_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
612 "Sgrp: List empty - Returning NULL\n"); 581 GNUNET_TIME_UNIT_SECONDS,
613 return NULL; 582 .1),
583 &RPS_sampler_get_rand_peer_,
584 cls);
585 return;
614 } 586 }
615 else
616 {
617 // TODO check if we have too much (distinct) sampled peers
618 // If we are not ready yet maybe schedule for later
619 struct GNUNET_PeerIdentity *peers;
620 uint32_t i;
621 587
622 peers = GNUNET_malloc (n * sizeof(struct GNUNET_PeerIdentity)); 588 *gpc->id = sampler->sampler_elements[r_index]->peer_id;
623 589
624 for ( i = 0 ; i < n ; i++ ) { 590 hash = GNUNET_new (struct GNUNET_HashCode);
625 //peers[i] = RPS_sampler_get_rand_peer_(sampler->sampler_elements); 591 GNUNET_CRYPTO_hash (&gpc->get_peer_task, sizeof (struct GNUNET_SCHEDULER_Task *), hash);
626 memcpy (&peers[i], RPS_sampler_get_rand_peer_ (), sizeof (struct GNUNET_PeerIdentity)); 592 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (get_peer_tasks, hash, &gpc->get_peer_task))
627 } 593 LOG (GNUNET_ERROR_TYPE_WARNING, "SAMPLER: Key to remove is not in the hashmap\n");
628 return peers; 594 GNUNET_free (gpc->get_peer_task);
629 } 595
596 gpc->cb (gpc->cb_cls, gpc->id);
630} 597}
631 598
632 599
@@ -639,28 +606,28 @@ RPS_sampler_get_n_rand_peers_ (uint32_t n)
639 * @return a random PeerID of the PeerIDs previously put into the sampler. 606 * @return a random PeerID of the PeerIDs previously put into the sampler.
640 */ 607 */
641 void 608 void
642//RPS_sampler_get_rand_peer (RPS_sampler_rand_peer_ready_cb cb,
643// void *cls, struct GNUNET_PeerIdentity *id)
644RPS_sampler_get_rand_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 609RPS_sampler_get_rand_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
645{ 610{
646 struct GetPeerCls *gpc; 611 struct GetPeerCls *gpc;
612 struct GNUNET_PeerIdentity tmp_id;
647 struct RPS_SamplerElement *s_elem; 613 struct RPS_SamplerElement *s_elem;
648 struct GNUNET_TIME_Relative last_request_diff; 614 struct GNUNET_TIME_Relative last_request_diff;
649 struct GNUNET_HashCode *hash; 615 struct GNUNET_HashCode *hash;
650 uint32_t tmp_client_get_index; 616 uint32_t tmp_client_get_index;
651 //struct GNUNET_TIME_Relative inv_last_request_diff;
652 617
653 LOG (GNUNET_ERROR_TYPE_DEBUG, "SAMPLER: Single peer was requested\n"); 618 LOG (GNUNET_ERROR_TYPE_DEBUG, "SAMPLER: Single peer was requested\n");
654 619
655 gpc = (struct GetPeerCls *) cls; 620 gpc = (struct GetPeerCls *) cls;
656 hash = GNUNET_new (struct GNUNET_HashCode); 621 hash = GNUNET_new (struct GNUNET_HashCode);
622
623 /* Store the next #client_get_index to check whether we cycled over the whole list */
657 if (0 < client_get_index) 624 if (0 < client_get_index)
658 tmp_client_get_index = client_get_index - 1; 625 tmp_client_get_index = client_get_index - 1;
659 else 626 else
660 tmp_client_get_index = sampler->sampler_size - 1; 627 tmp_client_get_index = sampler->sampler_size - 1;
661 628
662 LOG (GNUNET_ERROR_TYPE_DEBUG, 629 LOG (GNUNET_ERROR_TYPE_DEBUG,
663 "SAMPLER: scheduling for later if index reaches %" PRIX32 " (sampler size: %" PRIX32 ".\n", 630 "SAMPLER: scheduling for later if index reaches %" PRIX32 " (sampler size: %" PRIX32 ").\n",
664 tmp_client_get_index, sampler->sampler_size); 631 tmp_client_get_index, sampler->sampler_size);
665 632
666 do 633 do
@@ -674,17 +641,22 @@ RPS_sampler_get_rand_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext
674 return; 641 return;
675 } 642 }
676 643
677 *gpc->id = sampler->sampler_elements[client_get_index]->peer_id; 644 tmp_id = sampler->sampler_elements[client_get_index]->peer_id;
678
679 RPS_sampler_elem_reinit (sampler->sampler_elements[client_get_index]); 645 RPS_sampler_elem_reinit (sampler->sampler_elements[client_get_index]);
646 RPS_sampler_elem_next (sampler->sampler_elements[client_get_index], &tmp_id,
647 NULL, NULL, NULL, NULL);
648
649 /* Cycle the #client_get_index one step further */
680 if ( client_get_index == sampler->sampler_size - 1 ) 650 if ( client_get_index == sampler->sampler_size - 1 )
681 client_get_index = 0; 651 client_get_index = 0;
682 else 652 else
683 client_get_index++; 653 client_get_index++;
654
684 LOG (GNUNET_ERROR_TYPE_DEBUG, "SAMPLER: incremented index to %" PRIX32 ".\n", client_get_index); 655 LOG (GNUNET_ERROR_TYPE_DEBUG, "SAMPLER: incremented index to %" PRIX32 ".\n", client_get_index);
685 } while (EMPTY == sampler->sampler_elements[client_get_index]->is_empty); 656 } while (EMPTY == sampler->sampler_elements[client_get_index]->is_empty);
686 657
687 s_elem = sampler->sampler_elements[client_get_index]; 658 s_elem = sampler->sampler_elements[client_get_index];
659 *gpc->id = s_elem->peer_id;
688 660
689 /* Check whether we may use this sampler to give it back to the client */ 661 /* Check whether we may use this sampler to give it back to the client */
690 if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != s_elem->last_client_request.abs_value_us) 662 if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us != s_elem->last_client_request.abs_value_us)
@@ -729,54 +701,49 @@ RPS_sampler_get_rand_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext
729 * 701 *
730 * @param cb callback that will be called once the ids are ready. 702 * @param cb callback that will be called once the ids are ready.
731 * @param cls closure given to @a cb 703 * @param cls closure given to @a cb
704 * @param for_client #GNUNET_YES if result is used for client,
705 * #GNUNET_NO if used internally
732 * @param num_peers the number of peers requested 706 * @param num_peers the number of peers requested
733 */ 707 */
734 void 708 void
735RPS_sampler_get_n_rand_peers (RPS_sampler_n_rand_peers_ready_cb cb, 709RPS_sampler_get_n_rand_peers (RPS_sampler_n_rand_peers_ready_cb cb,
736 void *cls, uint32_t num_peers) 710 void *cls, uint32_t num_peers, int for_client)
737{ 711{
738 if ( 0 == sampler->sampler_size ) 712 GNUNET_assert (0 != sampler->sampler_size);
739 {
740 LOG (GNUNET_ERROR_TYPE_DEBUG,
741 "Sgrp: List empty - Returning NULL\n");
742 cb (cls, NULL, 0);
743 }
744 else
745 {
746 // TODO check if we have too much (distinct) sampled peers
747 // If we are not ready yet maybe schedule for later
748 uint32_t i;
749 struct RPS_GetNRandPeersReadyCls *cb_cls;
750 struct GetPeerCls *gpc;
751 struct GNUNET_HashCode *hash;
752
753 hash = GNUNET_new (struct GNUNET_HashCode);
754 713
755 cb_cls = GNUNET_new (struct RPS_GetNRandPeersReadyCls); 714 // TODO check if we have too much (distinct) sampled peers
756 cb_cls->num_peers = num_peers; 715 uint32_t i;
757 cb_cls->cur_num_peers = 0; 716 struct NRandPeersReadyCls *cb_cls;
758 cb_cls->ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity); 717 struct GetPeerCls *gpc;
759 cb_cls->callback = cb; 718 struct GNUNET_HashCode *hash;
760 cb_cls->cls = cls;
761 719
762 LOG (GNUNET_ERROR_TYPE_DEBUG, 720 hash = GNUNET_new (struct GNUNET_HashCode);
763 "SAMPLER: Scheduling requests for %" PRIX32 " peers\n", num_peers);
764 721
765 for ( i = 0 ; i < num_peers ; i++ ) 722 cb_cls = GNUNET_new (struct NRandPeersReadyCls);
766 { 723 cb_cls->num_peers = num_peers;
767 gpc = GNUNET_new (struct GetPeerCls); 724 cb_cls->cur_num_peers = 0;
768 gpc->cb = RPS_sampler_get_n_rand_peers_ready_cb; 725 cb_cls->ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
769 gpc->cb_cls = cb_cls; 726 cb_cls->callback = cb;
770 gpc->id = &cb_cls->ids[i]; 727 cb_cls->cls = cls;
728
729 LOG (GNUNET_ERROR_TYPE_DEBUG,
730 "SAMPLER: Scheduling requests for %" PRIX32 " peers\n", num_peers);
771 731
772 // maybe add a little delay 732 for ( i = 0 ; i < num_peers ; i++ )
733 {
734 gpc = GNUNET_new (struct GetPeerCls);
735 gpc->cb = check_n_peers_ready;
736 gpc->cb_cls = cb_cls;
737 gpc->id = &cb_cls->ids[i];
738
739 // maybe add a little delay
740 if (GNUNET_YES == for_client)
773 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (&RPS_sampler_get_rand_peer, gpc); 741 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (&RPS_sampler_get_rand_peer, gpc);
774 GNUNET_CRYPTO_hash (&gpc->get_peer_task, sizeof (struct GNUNET_SCHEDULER_Task *), hash); 742 else if (GNUNET_NO == for_client)
775 (void) GNUNET_CONTAINER_multihashmap_put (get_peer_tasks, hash, &gpc->get_peer_task, 743 gpc->get_peer_task = GNUNET_SCHEDULER_add_now (&RPS_sampler_get_rand_peer_, gpc);
776 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 744 GNUNET_CRYPTO_hash (&gpc->get_peer_task, sizeof (struct GNUNET_SCHEDULER_Task *), hash);
777 //RPS_sampler_get_rand_peer (RPS_sampler_get_n_rand_peers_ready_cb, 745 (void) GNUNET_CONTAINER_multihashmap_put (get_peer_tasks, hash, &gpc->get_peer_task,
778 // cb_cls, &peers[i]); 746 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
779 }
780 } 747 }
781} 748}
782 749