aboutsummaryrefslogtreecommitdiff
path: root/src/set
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2015-10-03 22:36:37 +0000
committerFlorian Dold <florian.dold@gmail.com>2015-10-03 22:36:37 +0000
commit8c85bda93a8ece52f02af7f20fb797ad6ac79337 (patch)
tree9170d89d46bae30e60a3f45e852e0469700a7eab /src/set
parent03b62462b4db11dbbb3e121cb6992c8d0fb9152a (diff)
downloadgnunet-8c85bda93a8ece52f02af7f20fb797ad6ac79337.tar.gz
gnunet-8c85bda93a8ece52f02af7f20fb797ad6ac79337.zip
- another fix to generation handling and lazy copying
Diffstat (limited to 'src/set')
-rw-r--r--src/set/gnunet-service-set.c54
-rw-r--r--src/set/gnunet-service-set.h8
-rw-r--r--src/set/test_set.conf2
-rw-r--r--src/set/test_set_union_copy.c17
4 files changed, 58 insertions, 23 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
402static int
403is_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
407int 413int
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
958again:
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,
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index c3650aa9b..bc3052f02 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -560,6 +560,9 @@ struct Set
560 */ 560 */
561 struct GenerationRange *excluded_generations; 561 struct GenerationRange *excluded_generations;
562 562
563 /**
564 * Number of elements in array @a excluded_generations.
565 */
563 unsigned int excluded_generations_size; 566 unsigned int excluded_generations_size;
564 567
565 /** 568 /**
@@ -574,6 +577,11 @@ struct Set
574 uint16_t iteration_id; 577 uint16_t iteration_id;
575 578
576 /** 579 /**
580 * Generation we're currently iteration over.
581 */
582 unsigned int iter_generation;
583
584 /**
577 * Content, possibly shared by multiple sets, 585 * Content, possibly shared by multiple sets,
578 * and thus reference counted. 586 * and thus reference counted.
579 */ 587 */
diff --git a/src/set/test_set.conf b/src/set/test_set.conf
index 4f32b8854..ae7708c2d 100644
--- a/src/set/test_set.conf
+++ b/src/set/test_set.conf
@@ -6,7 +6,7 @@ GNUNET_TEST_HOME = /tmp/test-gnunet-set/
6[set] 6[set]
7AUTOSTART = YES 7AUTOSTART = YES
8#PREFIX = valgrind 8#PREFIX = valgrind
9PREFIX = valgrind --leak-check=full 9#PREFIX = valgrind --leak-check=full
10#PREFIX = gdbserver :1234 10#PREFIX = gdbserver :1234
11OPTIONS = -L INFO 11OPTIONS = -L INFO
12 12
diff --git a/src/set/test_set_union_copy.c b/src/set/test_set_union_copy.c
index bb8d57631..47520588a 100644
--- a/src/set/test_set_union_copy.c
+++ b/src/set/test_set_union_copy.c
@@ -157,7 +157,7 @@ void test_done (void *cls)
157 157
158void check_new_set_count (void *cls) 158void check_new_set_count (void *cls)
159{ 159{
160 check_count (set2, "new set", 2, &test_done, NULL); 160 check_count (set2, "new set", 4, &test_done, NULL);
161} 161}
162 162
163 163
@@ -166,8 +166,13 @@ void copy_done (void *cls, struct GNUNET_SET_Handle *new_set)
166 printf ("copy done\n"); 166 printf ("copy done\n");
167 set2 = new_set; 167 set2 = new_set;
168 remove_element_str (set2, "spam"); 168 remove_element_str (set2, "spam");
169 add_element_str (set2, "new1");
170 add_element_str (set2, "new2");
171 remove_element_str (set2, "new2");
172 remove_element_str (set2, "new3");
169 // Check that set1 didn't change. 173 // Check that set1 didn't change.
170 check_count (set1, "old set", 3, &check_new_set_count, NULL); 174 check_count (set1, "old set", 3,
175 &check_new_set_count, NULL);
171} 176}
172 177
173 178
@@ -203,8 +208,14 @@ run (void *cls,
203 set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); 208 set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
204 add_element_str (set1, "foo"); 209 add_element_str (set1, "foo");
205 add_element_str (set1, "bar"); 210 add_element_str (set1, "bar");
211 /* duplicate -- ignored */
212 add_element_str (set1, "bar");
206 remove_element_str (set1, "foo"); 213 remove_element_str (set1, "foo");
214 /* non-existent -- ignored */
215 remove_element_str (set1, "nonexist1");
207 add_element_str (set1, "spam"); 216 add_element_str (set1, "spam");
217 /* duplicate -- ignored */
218 remove_element_str (set1, "foo");
208 add_element_str (set1, "eggs"); 219 add_element_str (set1, "eggs");
209 220
210 check_count (set1, "initial test", 3, &test_copy, NULL); 221 check_count (set1, "initial test", 3, &test_copy, NULL);
@@ -214,7 +225,7 @@ run (void *cls,
214int 225int
215main (int argc, char **argv) 226main (int argc, char **argv)
216{ 227{
217 if (0 != GNUNET_TESTING_peer_run ("test_set_api", 228 if (0 != GNUNET_TESTING_peer_run ("test_set_union_copy",
218 "test_set.conf", 229 "test_set.conf",
219 &run, NULL)) 230 &run, NULL))
220 { 231 {