diff options
author | Florian Dold <florian.dold@gmail.com> | 2015-10-03 22:36:37 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2015-10-03 22:36:37 +0000 |
commit | 8c85bda93a8ece52f02af7f20fb797ad6ac79337 (patch) | |
tree | 9170d89d46bae30e60a3f45e852e0469700a7eab /src/set/gnunet-service-set.c | |
parent | 03b62462b4db11dbbb3e121cb6992c8d0fb9152a (diff) | |
download | gnunet-8c85bda93a8ece52f02af7f20fb797ad6ac79337.tar.gz gnunet-8c85bda93a8ece52f02af7f20fb797ad6ac79337.zip |
- another fix to generation handling and lazy copying
Diffstat (limited to 'src/set/gnunet-service-set.c')
-rw-r--r-- | src/set/gnunet-service-set.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 754bc96e0..2f1578514 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -341,12 +341,7 @@ is_element_of_generation (struct ElementEntry *ee, | |||
341 | int is_present; | 341 | int is_present; |
342 | unsigned int i; | 342 | unsigned int i; |
343 | 343 | ||
344 | /* If ee->mutations is NULL, | 344 | GNUNET_assert (NULL != ee->mutations); |
345 | the element was added in generation 0, | ||
346 | and there are no removes, thus the element | ||
347 | is part of any generation we query. */ | ||
348 | if (NULL == ee->mutations) | ||
349 | return GNUNET_YES; | ||
350 | 345 | ||
351 | if (GNUNET_YES == is_excluded_generation (query_generation, excluded, excluded_size)) | 346 | if (GNUNET_YES == is_excluded_generation (query_generation, excluded, excluded_size)) |
352 | { | 347 | { |
@@ -389,7 +384,7 @@ is_element_of_generation (struct ElementEntry *ee, | |||
389 | is_present = mut->added; | 384 | is_present = mut->added; |
390 | } | 385 | } |
391 | 386 | ||
392 | return GNUNET_YES; | 387 | return is_present; |
393 | } | 388 | } |
394 | 389 | ||
395 | 390 | ||
@@ -404,6 +399,17 @@ _GSS_is_element_of_set (struct ElementEntry *ee, | |||
404 | } | 399 | } |
405 | 400 | ||
406 | 401 | ||
402 | static int | ||
403 | is_element_of_iteration (struct ElementEntry *ee, | ||
404 | struct Set *set) | ||
405 | { | ||
406 | return is_element_of_generation (ee, | ||
407 | set->iter_generation, | ||
408 | set->excluded_generations, | ||
409 | set->excluded_generations_size); | ||
410 | } | ||
411 | |||
412 | |||
407 | int | 413 | int |
408 | _GSS_is_element_of_operation (struct ElementEntry *ee, | 414 | _GSS_is_element_of_operation (struct ElementEntry *ee, |
409 | struct Operation *op) | 415 | struct Operation *op) |
@@ -842,11 +848,9 @@ execute_add (struct Set *set, | |||
842 | else if (GNUNET_YES == _GSS_is_element_of_set (ee, set)) | 848 | else if (GNUNET_YES == _GSS_is_element_of_set (ee, set)) |
843 | { | 849 | { |
844 | /* same element inserted twice */ | 850 | /* same element inserted twice */ |
845 | GNUNET_break (0); | ||
846 | return; | 851 | return; |
847 | } | 852 | } |
848 | 853 | ||
849 | if (0 != set->current_generation) | ||
850 | { | 854 | { |
851 | struct MutationEvent mut = { | 855 | struct MutationEvent mut = { |
852 | .generation = set->current_generation, | 856 | .generation = set->current_generation, |
@@ -888,22 +892,14 @@ execute_remove (struct Set *set, | |||
888 | &hash); | 892 | &hash); |
889 | if (NULL == ee) | 893 | if (NULL == ee) |
890 | { | 894 | { |
891 | /* Client tried to remove non-existing element */ | 895 | /* Client tried to remove non-existing element. */ |
892 | GNUNET_break (0); | ||
893 | return; | 896 | return; |
894 | } | 897 | } |
895 | if (GNUNET_NO == _GSS_is_element_of_set (ee, set)) | 898 | if (GNUNET_NO == _GSS_is_element_of_set (ee, set)) |
896 | { | 899 | { |
897 | /* Client tried to remove element twice */ | 900 | /* Client tried to remove element twice */ |
898 | GNUNET_break (0); | ||
899 | return; | 901 | return; |
900 | } | 902 | } |
901 | else if (0 == set->current_generation) | ||
902 | { | ||
903 | // If current_generation is 0, then there are no running set operations | ||
904 | // or lazy copies, thus we can safely remove the element. | ||
905 | (void) GNUNET_CONTAINER_multihashmap_remove_all (set->content->elements, &hash); | ||
906 | } | ||
907 | else | 903 | else |
908 | { | 904 | { |
909 | struct MutationEvent mut = { | 905 | struct MutationEvent mut = { |
@@ -958,6 +954,9 @@ send_client_element (struct Set *set) | |||
958 | struct GNUNET_SET_IterResponseMessage *msg; | 954 | struct GNUNET_SET_IterResponseMessage *msg; |
959 | 955 | ||
960 | GNUNET_assert (NULL != set->iter); | 956 | GNUNET_assert (NULL != set->iter); |
957 | |||
958 | again: | ||
959 | |||
961 | ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter, | 960 | ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter, |
962 | NULL, | 961 | NULL, |
963 | (const void **) &ee); | 962 | (const void **) &ee); |
@@ -997,6 +996,10 @@ send_client_element (struct Set *set) | |||
997 | else | 996 | else |
998 | { | 997 | { |
999 | GNUNET_assert (NULL != ee); | 998 | GNUNET_assert (NULL != ee); |
999 | |||
1000 | if (GNUNET_NO == is_element_of_iteration (ee, set)) | ||
1001 | goto again; | ||
1002 | |||
1000 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1003 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1001 | "Sending iteration element on %p.\n", | 1004 | "Sending iteration element on %p.\n", |
1002 | (void *) set); | 1005 | (void *) set); |
@@ -1046,13 +1049,15 @@ handle_client_iterate (void *cls, | |||
1046 | return; | 1049 | return; |
1047 | } | 1050 | } |
1048 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1051 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1049 | "Iterating set %p with %u elements\n", | 1052 | "Iterating set %p in gen %u with %u content elements\n", |
1050 | (void *) set, | 1053 | (void *) set, |
1054 | set->current_generation, | ||
1051 | GNUNET_CONTAINER_multihashmap_size (set->content->elements)); | 1055 | GNUNET_CONTAINER_multihashmap_size (set->content->elements)); |
1052 | GNUNET_SERVER_receive_done (client, | 1056 | GNUNET_SERVER_receive_done (client, |
1053 | GNUNET_OK); | 1057 | GNUNET_OK); |
1054 | set->content->iterator_count += 1; | 1058 | set->content->iterator_count += 1; |
1055 | set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements); | 1059 | set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements); |
1060 | set->iter_generation = set->current_generation; | ||
1056 | send_client_element (set); | 1061 | send_client_element (set); |
1057 | } | 1062 | } |
1058 | 1063 | ||
@@ -1529,6 +1534,17 @@ handle_client_copy_lazy_connect (void *cls, | |||
1529 | set->state = set->vt->copy_state (cr->source_set); | 1534 | set->state = set->vt->copy_state (cr->source_set); |
1530 | set->content = cr->source_set->content; | 1535 | set->content = cr->source_set->content; |
1531 | set->content->refcount += 1; | 1536 | set->content->refcount += 1; |
1537 | |||
1538 | set->current_generation = cr->source_set->current_generation; | ||
1539 | set->excluded_generations_size = cr->source_set->excluded_generations_size; | ||
1540 | set->excluded_generations = GNUNET_memdup (cr->source_set->excluded_generations, | ||
1541 | set->excluded_generations_size * sizeof (struct GenerationRange)); | ||
1542 | |||
1543 | /* Advance the generation of the new set, so that mutations to the | ||
1544 | of the cloned set and the source set are independent. */ | ||
1545 | advance_generation (set); | ||
1546 | |||
1547 | |||
1532 | set->client = client; | 1548 | set->client = client; |
1533 | set->client_mq = GNUNET_MQ_queue_for_server_client (client); | 1549 | set->client_mq = GNUNET_MQ_queue_for_server_client (client); |
1534 | GNUNET_CONTAINER_DLL_insert (sets_head, | 1550 | GNUNET_CONTAINER_DLL_insert (sets_head, |