aboutsummaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-03-22 22:17:05 -0500
committerDavid Barksdale <amatus@amat.us>2017-03-22 22:19:13 -0500
commit78ecfccd774a77ae3d7a51e3f5c7c7c86cf7985b (patch)
tree1dc23a2f6d78c8026e69181ac90055929d79bba8 /src/datastore
parentaa98f144e6db0da5a0a4cad83fe64a80bbab6692 (diff)
downloadgnunet-78ecfccd774a77ae3d7a51e3f5c7c7c86cf7985b.tar.gz
gnunet-78ecfccd774a77ae3d7a51e3f5c7c7c86cf7985b.zip
[datastore] Return and update replication
This fixes a couple FIXMEs in the datastore code. The replication value is now returned from the datastore and the update function can increase the replication.
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/datastore.h2
-rw-r--r--src/datastore/datastore_api.c22
-rw-r--r--src/datastore/gnunet-datastore.c38
-rw-r--r--src/datastore/gnunet-service-datastore.c38
-rw-r--r--src/datastore/plugin_datastore_heap.c99
-rw-r--r--src/datastore/plugin_datastore_mysql.c117
-rw-r--r--src/datastore/plugin_datastore_postgres.c112
-rw-r--r--src/datastore/plugin_datastore_sqlite.c62
-rw-r--r--src/datastore/plugin_datastore_template.c26
-rw-r--r--src/datastore/test_datastore_api.c4
-rw-r--r--src/datastore/test_datastore_api_management.c24
-rw-r--r--src/datastore/test_plugin_datastore.c10
12 files changed, 337 insertions, 217 deletions
diff --git a/src/datastore/datastore.h b/src/datastore/datastore.h
index 5fd360161..98f8b82ef 100644
--- a/src/datastore/datastore.h
+++ b/src/datastore/datastore.h
@@ -229,7 +229,7 @@ struct DataMessage
229 uint32_t anonymity GNUNET_PACKED; 229 uint32_t anonymity GNUNET_PACKED;
230 230
231 /** 231 /**
232 * Desired replication level. 0 from service to API. 232 * Desired replication level.
233 */ 233 */
234 uint32_t replication GNUNET_PACKED; 234 uint32_t replication GNUNET_PACKED;
235 235
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c
index 26e1e501d..31f7a997f 100644
--- a/src/datastore/datastore_api.c
+++ b/src/datastore/datastore_api.c
@@ -352,7 +352,11 @@ mq_error_handler (void *cls,
352 qc.rc.proc (qc.rc.proc_cls, 352 qc.rc.proc (qc.rc.proc_cls,
353 NULL, 353 NULL,
354 0, 354 0,
355 NULL, 0, 0, 0, 355 NULL,
356 0,
357 0,
358 0,
359 0,
356 GNUNET_TIME_UNIT_ZERO_ABS, 360 GNUNET_TIME_UNIT_ZERO_ABS,
357 0); 361 0);
358 break; 362 break;
@@ -468,7 +472,11 @@ GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h,
468 qe->qc.rc.proc (qe->qc.rc.proc_cls, 472 qe->qc.rc.proc (qe->qc.rc.proc_cls,
469 NULL, 473 NULL,
470 0, 474 0,
471 NULL, 0, 0, 0, 475 NULL,
476 0,
477 0,
478 0,
479 0,
472 GNUNET_TIME_UNIT_ZERO_ABS, 480 GNUNET_TIME_UNIT_ZERO_ABS,
473 0); 481 0);
474 break; 482 break;
@@ -825,6 +833,7 @@ handle_data (void *cls,
825 ntohl (dm->type), 833 ntohl (dm->type),
826 ntohl (dm->priority), 834 ntohl (dm->priority),
827 ntohl (dm->anonymity), 835 ntohl (dm->anonymity),
836 ntohl (dm->replication),
828 GNUNET_TIME_absolute_ntoh (dm->expiration), 837 GNUNET_TIME_absolute_ntoh (dm->expiration),
829 GNUNET_ntohll (dm->uid)); 838 GNUNET_ntohll (dm->uid));
830} 839}
@@ -887,6 +896,7 @@ handle_data_end (void *cls,
887 0, 896 0,
888 0, 897 0,
889 0, 898 0,
899 0,
890 GNUNET_TIME_UNIT_ZERO_ABS, 900 GNUNET_TIME_UNIT_ZERO_ABS,
891 0); 901 0);
892} 902}
@@ -1022,8 +1032,6 @@ GNUNET_DATASTORE_put (struct GNUNET_DATASTORE_Handle *h,
1022 dm->priority = htonl (priority); 1032 dm->priority = htonl (priority);
1023 dm->anonymity = htonl (anonymity); 1033 dm->anonymity = htonl (anonymity);
1024 dm->replication = htonl (replication); 1034 dm->replication = htonl (replication);
1025 dm->reserved = htonl (0);
1026 dm->uid = GNUNET_htonll (0);
1027 dm->expiration = GNUNET_TIME_absolute_hton (expiration); 1035 dm->expiration = GNUNET_TIME_absolute_hton (expiration);
1028 dm->key = *key; 1036 dm->key = *key;
1029 GNUNET_memcpy (&dm[1], 1037 GNUNET_memcpy (&dm[1],
@@ -1226,13 +1234,7 @@ GNUNET_DATASTORE_remove (struct GNUNET_DATASTORE_Handle *h,
1226 env = GNUNET_MQ_msg_extra (dm, 1234 env = GNUNET_MQ_msg_extra (dm,
1227 size, 1235 size,
1228 GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE); 1236 GNUNET_MESSAGE_TYPE_DATASTORE_REMOVE);
1229 dm->rid = htonl (0);
1230 dm->size = htonl (size); 1237 dm->size = htonl (size);
1231 dm->type = htonl (0);
1232 dm->priority = htonl (0);
1233 dm->anonymity = htonl (0);
1234 dm->uid = GNUNET_htonll (0);
1235 dm->expiration = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS);
1236 dm->key = *key; 1238 dm->key = *key;
1237 GNUNET_memcpy (&dm[1], 1239 GNUNET_memcpy (&dm[1],
1238 data, 1240 data,
diff --git a/src/datastore/gnunet-datastore.c b/src/datastore/gnunet-datastore.c
index c93bc8dd3..7caf5d175 100644
--- a/src/datastore/gnunet-datastore.c
+++ b/src/datastore/gnunet-datastore.c
@@ -130,20 +130,23 @@ do_finish (void *cls,
130 * @param type type of the content 130 * @param type type of the content
131 * @param priority priority of the content 131 * @param priority priority of the content
132 * @param anonymity anonymity-level for the content 132 * @param anonymity anonymity-level for the content
133 * @param replication replication-level for the content
133 * @param expiration expiration time for the content 134 * @param expiration expiration time for the content
134 * @param uid unique identifier for the datum; 135 * @param uid unique identifier for the datum;
135 * maybe 0 if no unique identifier is available 136 * maybe 0 if no unique identifier is available
136 */ 137 */
137static void 138static void
138do_put (void *cls, 139do_put (void *cls,
139 const struct GNUNET_HashCode *key, 140 const struct GNUNET_HashCode *key,
140 size_t size, 141 size_t size,
141 const void *data, 142 const void *data,
142 enum GNUNET_BLOCK_Type type, 143 enum GNUNET_BLOCK_Type type,
143 uint32_t priority, 144 uint32_t priority,
144 uint32_t anonymity, 145 uint32_t anonymity,
145 struct GNUNET_TIME_Absolute 146 uint32_t replication,
146 expiration, uint64_t uid) 147 struct GNUNET_TIME_Absolute
148 expiration,
149 uint64_t uid)
147{ 150{
148 qe = NULL; 151 qe = NULL;
149 if ( (0 != offset) && 152 if ( (0 != offset) &&
@@ -154,13 +157,20 @@ do_put (void *cls,
154 } 157 }
155 if (0 == offset) 158 if (0 == offset)
156 first_uid = uid; 159 first_uid = uid;
157 qe = GNUNET_DATASTORE_put (db_dst, 0, 160 qe = GNUNET_DATASTORE_put (db_dst,
158 key, size, data, type, 161 0,
159 priority, anonymity, 162 key,
160 0 /* FIXME: replication is lost... */, 163 size,
161 expiration, 164 data,
162 0, 1, 165 type,
163 &do_finish, NULL); 166 priority,
167 anonymity,
168 replication,
169 expiration,
170 0,
171 1,
172 &do_finish,
173 NULL);
164} 174}
165 175
166 176
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index af33c4412..277530843 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -286,6 +286,7 @@ delete_expired (void *cls);
286 * @param type type of the content 286 * @param type type of the content
287 * @param priority priority of the content 287 * @param priority priority of the content
288 * @param anonymity anonymity-level for the content 288 * @param anonymity anonymity-level for the content
289 * @param replication replication-level for the content
289 * @param expiration expiration time for the content 290 * @param expiration expiration time for the content
290 * @param uid unique identifier for the datum; 291 * @param uid unique identifier for the datum;
291 * maybe 0 if no unique identifier is available 292 * maybe 0 if no unique identifier is available
@@ -302,6 +303,7 @@ expired_processor (void *cls,
302 enum GNUNET_BLOCK_Type type, 303 enum GNUNET_BLOCK_Type type,
303 uint32_t priority, 304 uint32_t priority,
304 uint32_t anonymity, 305 uint32_t anonymity,
306 uint32_t replication,
305 struct GNUNET_TIME_Absolute expiration, 307 struct GNUNET_TIME_Absolute expiration,
306 uint64_t uid) 308 uint64_t uid)
307{ 309{
@@ -374,6 +376,7 @@ delete_expired (void *cls)
374 * @param type type of the content 376 * @param type type of the content
375 * @param priority priority of the content 377 * @param priority priority of the content
376 * @param anonymity anonymity-level for the content 378 * @param anonymity anonymity-level for the content
379 * @param replication replication-level for the content
377 * @param expiration expiration time for the content 380 * @param expiration expiration time for the content
378 * @param uid unique identifier for the datum; 381 * @param uid unique identifier for the datum;
379 * maybe 0 if no unique identifier is available 382 * maybe 0 if no unique identifier is available
@@ -389,6 +392,7 @@ quota_processor (void *cls,
389 enum GNUNET_BLOCK_Type type, 392 enum GNUNET_BLOCK_Type type,
390 uint32_t priority, 393 uint32_t priority,
391 uint32_t anonymity, 394 uint32_t anonymity,
395 uint32_t replication,
392 struct GNUNET_TIME_Absolute expiration, 396 struct GNUNET_TIME_Absolute expiration,
393 uint64_t uid) 397 uint64_t uid)
394{ 398{
@@ -495,6 +499,7 @@ transmit_status (struct GNUNET_SERVICE_Client *client,
495 * @param type type of the content 499 * @param type type of the content
496 * @param priority priority of the content 500 * @param priority priority of the content
497 * @param anonymity anonymity-level for the content 501 * @param anonymity anonymity-level for the content
502 * @param replication replication-level for the content
498 * @param expiration expiration time for the content 503 * @param expiration expiration time for the content
499 * @param uid unique identifier for the datum; 504 * @param uid unique identifier for the datum;
500 * maybe 0 if no unique identifier is available 505 * maybe 0 if no unique identifier is available
@@ -509,6 +514,7 @@ transmit_item (void *cls,
509 enum GNUNET_BLOCK_Type type, 514 enum GNUNET_BLOCK_Type type,
510 uint32_t priority, 515 uint32_t priority,
511 uint32_t anonymity, 516 uint32_t anonymity,
517 uint32_t replication,
512 struct GNUNET_TIME_Absolute expiration, 518 struct GNUNET_TIME_Absolute expiration,
513 uint64_t uid) 519 uint64_t uid)
514{ 520{
@@ -538,8 +544,7 @@ transmit_item (void *cls,
538 dm->type = htonl (type); 544 dm->type = htonl (type);
539 dm->priority = htonl (priority); 545 dm->priority = htonl (priority);
540 dm->anonymity = htonl (anonymity); 546 dm->anonymity = htonl (anonymity);
541 dm->replication = htonl (0); 547 dm->replication = htonl (replication);
542 dm->reserved = htonl (0);
543 dm->expiration = GNUNET_TIME_absolute_hton (expiration); 548 dm->expiration = GNUNET_TIME_absolute_hton (expiration);
544 dm->uid = GNUNET_htonll (uid); 549 dm->uid = GNUNET_htonll (uid);
545 dm->key = *key; 550 dm->key = *key;
@@ -848,6 +853,7 @@ check_present_continuation (void *cls,
848 * @param type type of the content 853 * @param type type of the content
849 * @param priority priority of the content 854 * @param priority priority of the content
850 * @param anonymity anonymity-level for the content 855 * @param anonymity anonymity-level for the content
856 * @param replication replication-level for the content
851 * @param expiration expiration time for the content 857 * @param expiration expiration time for the content
852 * @param uid unique identifier for the datum; 858 * @param uid unique identifier for the datum;
853 * maybe 0 if no unique identifier is available 859 * maybe 0 if no unique identifier is available
@@ -856,13 +862,14 @@ check_present_continuation (void *cls,
856 */ 862 */
857static int 863static int
858check_present (void *cls, 864check_present (void *cls,
859 const struct GNUNET_HashCode *key, 865 const struct GNUNET_HashCode *key,
860 uint32_t size, 866 uint32_t size,
861 const void *data, 867 const void *data,
862 enum GNUNET_BLOCK_Type type, 868 enum GNUNET_BLOCK_Type type,
863 uint32_t priority, 869 uint32_t priority,
864 uint32_t anonymity, 870 uint32_t anonymity,
865 struct GNUNET_TIME_Absolute expiration, 871 uint32_t replication,
872 struct GNUNET_TIME_Absolute expiration,
866 uint64_t uid) 873 uint64_t uid)
867{ 874{
868 struct PutContext *pc = cls; 875 struct PutContext *pc = cls;
@@ -883,16 +890,17 @@ check_present (void *cls,
883 { 890 {
884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
885 "Result already present in datastore\n"); 892 "Result already present in datastore\n");
886 /* FIXME: change API to allow increasing 'replication' counter */ 893 if ( (ntohl (dm->priority) > 0) ||
887 if ((ntohl (dm->priority) > 0) || 894 (ntohl (dm->replication) > 0) ||
888 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us > 895 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us >
889 expiration.abs_value_us)) 896 expiration.abs_value_us) )
890 plugin->api->update (plugin->api->cls, 897 plugin->api->update (plugin->api->cls,
891 uid, 898 uid,
892 ntohl (dm->priority), 899 ntohl (dm->priority),
900 ntohl (dm->replication),
893 GNUNET_TIME_absolute_ntoh (dm->expiration), 901 GNUNET_TIME_absolute_ntoh (dm->expiration),
894 &check_present_continuation, 902 &check_present_continuation,
895 pc->client); 903 pc->client);
896 else 904 else
897 { 905 {
898 transmit_status (pc->client, 906 transmit_status (pc->client,
@@ -1064,7 +1072,7 @@ handle_get_key (void *cls,
1064 1, 1072 1,
1065 GNUNET_NO); 1073 GNUNET_NO);
1066 transmit_item (client, 1074 transmit_item (client,
1067 NULL, 0, NULL, 0, 0, 0, 1075 NULL, 0, NULL, 0, 0, 0, 0,
1068 GNUNET_TIME_UNIT_ZERO_ABS, 1076 GNUNET_TIME_UNIT_ZERO_ABS,
1069 0); 1077 0);
1070 GNUNET_SERVICE_client_continue (client); 1078 GNUNET_SERVICE_client_continue (client);
@@ -1153,6 +1161,7 @@ handle_get_zero_anonymity (void *cls,
1153 * @param type type of the content 1161 * @param type type of the content
1154 * @param priority priority of the content 1162 * @param priority priority of the content
1155 * @param anonymity anonymity-level for the content 1163 * @param anonymity anonymity-level for the content
1164 * @param replication replication-level for the content
1156 * @param expiration expiration time for the content 1165 * @param expiration expiration time for the content
1157 * @param uid unique identifier for the datum 1166 * @param uid unique identifier for the datum
1158 * @return #GNUNET_OK to keep the item 1167 * @return #GNUNET_OK to keep the item
@@ -1166,6 +1175,7 @@ remove_callback (void *cls,
1166 enum GNUNET_BLOCK_Type type, 1175 enum GNUNET_BLOCK_Type type,
1167 uint32_t priority, 1176 uint32_t priority,
1168 uint32_t anonymity, 1177 uint32_t anonymity,
1178 uint32_t replication,
1169 struct GNUNET_TIME_Absolute expiration, 1179 struct GNUNET_TIME_Absolute expiration,
1170 uint64_t uid) 1180 uint64_t uid)
1171{ 1181{
diff --git a/src/datastore/plugin_datastore_heap.c b/src/datastore/plugin_datastore_heap.c
index e15cacb5b..d04c1cf60 100644
--- a/src/datastore/plugin_datastore_heap.c
+++ b/src/datastore/plugin_datastore_heap.c
@@ -439,7 +439,7 @@ heap_plugin_get_key (void *cls, uint64_t next_uid, bool random,
439 } 439 }
440 if (NULL == gc.value) 440 if (NULL == gc.value)
441 { 441 {
442 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 442 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
443 return; 443 return;
444 } 444 }
445 if (GNUNET_NO == 445 if (GNUNET_NO ==
@@ -450,6 +450,7 @@ heap_plugin_get_key (void *cls, uint64_t next_uid, bool random,
450 gc.value->type, 450 gc.value->type,
451 gc.value->priority, 451 gc.value->priority,
452 gc.value->anonymity, 452 gc.value->anonymity,
453 gc.value->replication,
453 gc.value->expiration, 454 gc.value->expiration,
454 (uint64_t) (intptr_t) gc.value)) 455 (uint64_t) (intptr_t) gc.value))
455 { 456 {
@@ -480,8 +481,7 @@ heap_plugin_get_replication (void *cls,
480 value = GNUNET_CONTAINER_heap_remove_root (plugin->by_replication); 481 value = GNUNET_CONTAINER_heap_remove_root (plugin->by_replication);
481 if (NULL == value) 482 if (NULL == value)
482 { 483 {
483 proc (proc_cls, 484 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
484 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
485 return; 485 return;
486 } 486 }
487 if (value->replication > 0) 487 if (value->replication > 0)
@@ -501,14 +501,15 @@ heap_plugin_get_replication (void *cls,
501 } 501 }
502 if (GNUNET_NO == 502 if (GNUNET_NO ==
503 proc (proc_cls, 503 proc (proc_cls,
504 &value->key, 504 &value->key,
505 value->size, 505 value->size,
506 &value[1], 506 &value[1],
507 value->type, 507 value->type,
508 value->priority, 508 value->priority,
509 value->anonymity, 509 value->anonymity,
510 value->expiration, 510 value->replication,
511 (uint64_t) (intptr_t) value)) 511 value->expiration,
512 (uint64_t) (intptr_t) value))
512 delete_value (plugin, value); 513 delete_value (plugin, value);
513} 514}
514 515
@@ -531,35 +532,36 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
531 value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration); 532 value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration);
532 if (NULL == value) 533 if (NULL == value)
533 { 534 {
534 proc (proc_cls, 535 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
535 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
536 return; 536 return;
537 } 537 }
538 if (GNUNET_NO == 538 if (GNUNET_NO ==
539 proc (proc_cls, 539 proc (proc_cls,
540 &value->key, 540 &value->key,
541 value->size, 541 value->size,
542 &value[1], 542 &value[1],
543 value->type, 543 value->type,
544 value->priority, 544 value->priority,
545 value->anonymity, 545 value->anonymity,
546 value->expiration, 546 value->replication,
547 (uint64_t) (intptr_t) value)) 547 value->expiration,
548 (uint64_t) (intptr_t) value))
548 delete_value (plugin, value); 549 delete_value (plugin, value);
549} 550}
550 551
551 552
552/** 553/**
553 * Update the priority for a particular key in the datastore. If 554 * Update the priority, replication and expiration for a particular
554 * the expiration time in value is different than the time found in 555 * unique ID in the datastore. If the expiration time in value is
555 * the datastore, the higher value should be kept. For the 556 * different than the time found in the datastore, the higher value
556 * anonymity level, the lower value is to be used. The specified 557 * should be kept. The specified priority and replication is added
557 * priority should be added to the existing priority, ignoring the 558 * to the existing value.
558 * priority in value.
559 * 559 *
560 * @param cls our `struct Plugin *` 560 * @param cls our `struct Plugin *`
561 * @param uid unique identifier of the datum 561 * @param uid unique identifier of the datum
562 * @param delta by how much should the priority 562 * @param priority by how much should the priority
563 * change?
564 * @param replication by how much should the replication
563 * change? 565 * change?
564 * @param expire new expiration time should be the 566 * @param expire new expiration time should be the
565 * MAX of any existing expiration time and 567 * MAX of any existing expiration time and
@@ -569,11 +571,12 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
569 */ 571 */
570static void 572static void
571heap_plugin_update (void *cls, 573heap_plugin_update (void *cls,
572 uint64_t uid, 574 uint64_t uid,
573 uint32_t delta, 575 uint32_t priority,
574 struct GNUNET_TIME_Absolute expire, 576 uint32_t replication,
575 PluginUpdateCont cont, 577 struct GNUNET_TIME_Absolute expire,
576 void *cont_cls) 578 PluginUpdateCont cont,
579 void *cont_cls)
577{ 580{
578 struct Value *value; 581 struct Value *value;
579 582
@@ -585,11 +588,15 @@ heap_plugin_update (void *cls,
585 GNUNET_CONTAINER_heap_update_cost (value->expire_heap, 588 GNUNET_CONTAINER_heap_update_cost (value->expire_heap,
586 expire.abs_value_us); 589 expire.abs_value_us);
587 } 590 }
588 /* Saturating add, don't overflow */ 591 /* Saturating adds, don't overflow */
589 if (value->priority > UINT32_MAX - delta) 592 if (value->priority > UINT32_MAX - priority)
590 value->priority = UINT32_MAX; 593 value->priority = UINT32_MAX;
591 else 594 else
592 value->priority += delta; 595 value->priority += priority;
596 if (value->replication > UINT32_MAX - replication)
597 value->replication = UINT32_MAX;
598 else
599 value->replication += replication;
593 cont (cont_cls, GNUNET_OK, NULL); 600 cont (cont_cls, GNUNET_OK, NULL);
594} 601}
595 602
@@ -631,20 +638,20 @@ heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
631 } 638 }
632 if (NULL == value) 639 if (NULL == value)
633 { 640 {
634 proc (proc_cls, 641 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
635 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
636 return; 642 return;
637 } 643 }
638 if (GNUNET_NO == 644 if (GNUNET_NO ==
639 proc (proc_cls, 645 proc (proc_cls,
640 &value->key, 646 &value->key,
641 value->size, 647 value->size,
642 &value[1], 648 &value[1],
643 value->type, 649 value->type,
644 value->priority, 650 value->priority,
645 value->anonymity, 651 value->anonymity,
646 value->expiration, 652 value->replication,
647 (uint64_t) (intptr_t) value)) 653 value->expiration,
654 (uint64_t) (intptr_t) value))
648 delete_value (plugin, value); 655 delete_value (plugin, value);
649} 656}
650 657
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index 5ae4485cb..6f2a76499 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -150,22 +150,56 @@ struct Plugin
150#define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?" 150#define DELETE_ENTRY_BY_UID "DELETE FROM gn090 WHERE uid=?"
151 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid; 151 struct GNUNET_MYSQL_StatementHandle *delete_entry_by_uid;
152 152
153#define SELECT_ENTRY "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 WHERE uid >= ? AND (rvalue >= ? OR 0 = ?) ORDER BY uid LIMIT 1" 153#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, uid"
154
155#define SELECT_ENTRY "SELECT " RESULT_COLUMNS " FROM gn090 "\
156 "WHERE uid >= ? AND "\
157 "(rvalue >= ? OR 0 = ?) "\
158 "ORDER BY uid LIMIT 1"
154 struct GNUNET_MYSQL_StatementHandle *select_entry; 159 struct GNUNET_MYSQL_StatementHandle *select_entry;
155 160
156#define SELECT_ENTRY_BY_HASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash) WHERE hash=? AND uid >= ? AND (rvalue >= ? OR 0 = ?) ORDER BY uid LIMIT 1" 161#define SELECT_ENTRY_BY_HASH "SELECT " RESULT_COLUMNS " FROM gn090 "\
162 "FORCE INDEX (idx_hash) "\
163 "WHERE hash=? AND "\
164 "uid >= ? AND "\
165 "(rvalue >= ? OR 0 = ?) "\
166 "ORDER BY uid LIMIT 1"
157 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash; 167 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash;
158 168
159#define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND uid >= ? AND (rvalue >= ? OR 0 = ?) ORDER BY uid LIMIT 1" 169#define SELECT_ENTRY_BY_HASH_AND_VHASH "SELECT " RESULT_COLUMNS " FROM gn090 "\
170 "FORCE INDEX (idx_hash_vhash) "\
171 "WHERE hash = ? AND "\
172 "vhash = ? AND "\
173 "uid >= ? AND "\
174 "(rvalue >= ? OR 0 = ?) "\
175 "ORDER BY uid LIMIT 1"
160 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash; 176 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_vhash;
161 177
162#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_type_uid) WHERE hash=? AND type=? AND uid >= ? AND (rvalue >= ? OR 0 = ?) ORDER BY uid LIMIT 1" 178#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT " RESULT_COLUMNS " FROM gn090 "\
179 "FORCE INDEX (idx_hash_type_uid) "\
180 "WHERE hash = ? AND "\
181 "type = ? AND "\
182 "uid >= ? AND "\
183 "(rvalue >= ? OR 0 = ?) "\
184 "ORDER BY uid LIMIT 1"
163 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type; 185 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_and_type;
164 186
165#define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_hash_vhash) WHERE hash=? AND vhash=? AND type=? AND uid >= ? AND (rvalue >= ? OR 0 = ?) ORDER BY uid LIMIT 1" 187#define SELECT_ENTRY_BY_HASH_VHASH_AND_TYPE "SELECT " RESULT_COLUMNS " "\
188 "FROM gn090 "\
189 "FORCE INDEX (idx_hash_vhash) "\
190 "WHERE hash = ? AND "\
191 "vhash = ? AND "\
192 "type = ? AND "\
193 "uid >= ? AND "\
194 "(rvalue >= ? OR 0 = ?) "\
195 "ORDER BY uid LIMIT 1"
166 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type; 196 struct GNUNET_MYSQL_StatementHandle *select_entry_by_hash_vhash_and_type;
167 197
168#define UPDATE_ENTRY "UPDATE gn090 SET prio=prio+?,expire=IF(expire>=?,expire,?) WHERE uid=?" 198#define UPDATE_ENTRY "UPDATE gn090 SET "\
199 "prio = prio + ?, "\
200 "repl = repl + ?, "\
201 "expire = IF(expire >= ?, expire, ?) "\
202 "WHERE uid = ?"
169 struct GNUNET_MYSQL_StatementHandle *update_entry; 203 struct GNUNET_MYSQL_StatementHandle *update_entry;
170 204
171#define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?" 205#define DEC_REPL "UPDATE gn090 SET repl=GREATEST (1, repl) - 1 WHERE uid=?"
@@ -174,20 +208,27 @@ struct Plugin
174#define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090" 208#define SELECT_SIZE "SELECT SUM(LENGTH(value)+256) FROM gn090"
175 struct GNUNET_MYSQL_StatementHandle *get_size; 209 struct GNUNET_MYSQL_StatementHandle *get_size;
176 210
177#define SELECT_IT_NON_ANONYMOUS "SELECT type,prio,anonLevel,expire,hash,value,uid "\ 211#define SELECT_IT_NON_ANONYMOUS "SELECT " RESULT_COLUMNS " FROM gn090 "\
178 "FROM gn090 FORCE INDEX (idx_anonLevel_type_rvalue) "\ 212 "FORCE INDEX (idx_anonLevel_type_rvalue) "\
179 "WHERE anonLevel=0 AND type=? AND uid >= ? "\ 213 "WHERE anonLevel=0 AND "\
180 "ORDER BY uid LIMIT 1" 214 "type=? AND "\
215 "uid >= ? "\
216 "ORDER BY uid LIMIT 1"
181 struct GNUNET_MYSQL_StatementHandle *zero_iter; 217 struct GNUNET_MYSQL_StatementHandle *zero_iter;
182 218
183#define SELECT_IT_EXPIRATION "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_expire) WHERE expire < ? ORDER BY expire ASC LIMIT 1" 219#define SELECT_IT_EXPIRATION "SELECT " RESULT_COLUMNS " FROM gn090 "\
220 "FORCE INDEX (idx_expire) "\
221 "WHERE expire < ? "\
222 "ORDER BY expire ASC LIMIT 1"
184 struct GNUNET_MYSQL_StatementHandle *select_expiration; 223 struct GNUNET_MYSQL_StatementHandle *select_expiration;
185 224
186#define SELECT_IT_PRIORITY "SELECT type,prio,anonLevel,expire,hash,value,uid FROM gn090 FORCE INDEX (idx_prio) ORDER BY prio ASC LIMIT 1" 225#define SELECT_IT_PRIORITY "SELECT " RESULT_COLUMNS " FROM gn090 "\
226 "FORCE INDEX (idx_prio) "\
227 "ORDER BY prio ASC LIMIT 1"
187 struct GNUNET_MYSQL_StatementHandle *select_priority; 228 struct GNUNET_MYSQL_StatementHandle *select_priority;
188 229
189#define SELECT_IT_REPLICATION "SELECT type,prio,anonLevel,expire,hash,value,uid "\ 230#define SELECT_IT_REPLICATION "SELECT " RESULT_COLUMNS " FROM gn090 "\
190 "FROM gn090 FORCE INDEX (idx_repl_rvalue) "\ 231 "FORCE INDEX (idx_repl_rvalue) "\
191 "WHERE repl=? AND "\ 232 "WHERE repl=? AND "\
192 " (rvalue>=? OR"\ 233 " (rvalue>=? OR"\
193 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\ 234 " NOT EXISTS (SELECT 1 FROM gn090 FORCE INDEX (idx_repl_rvalue) WHERE repl=? AND rvalue>=?)) "\
@@ -371,19 +412,17 @@ mysql_plugin_put (void *cls,
371 412
372 413
373/** 414/**
374 * Update the priority for a particular key in the datastore. If 415 * Update the priority, replication and expiration for a particular
375 * the expiration time in value is different than the time found in 416 * unique ID in the datastore. If the expiration time in value is
376 * the datastore, the higher value should be kept. For the 417 * different than the time found in the datastore, the higher value
377 * anonymity level, the lower value is to be used. The specified 418 * should be kept. The specified priority and replication is added
378 * priority should be added to the existing priority, ignoring the 419 * to the existing value.
379 * priority in value.
380 *
381 * Note that it is possible for multiple values to match this put.
382 * In that case, all of the respective values are updated.
383 * 420 *
384 * @param cls our "struct Plugin*" 421 * @param cls our "struct Plugin*"
385 * @param uid unique identifier of the datum 422 * @param uid unique identifier of the datum
386 * @param delta by how much should the priority 423 * @param priority by how much should the priority
424 * change?
425 * @param replication by how much should the replication
387 * change? 426 * change?
388 * @param expire new expiration time should be the 427 * @param expire new expiration time should be the
389 * MAX of any existing expiration time and 428 * MAX of any existing expiration time and
@@ -394,7 +433,8 @@ mysql_plugin_put (void *cls,
394static void 433static void
395mysql_plugin_update (void *cls, 434mysql_plugin_update (void *cls,
396 uint64_t uid, 435 uint64_t uid,
397 uint32_t delta, 436 uint32_t priority,
437 uint32_t replication,
398 struct GNUNET_TIME_Absolute expire, 438 struct GNUNET_TIME_Absolute expire,
399 PluginUpdateCont cont, 439 PluginUpdateCont cont,
400 void *cont_cls) 440 void *cont_cls)
@@ -404,13 +444,15 @@ mysql_plugin_update (void *cls,
404 int ret; 444 int ret;
405 445
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
407 "Updating value %llu adding %d to priority and maxing exp at %s\n", 447 "Updating value %llu adding %d to priority %d to replication and maxing exp at %s\n",
408 (unsigned long long) uid, 448 (unsigned long long) uid,
409 delta, 449 priority,
410 GNUNET_STRINGS_absolute_time_to_string (expire)); 450 replication,
451 GNUNET_STRINGS_absolute_time_to_string (expire));
411 452
412 struct GNUNET_MY_QueryParam params_update[] = { 453 struct GNUNET_MY_QueryParam params_update[] = {
413 GNUNET_MY_query_param_uint32 (&delta), 454 GNUNET_MY_query_param_uint32 (&priority),
455 GNUNET_MY_query_param_uint32 (&replication),
414 GNUNET_MY_query_param_uint64 (&lexpire), 456 GNUNET_MY_query_param_uint64 (&lexpire),
415 GNUNET_MY_query_param_uint64 (&lexpire), 457 GNUNET_MY_query_param_uint64 (&lexpire),
416 GNUNET_MY_query_param_uint64 (&uid), 458 GNUNET_MY_query_param_uint64 (&uid),
@@ -457,6 +499,7 @@ execute_select (struct Plugin *plugin,
457 struct GNUNET_MY_QueryParam *params_select) 499 struct GNUNET_MY_QueryParam *params_select)
458{ 500{
459 int ret; 501 int ret;
502 uint32_t replication;
460 uint32_t type; 503 uint32_t type;
461 uint32_t priority; 504 uint32_t priority;
462 uint32_t anonymity; 505 uint32_t anonymity;
@@ -466,6 +509,7 @@ execute_select (struct Plugin *plugin,
466 struct GNUNET_HashCode key; 509 struct GNUNET_HashCode key;
467 struct GNUNET_TIME_Absolute expiration; 510 struct GNUNET_TIME_Absolute expiration;
468 struct GNUNET_MY_ResultSpec results_select[] = { 511 struct GNUNET_MY_ResultSpec results_select[] = {
512 GNUNET_MY_result_spec_uint32 (&replication),
469 GNUNET_MY_result_spec_uint32 (&type), 513 GNUNET_MY_result_spec_uint32 (&type),
470 GNUNET_MY_result_spec_uint32 (&priority), 514 GNUNET_MY_result_spec_uint32 (&priority),
471 GNUNET_MY_result_spec_uint32 (&anonymity), 515 GNUNET_MY_result_spec_uint32 (&anonymity),
@@ -482,7 +526,7 @@ execute_select (struct Plugin *plugin,
482 if (GNUNET_OK != ret) 526 if (GNUNET_OK != ret)
483 { 527 {
484 proc (proc_cls, 528 proc (proc_cls,
485 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 529 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
486 return; 530 return;
487 } 531 }
488 532
@@ -491,7 +535,7 @@ execute_select (struct Plugin *plugin,
491 if (GNUNET_OK != ret) 535 if (GNUNET_OK != ret)
492 { 536 {
493 proc (proc_cls, 537 proc (proc_cls,
494 NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 538 NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
495 return; 539 return;
496 } 540 }
497 541
@@ -513,6 +557,7 @@ execute_select (struct Plugin *plugin,
513 type, 557 type,
514 priority, 558 priority,
515 anonymity, 559 anonymity,
560 replication,
516 expiration, 561 expiration,
517 uid); 562 uid);
518 GNUNET_MY_cleanup_result (results_select); 563 GNUNET_MY_cleanup_result (results_select);
@@ -729,6 +774,7 @@ struct ReplCtx
729 * @param type type of the content 774 * @param type type of the content
730 * @param priority priority of the content 775 * @param priority priority of the content
731 * @param anonymity anonymity-level for the content 776 * @param anonymity anonymity-level for the content
777 * @param replication replication-level for the content
732 * @param expiration expiration time for the content 778 * @param expiration expiration time for the content
733 * @param uid unique identifier for the datum; 779 * @param uid unique identifier for the datum;
734 * maybe 0 if no unique identifier is available 780 * maybe 0 if no unique identifier is available
@@ -744,6 +790,7 @@ repl_proc (void *cls,
744 enum GNUNET_BLOCK_Type type, 790 enum GNUNET_BLOCK_Type type,
745 uint32_t priority, 791 uint32_t priority,
746 uint32_t anonymity, 792 uint32_t anonymity,
793 uint32_t replication,
747 struct GNUNET_TIME_Absolute expiration, 794 struct GNUNET_TIME_Absolute expiration,
748 uint64_t uid) 795 uint64_t uid)
749{ 796{
@@ -759,6 +806,7 @@ repl_proc (void *cls,
759 type, 806 type,
760 priority, 807 priority,
761 anonymity, 808 anonymity,
809 replication,
762 expiration, 810 expiration,
763 uid); 811 uid);
764 if (NULL != key) 812 if (NULL != key)
@@ -826,7 +874,7 @@ mysql_plugin_get_replication (void *cls,
826 plugin->max_repl, 874 plugin->max_repl,
827 params_get)) 875 params_get))
828 { 876 {
829 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 877 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
830 return; 878 return;
831 } 879 }
832 880
@@ -834,7 +882,7 @@ mysql_plugin_get_replication (void *cls,
834 GNUNET_MY_extract_result (plugin->max_repl, 882 GNUNET_MY_extract_result (plugin->max_repl,
835 results_get)) 883 results_get))
836 { 884 {
837 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 885 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
838 return; 886 return;
839 } 887 }
840 GNUNET_break (GNUNET_NO == 888 GNUNET_break (GNUNET_NO ==
@@ -976,6 +1024,7 @@ struct ExpiCtx
976 * @param type type of the content 1024 * @param type type of the content
977 * @param priority priority of the content 1025 * @param priority priority of the content
978 * @param anonymity anonymity-level for the content 1026 * @param anonymity anonymity-level for the content
1027 * @param replication replication-level for the content
979 * @param expiration expiration time for the content 1028 * @param expiration expiration time for the content
980 * @param uid unique identifier for the datum; 1029 * @param uid unique identifier for the datum;
981 * maybe 0 if no unique identifier is available 1030 * maybe 0 if no unique identifier is available
@@ -991,6 +1040,7 @@ expi_proc (void *cls,
991 enum GNUNET_BLOCK_Type type, 1040 enum GNUNET_BLOCK_Type type,
992 uint32_t priority, 1041 uint32_t priority,
993 uint32_t anonymity, 1042 uint32_t anonymity,
1043 uint32_t replication,
994 struct GNUNET_TIME_Absolute expiration, 1044 struct GNUNET_TIME_Absolute expiration,
995 uint64_t uid) 1045 uint64_t uid)
996{ 1046{
@@ -1016,6 +1066,7 @@ expi_proc (void *cls,
1016 type, 1066 type,
1017 priority, 1067 priority,
1018 anonymity, 1068 anonymity,
1069 replication,
1019 expiration, 1070 expiration,
1020 uid); 1071 uid);
1021} 1072}
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 0376ebb6c..87a7acbdc 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -176,9 +176,10 @@ init_connection (struct Plugin *plugin)
176 return GNUNET_SYSERR; 176 return GNUNET_SYSERR;
177 } 177 }
178 PQclear (ret); 178 PQclear (ret);
179#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, oid"
179 if ((GNUNET_OK != 180 if ((GNUNET_OK !=
180 GNUNET_POSTGRES_prepare (plugin->dbh, "get", 181 GNUNET_POSTGRES_prepare (plugin->dbh, "get",
181 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 182 "SELECT " RESULT_COLUMNS " FROM gn090 "
182 "WHERE oid >= $1::bigint AND " 183 "WHERE oid >= $1::bigint AND "
183 "(rvalue >= $2 OR 0 = $3::smallint) AND " 184 "(rvalue >= $2 OR 0 = $3::smallint) AND "
184 "(hash = $4 OR 0 = $5::smallint) AND " 185 "(hash = $4 OR 0 = $5::smallint) AND "
@@ -191,28 +192,33 @@ init_connection (struct Plugin *plugin)
191 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", 9)) || 192 "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", 9)) ||
192 (GNUNET_OK != 193 (GNUNET_OK !=
193 GNUNET_POSTGRES_prepare (plugin->dbh, "update", 194 GNUNET_POSTGRES_prepare (plugin->dbh, "update",
194 "UPDATE gn090 SET prio = prio + $1, expire = CASE WHEN expire < $2 THEN $2 ELSE expire END " 195 "UPDATE gn090 "
195 "WHERE oid = $3", 3)) || 196 "SET prio = prio + $1, "
197 "repl = repl + $2, "
198 "expire = CASE WHEN expire < $3 THEN $3 ELSE expire END "
199 "WHERE oid = $4", 4)) ||
196 (GNUNET_OK != 200 (GNUNET_OK !=
197 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", 201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl",
198 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " 202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
199 "WHERE oid = $1", 1)) || 203 "WHERE oid = $1", 1)) ||
200 (GNUNET_OK != 204 (GNUNET_OK !=
201 GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous", 205 GNUNET_POSTGRES_prepare (plugin->dbh, "select_non_anonymous",
202 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 206 "SELECT " RESULT_COLUMNS " FROM gn090 "
203 "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint " 207 "WHERE anonLevel = 0 AND type = $1 AND oid >= $2::bigint "
204 "ORDER BY oid ASC LIMIT 1", 208 "ORDER BY oid ASC LIMIT 1",
205 2)) || 209 2)) ||
206 (GNUNET_OK != 210 (GNUNET_OK !=
207 GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order", 211 GNUNET_POSTGRES_prepare (plugin->dbh, "select_expiration_order",
208 "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 212 "(SELECT " RESULT_COLUMNS " FROM gn090 "
209 "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) " "UNION " 213 "WHERE expire < $1 ORDER BY prio ASC LIMIT 1) "
210 "(SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 214 "UNION "
211 "ORDER BY prio ASC LIMIT 1) " "ORDER BY expire ASC LIMIT 1", 215 "(SELECT " RESULT_COLUMNS " FROM gn090 "
216 "ORDER BY prio ASC LIMIT 1) "
217 "ORDER BY expire ASC LIMIT 1",
212 1)) || 218 1)) ||
213 (GNUNET_OK != 219 (GNUNET_OK !=
214 GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order", 220 GNUNET_POSTGRES_prepare (plugin->dbh, "select_replication_order",
215 "SELECT type, prio, anonLevel, expire, hash, value, oid FROM gn090 " 221 "SELECT " RESULT_COLUMNS " FROM gn090 "
216 "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) || 222 "ORDER BY repl DESC,RANDOM() LIMIT 1", 0)) ||
217 (GNUNET_OK != 223 (GNUNET_OK !=
218 GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) || 224 GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090 " "WHERE oid=$1", 1)) ||
@@ -371,19 +377,21 @@ process_result (struct Plugin *plugin,
371 uint32_t rowid; 377 uint32_t rowid;
372 uint32_t utype; 378 uint32_t utype;
373 uint32_t anonymity; 379 uint32_t anonymity;
380 uint32_t replication;
374 uint32_t priority; 381 uint32_t priority;
375 size_t size; 382 size_t size;
376 void *data; 383 void *data;
377 struct GNUNET_TIME_Absolute expiration_time; 384 struct GNUNET_TIME_Absolute expiration_time;
378 struct GNUNET_HashCode key; 385 struct GNUNET_HashCode key;
379 struct GNUNET_PQ_ResultSpec rs[] = { 386 struct GNUNET_PQ_ResultSpec rs[] = {
387 GNUNET_PQ_result_spec_uint32 ("repl", &replication),
380 GNUNET_PQ_result_spec_uint32 ("type", &utype), 388 GNUNET_PQ_result_spec_uint32 ("type", &utype),
381 GNUNET_PQ_result_spec_uint32 ("prio", &priority), 389 GNUNET_PQ_result_spec_uint32 ("prio", &priority),
382 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity), 390 GNUNET_PQ_result_spec_uint32 ("anonLevel", &anonymity),
383 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
384 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time), 391 GNUNET_PQ_result_spec_absolute_time ("expire", &expiration_time),
385 GNUNET_PQ_result_spec_auto_from_type ("hash", &key), 392 GNUNET_PQ_result_spec_auto_from_type ("hash", &key),
386 GNUNET_PQ_result_spec_variable_size ("value", &data, &size), 393 GNUNET_PQ_result_spec_variable_size ("value", &data, &size),
394 GNUNET_PQ_result_spec_uint32 ("oid", &rowid),
387 GNUNET_PQ_result_spec_end 395 GNUNET_PQ_result_spec_end
388 }; 396 };
389 397
@@ -398,8 +406,7 @@ process_result (struct Plugin *plugin,
398 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 406 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
399 "datastore-postgres", 407 "datastore-postgres",
400 "Ending iteration (postgres error)\n"); 408 "Ending iteration (postgres error)\n");
401 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 409 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
402 GNUNET_TIME_UNIT_ZERO_ABS, 0);
403 return; 410 return;
404 } 411 }
405 412
@@ -409,16 +416,14 @@ process_result (struct Plugin *plugin,
409 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 416 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
410 "datastore-postgres", 417 "datastore-postgres",
411 "Ending iteration (no more results)\n"); 418 "Ending iteration (no more results)\n");
412 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 419 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
413 GNUNET_TIME_UNIT_ZERO_ABS, 0);
414 PQclear (res); 420 PQclear (res);
415 return; 421 return;
416 } 422 }
417 if (1 != PQntuples (res)) 423 if (1 != PQntuples (res))
418 { 424 {
419 GNUNET_break (0); 425 GNUNET_break (0);
420 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 426 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
421 GNUNET_TIME_UNIT_ZERO_ABS, 0);
422 PQclear (res); 427 PQclear (res);
423 return; 428 return;
424 } 429 }
@@ -432,8 +437,7 @@ process_result (struct Plugin *plugin,
432 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, 437 GNUNET_POSTGRES_delete_by_rowid (plugin->dbh,
433 "delrow", 438 "delrow",
434 rowid); 439 rowid);
435 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 440 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
436 GNUNET_TIME_UNIT_ZERO_ABS, 0);
437 return; 441 return;
438 } 442 }
439 443
@@ -443,14 +447,15 @@ process_result (struct Plugin *plugin,
443 (unsigned int) size, 447 (unsigned int) size,
444 (unsigned int) utype); 448 (unsigned int) utype);
445 iret = proc (proc_cls, 449 iret = proc (proc_cls,
446 &key, 450 &key,
447 size, 451 size,
448 data, 452 data,
449 (enum GNUNET_BLOCK_Type) utype, 453 (enum GNUNET_BLOCK_Type) utype,
450 priority, 454 priority,
451 anonymity, 455 anonymity,
452 expiration_time, 456 replication,
453 rowid); 457 expiration_time,
458 rowid);
454 PQclear (res); 459 PQclear (res);
455 if (iret == GNUNET_NO) 460 if (iret == GNUNET_NO)
456 { 461 {
@@ -620,6 +625,7 @@ struct ReplCtx
620 * @param type type of the content 625 * @param type type of the content
621 * @param priority priority of the content 626 * @param priority priority of the content
622 * @param anonymity anonymity-level for the content 627 * @param anonymity anonymity-level for the content
628 * @param replication replication-level for the content
623 * @param expiration expiration time for the content 629 * @param expiration expiration time for the content
624 * @param uid unique identifier for the datum; 630 * @param uid unique identifier for the datum;
625 * maybe 0 if no unique identifier is available 631 * maybe 0 if no unique identifier is available
@@ -630,13 +636,14 @@ struct ReplCtx
630 */ 636 */
631static int 637static int
632repl_proc (void *cls, 638repl_proc (void *cls,
633 const struct GNUNET_HashCode *key, 639 const struct GNUNET_HashCode *key,
634 uint32_t size, 640 uint32_t size,
635 const void *data, 641 const void *data,
636 enum GNUNET_BLOCK_Type type, 642 enum GNUNET_BLOCK_Type type,
637 uint32_t priority, 643 uint32_t priority,
638 uint32_t anonymity, 644 uint32_t anonymity,
639 struct GNUNET_TIME_Absolute expiration, 645 uint32_t replication,
646 struct GNUNET_TIME_Absolute expiration,
640 uint64_t uid) 647 uint64_t uid)
641{ 648{
642 struct ReplCtx *rc = cls; 649 struct ReplCtx *rc = cls;
@@ -650,12 +657,15 @@ repl_proc (void *cls,
650 PGresult *qret; 657 PGresult *qret;
651 658
652 ret = rc->proc (rc->proc_cls, 659 ret = rc->proc (rc->proc_cls,
653 key, 660 key,
654 size, data, 661 size,
655 type, 662 data,
656 priority, 663 type,
657 anonymity, 664 priority,
658 expiration, uid); 665 anonymity,
666 replication,
667 expiration,
668 uid);
659 if (NULL == key) 669 if (NULL == key)
660 return ret; 670 return ret;
661 qret = GNUNET_PQ_exec_prepared (plugin->dbh, 671 qret = GNUNET_PQ_exec_prepared (plugin->dbh,
@@ -740,19 +750,17 @@ postgres_plugin_get_expiration (void *cls,
740 750
741 751
742/** 752/**
743 * Update the priority for a particular key in the datastore. If 753 * Update the priority, replication and expiration for a particular
744 * the expiration time in value is different than the time found in 754 * unique ID in the datastore. If the expiration time in value is
745 * the datastore, the higher value should be kept. For the 755 * different than the time found in the datastore, the higher value
746 * anonymity level, the lower value is to be used. The specified 756 * should be kept. The specified priority and replication is added
747 * priority should be added to the existing priority, ignoring the 757 * to the existing value.
748 * priority in value.
749 *
750 * Note that it is possible for multiple values to match this put.
751 * In that case, all of the respective values are updated.
752 * 758 *
753 * @param cls our `struct Plugin *` 759 * @param cls our `struct Plugin *`
754 * @param uid unique identifier of the datum 760 * @param uid unique identifier of the datum
755 * @param delta by how much should the priority 761 * @param priority by how much should the priority
762 * change?
763 * @param replication by how much should the replication
756 * change? 764 * change?
757 * @param expire new expiration time should be the 765 * @param expire new expiration time should be the
758 * MAX of any existing expiration time and 766 * MAX of any existing expiration time and
@@ -762,16 +770,18 @@ postgres_plugin_get_expiration (void *cls,
762 */ 770 */
763static void 771static void
764postgres_plugin_update (void *cls, 772postgres_plugin_update (void *cls,
765 uint64_t uid, 773 uint64_t uid,
766 uint32_t delta, 774 uint32_t priority,
775 uint32_t replication,
767 struct GNUNET_TIME_Absolute expire, 776 struct GNUNET_TIME_Absolute expire,
768 PluginUpdateCont cont, 777 PluginUpdateCont cont,
769 void *cont_cls) 778 void *cont_cls)
770{ 779{
771 struct Plugin *plugin = cls; 780 struct Plugin *plugin = cls;
772 uint32_t oid = (uint32_t) uid; 781 uint32_t oid = (uint32_t) uid;
773 struct GNUNET_PQ_QueryParam params[] = { 782 struct GNUNET_PQ_QueryParam params[] = {
774 GNUNET_PQ_query_param_uint32 (&delta), 783 GNUNET_PQ_query_param_uint32 (&priority),
784 GNUNET_PQ_query_param_uint32 (&replication),
775 GNUNET_PQ_query_param_absolute_time (&expire), 785 GNUNET_PQ_query_param_absolute_time (&expire),
776 GNUNET_PQ_query_param_uint32 (&oid), 786 GNUNET_PQ_query_param_uint32 (&oid),
777 GNUNET_PQ_query_param_end 787 GNUNET_PQ_query_param_end
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 76f791ad4..1f874e190 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -349,10 +349,14 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
349 sqlite3_finalize (stmt); 349 sqlite3_finalize (stmt);
350 create_indices (plugin->dbh); 350 create_indices (plugin->dbh);
351 351
352#define RESULT_COLUMNS "repl, type, prio, anonLevel, expire, hash, value, _ROWID_"
352 if ( (SQLITE_OK != 353 if ( (SQLITE_OK !=
353 sq_prepare (plugin->dbh, 354 sq_prepare (plugin->dbh,
354 "UPDATE gn090 " 355 "UPDATE gn090 "
355 "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?", 356 "SET prio = prio + ?, "
357 "repl = repl + ?, "
358 "expire = MAX(expire, ?) "
359 "WHERE _ROWID_ = ?",
356 &plugin->updPrio)) || 360 &plugin->updPrio)) ||
357 (SQLITE_OK != 361 (SQLITE_OK !=
358 sq_prepare (plugin->dbh, 362 sq_prepare (plugin->dbh,
@@ -360,7 +364,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
360 &plugin->updRepl)) || 364 &plugin->updRepl)) ||
361 (SQLITE_OK != 365 (SQLITE_OK !=
362 sq_prepare (plugin->dbh, 366 sq_prepare (plugin->dbh,
363 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 367 "SELECT " RESULT_COLUMNS " FROM gn090 "
364#if SQLITE_VERSION_NUMBER >= 3007000 368#if SQLITE_VERSION_NUMBER >= 3007000
365 "INDEXED BY idx_repl_rvalue " 369 "INDEXED BY idx_repl_rvalue "
366#endif 370#endif
@@ -382,7 +386,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
382 &plugin->maxRepl)) || 386 &plugin->maxRepl)) ||
383 (SQLITE_OK != 387 (SQLITE_OK !=
384 sq_prepare (plugin->dbh, 388 sq_prepare (plugin->dbh,
385 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 389 "SELECT " RESULT_COLUMNS " FROM gn090 "
386#if SQLITE_VERSION_NUMBER >= 3007000 390#if SQLITE_VERSION_NUMBER >= 3007000
387 "INDEXED BY idx_expire " 391 "INDEXED BY idx_expire "
388#endif 392#endif
@@ -391,7 +395,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
391 &plugin->selExpi)) || 395 &plugin->selExpi)) ||
392 (SQLITE_OK != 396 (SQLITE_OK !=
393 sq_prepare (plugin->dbh, 397 sq_prepare (plugin->dbh,
394 "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 " 398 "SELECT " RESULT_COLUMNS " FROM gn090 "
395#if SQLITE_VERSION_NUMBER >= 3007000 399#if SQLITE_VERSION_NUMBER >= 3007000
396 "INDEXED BY idx_anon_type_hash " 400 "INDEXED BY idx_anon_type_hash "
397#endif 401#endif
@@ -407,7 +411,7 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
407 &plugin->insertContent)) || 411 &plugin->insertContent)) ||
408 (SQLITE_OK != 412 (SQLITE_OK !=
409 sq_prepare (plugin->dbh, 413 sq_prepare (plugin->dbh,
410 "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ FROM gn090 " 414 "SELECT " RESULT_COLUMNS " FROM gn090 "
411 "WHERE _ROWID_ >= ? AND " 415 "WHERE _ROWID_ >= ? AND "
412 "(rvalue >= ? OR 0 = ?) AND " 416 "(rvalue >= ? OR 0 = ?) AND "
413 "(hash = ? OR 0 = ?) AND " 417 "(hash = ? OR 0 = ?) AND "
@@ -642,19 +646,17 @@ sqlite_plugin_put (void *cls,
642 646
643 647
644/** 648/**
645 * Update the priority for a particular key in the datastore. If 649 * Update the priority, replication and expiration for a particular
646 * the expiration time in value is different than the time found in 650 * unique ID in the datastore. If the expiration time in value is
647 * the datastore, the higher value should be kept. For the 651 * different than the time found in the datastore, the higher value
648 * anonymity level, the lower value is to be used. The specified 652 * should be kept. The specified priority and replication is added
649 * priority should be added to the existing priority, ignoring the 653 * to the existing value.
650 * priority in value.
651 *
652 * Note that it is possible for multiple values to match this put.
653 * In that case, all of the respective values are updated.
654 * 654 *
655 * @param cls the plugin context (state for this module) 655 * @param cls the plugin context (state for this module)
656 * @param uid unique identifier of the datum 656 * @param uid unique identifier of the datum
657 * @param delta by how much should the priority 657 * @param priority by how much should the priority
658 * change?
659 * @param replication by how much should the replication
658 * change? 660 * change?
659 * @param expire new expiration time should be the 661 * @param expire new expiration time should be the
660 * MAX of any existing expiration time and 662 * MAX of any existing expiration time and
@@ -665,14 +667,16 @@ sqlite_plugin_put (void *cls,
665static void 667static void
666sqlite_plugin_update (void *cls, 668sqlite_plugin_update (void *cls,
667 uint64_t uid, 669 uint64_t uid,
668 uint32_t delta, 670 uint32_t priority,
671 uint32_t replication,
669 struct GNUNET_TIME_Absolute expire, 672 struct GNUNET_TIME_Absolute expire,
670 PluginUpdateCont cont, 673 PluginUpdateCont cont,
671 void *cont_cls) 674 void *cont_cls)
672{ 675{
673 struct Plugin *plugin = cls; 676 struct Plugin *plugin = cls;
674 struct GNUNET_SQ_QueryParam params[] = { 677 struct GNUNET_SQ_QueryParam params[] = {
675 GNUNET_SQ_query_param_uint32 (&delta), 678 GNUNET_SQ_query_param_uint32 (&priority),
679 GNUNET_SQ_query_param_uint32 (&replication),
676 GNUNET_SQ_query_param_absolute_time (&expire), 680 GNUNET_SQ_query_param_absolute_time (&expire),
677 GNUNET_SQ_query_param_uint64 (&uid), 681 GNUNET_SQ_query_param_uint64 (&uid),
678 GNUNET_SQ_query_param_end 682 GNUNET_SQ_query_param_end
@@ -731,6 +735,7 @@ execute_get (struct Plugin *plugin,
731{ 735{
732 int n; 736 int n;
733 struct GNUNET_TIME_Absolute expiration; 737 struct GNUNET_TIME_Absolute expiration;
738 uint32_t replication;
734 uint32_t type; 739 uint32_t type;
735 uint32_t priority; 740 uint32_t priority;
736 uint32_t anonymity; 741 uint32_t anonymity;
@@ -740,6 +745,7 @@ execute_get (struct Plugin *plugin,
740 struct GNUNET_HashCode key; 745 struct GNUNET_HashCode key;
741 int ret; 746 int ret;
742 struct GNUNET_SQ_ResultSpec rs[] = { 747 struct GNUNET_SQ_ResultSpec rs[] = {
748 GNUNET_SQ_result_spec_uint32 (&replication),
743 GNUNET_SQ_result_spec_uint32 (&type), 749 GNUNET_SQ_result_spec_uint32 (&type),
744 GNUNET_SQ_result_spec_uint32 (&priority), 750 GNUNET_SQ_result_spec_uint32 (&priority),
745 GNUNET_SQ_result_spec_uint32 (&anonymity), 751 GNUNET_SQ_result_spec_uint32 (&anonymity),
@@ -773,6 +779,7 @@ execute_get (struct Plugin *plugin,
773 type, 779 type,
774 priority, 780 priority,
775 anonymity, 781 anonymity,
782 replication,
776 expiration, 783 expiration,
777 rowid); 784 rowid);
778 GNUNET_SQ_cleanup_result (rs); 785 GNUNET_SQ_cleanup_result (rs);
@@ -801,7 +808,7 @@ execute_get (struct Plugin *plugin,
801 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 808 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
802 "sqlite3_reset"); 809 "sqlite3_reset");
803 GNUNET_break (0); 810 GNUNET_break (0);
804 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 811 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
805 database_shutdown (plugin); 812 database_shutdown (plugin);
806 database_setup (plugin->env->cfg, 813 database_setup (plugin->env->cfg,
807 plugin); 814 plugin);
@@ -809,7 +816,7 @@ execute_get (struct Plugin *plugin,
809 } 816 }
810 GNUNET_SQ_reset (plugin->dbh, 817 GNUNET_SQ_reset (plugin->dbh,
811 stmt); 818 stmt);
812 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 819 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
813} 820}
814 821
815 822
@@ -844,7 +851,7 @@ sqlite_plugin_get_zero_anonymity (void *cls,
844 GNUNET_SQ_bind (plugin->selZeroAnon, 851 GNUNET_SQ_bind (plugin->selZeroAnon,
845 params)) 852 params))
846 { 853 {
847 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 854 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
848 return; 855 return;
849 } 856 }
850 execute_get (plugin, plugin->selZeroAnon, proc, proc_cls); 857 execute_get (plugin, plugin->selZeroAnon, proc, proc_cls);
@@ -912,7 +919,7 @@ sqlite_plugin_get_key (void *cls,
912 GNUNET_SQ_bind (plugin->get, 919 GNUNET_SQ_bind (plugin->get,
913 params)) 920 params))
914 { 921 {
915 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 922 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
916 return; 923 return;
917 } 924 }
918 execute_get (plugin, 925 execute_get (plugin,
@@ -962,6 +969,7 @@ struct ReplCtx
962 * @param type type of the content 969 * @param type type of the content
963 * @param priority priority of the content 970 * @param priority priority of the content
964 * @param anonymity anonymity-level for the content 971 * @param anonymity anonymity-level for the content
972 * @param replication replication-level for the content
965 * @param expiration expiration time for the content 973 * @param expiration expiration time for the content
966 * @param uid unique identifier for the datum; 974 * @param uid unique identifier for the datum;
967 * maybe 0 if no unique identifier is available 975 * maybe 0 if no unique identifier is available
@@ -976,6 +984,7 @@ repl_proc (void *cls,
976 enum GNUNET_BLOCK_Type type, 984 enum GNUNET_BLOCK_Type type,
977 uint32_t priority, 985 uint32_t priority,
978 uint32_t anonymity, 986 uint32_t anonymity,
987 uint32_t replication,
979 struct GNUNET_TIME_Absolute expiration, 988 struct GNUNET_TIME_Absolute expiration,
980 uint64_t uid) 989 uint64_t uid)
981{ 990{
@@ -991,6 +1000,7 @@ repl_proc (void *cls,
991 type, 1000 type,
992 priority, 1001 priority,
993 anonymity, 1002 anonymity,
1003 replication,
994 expiration, 1004 expiration,
995 uid); 1005 uid);
996 if (NULL != key) 1006 if (NULL != key)
@@ -1040,7 +1050,7 @@ sqlite_plugin_get_replication (void *cls,
1040 GNUNET_SQ_reset (plugin->dbh, 1050 GNUNET_SQ_reset (plugin->dbh,
1041 plugin->maxRepl); 1051 plugin->maxRepl);
1042 /* DB empty */ 1052 /* DB empty */
1043 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1053 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1044 return; 1054 return;
1045 } 1055 }
1046 repl = sqlite3_column_int (plugin->maxRepl, 1056 repl = sqlite3_column_int (plugin->maxRepl,
@@ -1053,7 +1063,7 @@ sqlite_plugin_get_replication (void *cls,
1053 GNUNET_SQ_bind (plugin->selRepl, 1063 GNUNET_SQ_bind (plugin->selRepl,
1054 params_sel_repl)) 1064 params_sel_repl))
1055 { 1065 {
1056 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1066 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1057 return; 1067 return;
1058 } 1068 }
1059 rc.have_uid = GNUNET_SYSERR; 1069 rc.have_uid = GNUNET_SYSERR;
@@ -1069,7 +1079,7 @@ sqlite_plugin_get_replication (void *cls,
1069 GNUNET_SQ_bind (plugin->updRepl, 1079 GNUNET_SQ_bind (plugin->updRepl,
1070 params_upd_repl)) 1080 params_upd_repl))
1071 { 1081 {
1072 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1082 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1073 return; 1083 return;
1074 } 1084 }
1075 if (SQLITE_DONE != 1085 if (SQLITE_DONE !=
@@ -1083,7 +1093,7 @@ sqlite_plugin_get_replication (void *cls,
1083 if (GNUNET_SYSERR == rc.have_uid) 1093 if (GNUNET_SYSERR == rc.have_uid)
1084 { 1094 {
1085 /* proc was not called at all so far, do it now. */ 1095 /* proc was not called at all so far, do it now. */
1086 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1096 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1087 } 1097 }
1088} 1098}
1089 1099
@@ -1117,7 +1127,7 @@ sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
1117 GNUNET_SQ_bind (stmt, 1127 GNUNET_SQ_bind (stmt,
1118 params)) 1128 params))
1119 { 1129 {
1120 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 1130 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1121 return; 1131 return;
1122 } 1132 }
1123 execute_get (plugin, stmt, proc, proc_cls); 1133 execute_get (plugin, stmt, proc, proc_cls);
diff --git a/src/datastore/plugin_datastore_template.c b/src/datastore/plugin_datastore_template.c
index 187221798..8e44f020d 100644
--- a/src/datastore/plugin_datastore_template.c
+++ b/src/datastore/plugin_datastore_template.c
@@ -151,19 +151,17 @@ template_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
151 151
152 152
153/** 153/**
154 * Update the priority for a particular key in the datastore. If 154 * Update the priority, replication and expiration for a particular
155 * the expiration time in value is different than the time found in 155 * unique ID in the datastore. If the expiration time in value is
156 * the datastore, the higher value should be kept. For the 156 * different than the time found in the datastore, the higher value
157 * anonymity level, the lower value is to be used. The specified 157 * should be kept. The specified priority and replication is added
158 * priority should be added to the existing priority, ignoring the 158 * to the existing value.
159 * priority in value.
160 *
161 * Note that it is possible for multiple values to match this put.
162 * In that case, all of the respective values are updated.
163 * 159 *
164 * @param cls our "struct Plugin*" 160 * @param cls our "struct Plugin*"
165 * @param uid unique identifier of the datum 161 * @param uid unique identifier of the datum
166 * @param delta by how much should the priority 162 * @param priority by how much should the priority
163 * change?
164 * @param replication by how much should the replication
167 * change? 165 * change?
168 * @param expire new expiration time should be the 166 * @param expire new expiration time should be the
169 * MAX of any existing expiration time and 167 * MAX of any existing expiration time and
@@ -172,9 +170,13 @@ template_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
172 * @param cons_cls continuation closure 170 * @param cons_cls continuation closure
173 */ 171 */
174static void 172static void
175template_plugin_update (void *cls, uint64_t uid, uint32_t delta, 173template_plugin_update (void *cls,
174 uint64_t uid,
175 uint32_t priority,
176 uint32_t replication,
176 struct GNUNET_TIME_Absolute expire, 177 struct GNUNET_TIME_Absolute expire,
177 PluginUpdateCont cont, void *cont_cls) 178 PluginUpdateCont cont,
179 void *cont_cls)
178{ 180{
179 GNUNET_break (0); 181 GNUNET_break (0);
180 cont (cont_cls, GNUNET_SYSERR, "not implemented"); 182 cont (cont_cls, GNUNET_SYSERR, "not implemented");
diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c
index 0da68b266..63927a364 100644
--- a/src/datastore/test_datastore_api.c
+++ b/src/datastore/test_datastore_api.c
@@ -231,6 +231,7 @@ check_value (void *cls,
231 enum GNUNET_BLOCK_Type type, 231 enum GNUNET_BLOCK_Type type,
232 uint32_t priority, 232 uint32_t priority,
233 uint32_t anonymity, 233 uint32_t anonymity,
234 uint32_t replication,
234 struct GNUNET_TIME_Absolute expiration, 235 struct GNUNET_TIME_Absolute expiration,
235 uint64_t uid) 236 uint64_t uid)
236{ 237{
@@ -283,6 +284,7 @@ delete_value (void *cls,
283 enum GNUNET_BLOCK_Type type, 284 enum GNUNET_BLOCK_Type type,
284 uint32_t priority, 285 uint32_t priority,
285 uint32_t anonymity, 286 uint32_t anonymity,
287 uint32_t replication,
286 struct GNUNET_TIME_Absolute expiration, 288 struct GNUNET_TIME_Absolute expiration,
287 uint64_t uid) 289 uint64_t uid)
288{ 290{
@@ -308,6 +310,7 @@ check_nothing (void *cls,
308 enum GNUNET_BLOCK_Type type, 310 enum GNUNET_BLOCK_Type type,
309 uint32_t priority, 311 uint32_t priority,
310 uint32_t anonymity, 312 uint32_t anonymity,
313 uint32_t replication,
311 struct GNUNET_TIME_Absolute expiration, 314 struct GNUNET_TIME_Absolute expiration,
312 uint64_t uid) 315 uint64_t uid)
313{ 316{
@@ -329,6 +332,7 @@ check_multiple (void *cls,
329 enum GNUNET_BLOCK_Type type, 332 enum GNUNET_BLOCK_Type type,
330 uint32_t priority, 333 uint32_t priority,
331 uint32_t anonymity, 334 uint32_t anonymity,
335 uint32_t replication,
332 struct GNUNET_TIME_Absolute expiration, 336 struct GNUNET_TIME_Absolute expiration,
333 uint64_t uid) 337 uint64_t uid)
334{ 338{
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c
index de4dc657f..e50b98909 100644
--- a/src/datastore/test_datastore_api_management.c
+++ b/src/datastore/test_datastore_api_management.c
@@ -137,9 +137,15 @@ check_success (void *cls, int success, struct GNUNET_TIME_Absolute min_expiratio
137 137
138 138
139static void 139static void
140check_value (void *cls, const struct GNUNET_HashCode * key, size_t size, 140check_value (void *cls,
141 const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, 141 const struct GNUNET_HashCode *key,
142 uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, 142 size_t size,
143 const void *data,
144 enum GNUNET_BLOCK_Type type,
145 uint32_t priority,
146 uint32_t anonymity,
147 uint32_t replication,
148 struct GNUNET_TIME_Absolute expiration,
143 uint64_t uid) 149 uint64_t uid)
144{ 150{
145 struct CpsRunContext *crc = cls; 151 struct CpsRunContext *crc = cls;
@@ -166,9 +172,15 @@ check_value (void *cls, const struct GNUNET_HashCode * key, size_t size,
166 172
167 173
168static void 174static void
169check_nothing (void *cls, const struct GNUNET_HashCode * key, size_t size, 175check_nothing (void *cls,
170 const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, 176 const struct GNUNET_HashCode *key,
171 uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, 177 size_t size,
178 const void *data,
179 enum GNUNET_BLOCK_Type type,
180 uint32_t priority,
181 uint32_t anonymity,
182 uint32_t replication,
183 struct GNUNET_TIME_Absolute expiration,
172 uint64_t uid) 184 uint64_t uid)
173{ 185{
174 struct CpsRunContext *crc = cls; 186 struct CpsRunContext *crc = cls;
diff --git a/src/datastore/test_plugin_datastore.c b/src/datastore/test_plugin_datastore.c
index 94d93aac6..1867d6755 100644
--- a/src/datastore/test_plugin_datastore.c
+++ b/src/datastore/test_plugin_datastore.c
@@ -193,6 +193,7 @@ iterate_one_shot (void *cls,
193 enum GNUNET_BLOCK_Type type, 193 enum GNUNET_BLOCK_Type type,
194 uint32_t priority, 194 uint32_t priority,
195 uint32_t anonymity, 195 uint32_t anonymity,
196 uint32_t replication,
196 struct GNUNET_TIME_Absolute expiration, 197 struct GNUNET_TIME_Absolute expiration,
197 uint64_t uid) 198 uint64_t uid)
198{ 199{
@@ -317,11 +318,12 @@ test (void *cls)
317 break; 318 break;
318 case RP_UPDATE: 319 case RP_UPDATE:
319 crc->api->update (crc->api->cls, 320 crc->api->update (crc->api->cls,
320 guid, 321 guid,
321 1, 322 1,
322 GNUNET_TIME_UNIT_ZERO_ABS, 323 1,
324 GNUNET_TIME_UNIT_ZERO_ABS,
323 &update_continuation, 325 &update_continuation,
324 crc); 326 crc);
325 break; 327 break;
326 328
327 case RP_ITER_ZERO: 329 case RP_ITER_ZERO: