summaryrefslogtreecommitdiff
path: root/src/datastore
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-04-16 12:39:43 -0500
committerDavid Barksdale <amatus@amat.us>2017-04-16 12:42:34 -0500
commit4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch)
treea2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore
parentcacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff)
downloadgnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz
gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore')
-rw-r--r--src/datastore/gnunet-service-datastore.c194
-rw-r--r--src/datastore/perf_plugin_datastore.c13
-rw-r--r--src/datastore/plugin_datastore_heap.c170
-rw-r--r--src/datastore/plugin_datastore_mysql.c127
-rw-r--r--src/datastore/plugin_datastore_postgres.c129
-rw-r--r--src/datastore/plugin_datastore_sqlite.c149
-rw-r--r--src/datastore/plugin_datastore_template.c49
-rw-r--r--src/datastore/test_plugin_datastore.c36
8 files changed, 332 insertions, 535 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 277530843..d965ad8e0 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -733,41 +733,23 @@ check_data (const struct DataMessage *dm)
733 733
734 734
735/** 735/**
736 * Context for a PUT request used to see if the content is
737 * already present.
738 */
739struct PutContext
740{
741 /**
742 * Client to notify on completion.
743 */
744 struct GNUNET_SERVICE_Client *client;
745
746#if ! HAVE_UNALIGNED_64_ACCESS
747 void *reserved;
748#endif
749
750 /* followed by the 'struct DataMessage' */
751};
752
753
754/**
755 * Put continuation. 736 * Put continuation.
756 * 737 *
757 * @param cls closure 738 * @param cls closure
758 * @param key key for the item stored 739 * @param key key for the item stored
759 * @param size size of the item stored 740 * @param size size of the item stored
760 * @param status #GNUNET_OK or #GNUNET_SYSERROR 741 * @param status #GNUNET_OK if inserted, #GNUNET_NO if updated,
742 * or #GNUNET_SYSERROR if error
761 * @param msg error message on error 743 * @param msg error message on error
762 */ 744 */
763static void 745static void
764put_continuation (void *cls, 746put_continuation (void *cls,
765 const struct GNUNET_HashCode *key, 747 const struct GNUNET_HashCode *key,
766 uint32_t size, 748 uint32_t size,
767 int status, 749 int status,
768 const char *msg) 750 const char *msg)
769{ 751{
770 struct PutContext *pc = cls; 752 struct GNUNET_SERVICE_Client *client = cls;
771 753
772 if (GNUNET_OK == status) 754 if (GNUNET_OK == status)
773 { 755 {
@@ -782,10 +764,9 @@ put_continuation (void *cls,
782 size, 764 size,
783 GNUNET_h2s (key)); 765 GNUNET_h2s (key));
784 } 766 }
785 transmit_status (pc->client, 767 transmit_status (client,
786 status, 768 GNUNET_SYSERR == status ? GNUNET_SYSERR : GNUNET_OK,
787 msg); 769 msg);
788 GNUNET_free (pc);
789 if (quota - reserved - cache_size < payload) 770 if (quota - reserved - cache_size < payload)
790 { 771 {
791 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 772 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -799,125 +780,6 @@ put_continuation (void *cls,
799 780
800 781
801/** 782/**
802 * Actually put the data message.
803 *
804 * @param pc put context
805 */
806static void
807execute_put (struct PutContext *pc)
808{
809 const struct DataMessage *dm;
810
811 dm = (const struct DataMessage *) &pc[1];
812 plugin->api->put (plugin->api->cls,
813 &dm->key,
814 ntohl (dm->size),
815 &dm[1],
816 ntohl (dm->type),
817 ntohl (dm->priority),
818 ntohl (dm->anonymity),
819 ntohl (dm->replication),
820 GNUNET_TIME_absolute_ntoh (dm->expiration),
821 &put_continuation,
822 pc);
823}
824
825
826/**
827 *
828 * @param cls closure
829 * @param status #GNUNET_OK or #GNUNET_SYSERR
830 * @param msg error message on error
831 */
832static void
833check_present_continuation (void *cls,
834 int status,
835 const char *msg)
836{
837 struct GNUNET_SERVICE_Client *client = cls;
838
839 transmit_status (client,
840 GNUNET_NO,
841 NULL);
842}
843
844
845/**
846 * Function that will check if the given datastore entry
847 * matches the put and if none match executes the put.
848 *
849 * @param cls closure, pointer to the client (of type `struct PutContext`).
850 * @param key key for the content
851 * @param size number of bytes in data
852 * @param data content stored
853 * @param type type of the content
854 * @param priority priority of the content
855 * @param anonymity anonymity-level for the content
856 * @param replication replication-level for the content
857 * @param expiration expiration time for the content
858 * @param uid unique identifier for the datum;
859 * maybe 0 if no unique identifier is available
860 * @return #GNUNET_OK usually
861 * #GNUNET_NO to delete the item
862 */
863static int
864check_present (void *cls,
865 const struct GNUNET_HashCode *key,
866 uint32_t size,
867 const void *data,
868 enum GNUNET_BLOCK_Type type,
869 uint32_t priority,
870 uint32_t anonymity,
871 uint32_t replication,
872 struct GNUNET_TIME_Absolute expiration,
873 uint64_t uid)
874{
875 struct PutContext *pc = cls;
876 const struct DataMessage *dm;
877
878 dm = (const struct DataMessage *) &pc[1];
879 if (key == NULL)
880 {
881 execute_put (pc);
882 return GNUNET_OK;
883 }
884 if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == type) ||
885 (GNUNET_BLOCK_TYPE_FS_IBLOCK == type) ||
886 ( (size == ntohl (dm->size)) &&
887 (0 == memcmp (&dm[1],
888 data,
889 size)) ) )
890 {
891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
892 "Result already present in datastore\n");
893 if ( (ntohl (dm->priority) > 0) ||
894 (ntohl (dm->replication) > 0) ||
895 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us >
896 expiration.abs_value_us) )
897 plugin->api->update (plugin->api->cls,
898 uid,
899 ntohl (dm->priority),
900 ntohl (dm->replication),
901 GNUNET_TIME_absolute_ntoh (dm->expiration),
902 &check_present_continuation,
903 pc->client);
904 else
905 {
906 transmit_status (pc->client,
907 GNUNET_NO,
908 NULL);
909 }
910 GNUNET_free (pc);
911 }
912 else
913 {
914 execute_put (pc);
915 }
916 return GNUNET_OK;
917}
918
919
920/**
921 * Verify PUT-message. 783 * Verify PUT-message.
922 * 784 *
923 * @param cls identification of the client 785 * @param cls identification of the client
@@ -950,8 +812,6 @@ handle_put (void *cls,
950 struct GNUNET_SERVICE_Client *client = cls; 812 struct GNUNET_SERVICE_Client *client = cls;
951 int rid; 813 int rid;
952 struct ReservationList *pos; 814 struct ReservationList *pos;
953 struct PutContext *pc;
954 struct GNUNET_HashCode vhash;
955 uint32_t size; 815 uint32_t size;
956 816
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -979,30 +839,20 @@ handle_put (void *cls,
979 GNUNET_NO); 839 GNUNET_NO);
980 } 840 }
981 } 841 }
982 pc = GNUNET_malloc (sizeof (struct PutContext) + size + 842 bool absent = GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (filter,
983 sizeof (struct DataMessage)); 843 &dm->key);
984 pc->client = client; 844 plugin->api->put (plugin->api->cls,
985 GNUNET_memcpy (&pc[1], 845 &dm->key,
986 dm, 846 absent,
987 size + sizeof (struct DataMessage)); 847 ntohl (dm->size),
988 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (filter, 848 &dm[1],
989 &dm->key)) 849 ntohl (dm->type),
990 { 850 ntohl (dm->priority),
991 GNUNET_CRYPTO_hash (&dm[1], 851 ntohl (dm->anonymity),
992 size, 852 ntohl (dm->replication),
993 &vhash); 853 GNUNET_TIME_absolute_ntoh (dm->expiration),
994 plugin->api->get_key (plugin->api->cls, 854 &put_continuation,
995 0, 855 client);
996 false,
997 &dm->key,
998 &vhash,
999 ntohl (dm->type),
1000 &check_present,
1001 pc);
1002 GNUNET_SERVICE_client_continue (client);
1003 return;
1004 }
1005 execute_put (pc);
1006 GNUNET_SERVICE_client_continue (client); 856 GNUNET_SERVICE_client_continue (client);
1007} 857}
1008 858
diff --git a/src/datastore/perf_plugin_datastore.c b/src/datastore/perf_plugin_datastore.c
index 2f9502989..d6f44bf9f 100644
--- a/src/datastore/perf_plugin_datastore.c
+++ b/src/datastore/perf_plugin_datastore.c
@@ -181,8 +181,14 @@ do_put (struct CpsRunContext *crc)
181 value[0] = crc->i; 181 value[0] = crc->i;
182 GNUNET_memcpy (&value[4], &i, sizeof (i)); 182 GNUNET_memcpy (&value[4], &i, sizeof (i));
183 prio = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100); 183 prio = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100);
184 crc->api->put (crc->api->cls, &key, size, value, 1 + i % 4 /* type */ , 184 crc->api->put (crc->api->cls,
185 prio, i % 4 /* anonymity */ , 185 &key,
186 false /* absent */,
187 size,
188 value,
189 1 + i % 4 /* type */ ,
190 prio,
191 i % 4 /* anonymity */ ,
186 0 /* replication */ , 192 0 /* replication */ ,
187 GNUNET_TIME_relative_to_absolute 193 GNUNET_TIME_relative_to_absolute
188 (GNUNET_TIME_relative_multiply 194 (GNUNET_TIME_relative_multiply
@@ -190,7 +196,8 @@ do_put (struct CpsRunContext *crc)
190 60 * 60 * 60 * 1000 + 196 60 * 60 * 60 * 1000 +
191 GNUNET_CRYPTO_random_u32 197 GNUNET_CRYPTO_random_u32
192 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), 198 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
193 put_continuation, crc); 199 put_continuation,
200 crc);
194 i++; 201 i++;
195} 202}
196 203
diff --git a/src/datastore/plugin_datastore_heap.c b/src/datastore/plugin_datastore_heap.c
index d04c1cf60..6dbc15ebd 100644
--- a/src/datastore/plugin_datastore_heap.c
+++ b/src/datastore/plugin_datastore_heap.c
@@ -195,10 +195,89 @@ heap_plugin_estimate_size (void *cls, unsigned long long *estimate)
195 195
196 196
197/** 197/**
198 * Closure for iterator for updating.
199 */
200struct UpdateContext
201{
202 /**
203 * Number of bytes in 'data'.
204 */
205 uint32_t size;
206
207 /**
208 * Pointer to the data.
209 */
210 const void *data;
211
212 /**
213 * Priority of the value.
214 */
215 uint32_t priority;
216
217 /**
218 * Replication level for the value.
219 */
220 uint32_t replication;
221
222 /**
223 * Expiration time for this value.
224 */
225 struct GNUNET_TIME_Absolute expiration;
226
227 /**
228 * True if the value was found and updated.
229 */
230 bool updated;
231};
232
233
234/**
235 * Update the matching value.
236 *
237 * @param cls the 'struct UpdateContext'
238 * @param key unused
239 * @param val the 'struct Value'
240 * @return GNUNET_YES (continue iteration), GNUNET_NO if value was found
241 */
242static int
243update_iterator (void *cls,
244 const struct GNUNET_HashCode *key,
245 void *val)
246{
247 struct UpdateContext *uc = cls;
248 struct Value *value = val;
249
250 if (value->size != uc->size)
251 return GNUNET_YES;
252 if (0 != memcmp (value->data, uc->data, uc->size))
253 return GNUNET_YES;
254 uc->expiration = GNUNET_TIME_absolute_max (value->expiration,
255 uc->expiration);
256 if (value->expiration.abs_value_us != uc->expiration.abs_value_us)
257 {
258 value->expiration = uc->expiration;
259 GNUNET_CONTAINER_heap_update_cost (value->expire_heap,
260 value->expiration.abs_value_us);
261 }
262 /* Saturating adds, don't overflow */
263 if (value->priority > UINT32_MAX - uc->priority)
264 value->priority = UINT32_MAX;
265 else
266 value->priority += uc->priority;
267 if (value->replication > UINT32_MAX - uc->replication)
268 value->replication = UINT32_MAX;
269 else
270 value->replication += uc->replication;
271 uc->updated = true;
272 return GNUNET_NO;
273}
274
275/**
198 * Store an item in the datastore. 276 * Store an item in the datastore.
199 * 277 *
200 * @param cls closure 278 * @param cls closure
201 * @param key key for the item 279 * @param key key for the item
280 * @param absent true if the key was not found in the bloom filter
202 * @param size number of bytes in data 281 * @param size number of bytes in data
203 * @param data content stored 282 * @param data content stored
204 * @param type type of the content 283 * @param type type of the content
@@ -211,19 +290,40 @@ heap_plugin_estimate_size (void *cls, unsigned long long *estimate)
211 */ 290 */
212static void 291static void
213heap_plugin_put (void *cls, 292heap_plugin_put (void *cls,
214 const struct GNUNET_HashCode * key, 293 const struct GNUNET_HashCode *key,
215 uint32_t size, 294 bool absent,
216 const void *data, 295 uint32_t size,
217 enum GNUNET_BLOCK_Type type, 296 const void *data,
218 uint32_t priority, uint32_t anonymity, 297 enum GNUNET_BLOCK_Type type,
219 uint32_t replication, 298 uint32_t priority,
220 struct GNUNET_TIME_Absolute expiration, 299 uint32_t anonymity,
221 PluginPutCont cont, 300 uint32_t replication,
222 void *cont_cls) 301 struct GNUNET_TIME_Absolute expiration,
302 PluginPutCont cont,
303 void *cont_cls)
223{ 304{
224 struct Plugin *plugin = cls; 305 struct Plugin *plugin = cls;
225 struct Value *value; 306 struct Value *value;
226 307
308 if (!absent) {
309 struct UpdateContext uc;
310
311 uc.size = size;
312 uc.data = data;
313 uc.priority = priority;
314 uc.replication = replication;
315 uc.expiration = expiration;
316 uc.updated = false;
317 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue,
318 key,
319 &update_iterator,
320 &uc);
321 if (uc.updated)
322 {
323 cont (cont_cls, key, size, GNUNET_NO, NULL);
324 return;
325 }
326 }
227 value = GNUNET_malloc (sizeof (struct Value) + size); 327 value = GNUNET_malloc (sizeof (struct Value) + size);
228 value->key = *key; 328 value->key = *key;
229 value->data = &value[1]; 329 value->data = &value[1];
@@ -551,57 +651,6 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
551 651
552 652
553/** 653/**
554 * Update the priority, replication and expiration for a particular
555 * unique ID in the datastore. If the expiration time in value is
556 * different than the time found in the datastore, the higher value
557 * should be kept. The specified priority and replication is added
558 * to the existing value.
559 *
560 * @param cls our `struct Plugin *`
561 * @param uid unique identifier of the datum
562 * @param priority by how much should the priority
563 * change?
564 * @param replication by how much should the replication
565 * change?
566 * @param expire new expiration time should be the
567 * MAX of any existing expiration time and
568 * this value
569 * @param cont continuation called with success or failure status
570 * @param cons_cls continuation closure
571 */
572static void
573heap_plugin_update (void *cls,
574 uint64_t uid,
575 uint32_t priority,
576 uint32_t replication,
577 struct GNUNET_TIME_Absolute expire,
578 PluginUpdateCont cont,
579 void *cont_cls)
580{
581 struct Value *value;
582
583 value = (struct Value*) (intptr_t) uid;
584 GNUNET_assert (NULL != value);
585 if (value->expiration.abs_value_us != expire.abs_value_us)
586 {
587 value->expiration = expire;
588 GNUNET_CONTAINER_heap_update_cost (value->expire_heap,
589 expire.abs_value_us);
590 }
591 /* Saturating adds, don't overflow */
592 if (value->priority > UINT32_MAX - priority)
593 value->priority = UINT32_MAX;
594 else
595 value->priority += priority;
596 if (value->replication > UINT32_MAX - replication)
597 value->replication = UINT32_MAX;
598 else
599 value->replication += replication;
600 cont (cont_cls, GNUNET_OK, NULL);
601}
602
603
604/**
605 * Call the given processor on an item with zero anonymity. 654 * Call the given processor on an item with zero anonymity.
606 * 655 *
607 * @param cls our "struct Plugin*" 656 * @param cls our "struct Plugin*"
@@ -758,7 +807,6 @@ libgnunet_plugin_datastore_heap_init (void *cls)
758 api->cls = plugin; 807 api->cls = plugin;
759 api->estimate_size = &heap_plugin_estimate_size; 808 api->estimate_size = &heap_plugin_estimate_size;
760 api->put = &heap_plugin_put; 809 api->put = &heap_plugin_put;
761 api->update = &heap_plugin_update;
762 api->get_key = &heap_plugin_get_key; 810 api->get_key = &heap_plugin_get_key;
763 api->get_replication = &heap_plugin_get_replication; 811 api->get_replication = &heap_plugin_get_replication;
764 api->get_expiration = &heap_plugin_get_expiration; 812 api->get_expiration = &heap_plugin_get_expiration;
diff --git a/src/datastore/plugin_datastore_mysql.c b/src/datastore/plugin_datastore_mysql.c
index 6f2a76499..edc459272 100644
--- a/src/datastore/plugin_datastore_mysql.c
+++ b/src/datastore/plugin_datastore_mysql.c
@@ -198,8 +198,8 @@ struct Plugin
198#define UPDATE_ENTRY "UPDATE gn090 SET "\ 198#define UPDATE_ENTRY "UPDATE gn090 SET "\
199 "prio = prio + ?, "\ 199 "prio = prio + ?, "\
200 "repl = repl + ?, "\ 200 "repl = repl + ?, "\
201 "expire = IF(expire >= ?, expire, ?) "\ 201 "expire = GREATEST(expire, ?) "\
202 "WHERE uid = ?" 202 "WHERE hash = ? AND vhash = ?"
203 struct GNUNET_MYSQL_StatementHandle *update_entry; 203 struct GNUNET_MYSQL_StatementHandle *update_entry;
204 204
205#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=?"
@@ -330,6 +330,7 @@ mysql_plugin_estimate_size (void *cls,
330 * 330 *
331 * @param cls closure 331 * @param cls closure
332 * @param key key for the item 332 * @param key key for the item
333 * @param absent true if the key was not found in the bloom filter
333 * @param size number of bytes in @a data 334 * @param size number of bytes in @a data
334 * @param data content stored 335 * @param data content stored
335 * @param type type of the content 336 * @param type type of the content
@@ -343,6 +344,7 @@ mysql_plugin_estimate_size (void *cls,
343static void 344static void
344mysql_plugin_put (void *cls, 345mysql_plugin_put (void *cls,
345 const struct GNUNET_HashCode *key, 346 const struct GNUNET_HashCode *key,
347 bool absent,
346 uint32_t size, 348 uint32_t size,
347 const void *data, 349 const void *data,
348 enum GNUNET_BLOCK_Type type, 350 enum GNUNET_BLOCK_Type type,
@@ -355,9 +357,54 @@ mysql_plugin_put (void *cls,
355{ 357{
356 struct Plugin *plugin = cls; 358 struct Plugin *plugin = cls;
357 uint64_t lexpiration = expiration.abs_value_us; 359 uint64_t lexpiration = expiration.abs_value_us;
360 struct GNUNET_HashCode vhash;
361
362 GNUNET_CRYPTO_hash (data,
363 size,
364 &vhash);
365 if (!absent)
366 {
367 struct GNUNET_MY_QueryParam params_update[] = {
368 GNUNET_MY_query_param_uint32 (&priority),
369 GNUNET_MY_query_param_uint32 (&replication),
370 GNUNET_MY_query_param_uint64 (&lexpiration),
371 GNUNET_MY_query_param_auto_from_type (key),
372 GNUNET_MY_query_param_auto_from_type (&vhash),
373 GNUNET_MY_query_param_end
374 };
375
376 if (GNUNET_OK !=
377 GNUNET_MY_exec_prepared (plugin->mc,
378 plugin->update_entry,
379 params_update))
380 {
381 cont (cont_cls,
382 key,
383 size,
384 GNUNET_SYSERR,
385 _("MySQL statement run failure"));
386 return;
387 }
388
389 MYSQL_STMT *stmt = GNUNET_MYSQL_statement_get_stmt (plugin->update_entry);
390 my_ulonglong rows = mysql_stmt_affected_rows (stmt);
391
392 GNUNET_break (GNUNET_NO ==
393 GNUNET_MY_extract_result (plugin->update_entry,
394 NULL));
395 if (0 != rows)
396 {
397 cont (cont_cls,
398 key,
399 size,
400 GNUNET_NO,
401 NULL);
402 return;
403 }
404 }
405
358 uint64_t lrvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 406 uint64_t lrvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
359 UINT64_MAX); 407 UINT64_MAX);
360 struct GNUNET_HashCode vhash;
361 struct GNUNET_MY_QueryParam params_insert[] = { 408 struct GNUNET_MY_QueryParam params_insert[] = {
362 GNUNET_MY_query_param_uint32 (&replication), 409 GNUNET_MY_query_param_uint32 (&replication),
363 GNUNET_MY_query_param_uint32 (&type), 410 GNUNET_MY_query_param_uint32 (&type),
@@ -377,9 +424,6 @@ mysql_plugin_put (void *cls,
377 cont (cont_cls, key, size, GNUNET_SYSERR, _("Data too large")); 424 cont (cont_cls, key, size, GNUNET_SYSERR, _("Data too large"));
378 return; 425 return;
379 } 426 }
380 GNUNET_CRYPTO_hash (data,
381 size,
382 &vhash);
383 427
384 if (GNUNET_OK != 428 if (GNUNET_OK !=
385 GNUNET_MY_exec_prepared (plugin->mc, 429 GNUNET_MY_exec_prepared (plugin->mc,
@@ -412,76 +456,6 @@ mysql_plugin_put (void *cls,
412 456
413 457
414/** 458/**
415 * Update the priority, replication and expiration for a particular
416 * unique ID in the datastore. If the expiration time in value is
417 * different than the time found in the datastore, the higher value
418 * should be kept. The specified priority and replication is added
419 * to the existing value.
420 *
421 * @param cls our "struct Plugin*"
422 * @param uid unique identifier of the datum
423 * @param priority by how much should the priority
424 * change?
425 * @param replication by how much should the replication
426 * change?
427 * @param expire new expiration time should be the
428 * MAX of any existing expiration time and
429 * this value
430 * @param cont continuation called with success or failure status
431 * @param cons_cls continuation closure
432 */
433static void
434mysql_plugin_update (void *cls,
435 uint64_t uid,
436 uint32_t priority,
437 uint32_t replication,
438 struct GNUNET_TIME_Absolute expire,
439 PluginUpdateCont cont,
440 void *cont_cls)
441{
442 struct Plugin *plugin = cls;
443 uint64_t lexpire = expire.abs_value_us;
444 int ret;
445
446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
447 "Updating value %llu adding %d to priority %d to replication and maxing exp at %s\n",
448 (unsigned long long) uid,
449 priority,
450 replication,
451 GNUNET_STRINGS_absolute_time_to_string (expire));
452
453 struct GNUNET_MY_QueryParam params_update[] = {
454 GNUNET_MY_query_param_uint32 (&priority),
455 GNUNET_MY_query_param_uint32 (&replication),
456 GNUNET_MY_query_param_uint64 (&lexpire),
457 GNUNET_MY_query_param_uint64 (&lexpire),
458 GNUNET_MY_query_param_uint64 (&uid),
459 GNUNET_MY_query_param_end
460 };
461
462 ret = GNUNET_MY_exec_prepared (plugin->mc,
463 plugin->update_entry,
464 params_update);
465
466 if (GNUNET_OK != ret)
467 {
468 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
469 "Failed to update value %llu\n",
470 (unsigned long long) uid);
471 }
472 else
473 {
474 GNUNET_break (GNUNET_NO ==
475 GNUNET_MY_extract_result (plugin->update_entry,
476 NULL));
477 }
478 cont (cont_cls,
479 ret,
480 NULL);
481}
482
483
484/**
485 * Run the given select statement and call 'proc' on the resulting 459 * Run the given select statement and call 'proc' on the resulting
486 * values (which must be in particular positions). 460 * values (which must be in particular positions).
487 * 461 *
@@ -1197,7 +1171,6 @@ libgnunet_plugin_datastore_mysql_init (void *cls)
1197 api->cls = plugin; 1171 api->cls = plugin;
1198 api->estimate_size = &mysql_plugin_estimate_size; 1172 api->estimate_size = &mysql_plugin_estimate_size;
1199 api->put = &mysql_plugin_put; 1173 api->put = &mysql_plugin_put;
1200 api->update = &mysql_plugin_update;
1201 api->get_key = &mysql_plugin_get_key; 1174 api->get_key = &mysql_plugin_get_key;
1202 api->get_replication = &mysql_plugin_get_replication; 1175 api->get_replication = &mysql_plugin_get_replication;
1203 api->get_expiration = &mysql_plugin_get_expiration; 1176 api->get_expiration = &mysql_plugin_get_expiration;
diff --git a/src/datastore/plugin_datastore_postgres.c b/src/datastore/plugin_datastore_postgres.c
index 87a7acbdc..349848ae6 100644
--- a/src/datastore/plugin_datastore_postgres.c
+++ b/src/datastore/plugin_datastore_postgres.c
@@ -195,8 +195,8 @@ init_connection (struct Plugin *plugin)
195 "UPDATE gn090 " 195 "UPDATE gn090 "
196 "SET prio = prio + $1, " 196 "SET prio = prio + $1, "
197 "repl = repl + $2, " 197 "repl = repl + $2, "
198 "expire = CASE WHEN expire < $3 THEN $3 ELSE expire END " 198 "expire = GREATEST(expire, $3) "
199 "WHERE oid = $4", 4)) || 199 "WHERE hash = $4 AND vhash = $5", 5)) ||
200 (GNUNET_OK != 200 (GNUNET_OK !=
201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl", 201 GNUNET_POSTGRES_prepare (plugin->dbh, "decrepl",
202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) " 202 "UPDATE gn090 SET repl = GREATEST (repl - 1, 0) "
@@ -288,6 +288,7 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
288 * 288 *
289 * @param cls closure with the `struct Plugin` 289 * @param cls closure with the `struct Plugin`
290 * @param key key for the item 290 * @param key key for the item
291 * @param absent true if the key was not found in the bloom filter
291 * @param size number of bytes in data 292 * @param size number of bytes in data
292 * @param data content stored 293 * @param data content stored
293 * @param type type of the content 294 * @param type type of the content
@@ -300,23 +301,70 @@ postgres_plugin_estimate_size (void *cls, unsigned long long *estimate)
300 */ 301 */
301static void 302static void
302postgres_plugin_put (void *cls, 303postgres_plugin_put (void *cls,
303 const struct GNUNET_HashCode *key, 304 const struct GNUNET_HashCode *key,
304 uint32_t size, 305 bool absent,
306 uint32_t size,
305 const void *data, 307 const void *data,
306 enum GNUNET_BLOCK_Type type, 308 enum GNUNET_BLOCK_Type type,
307 uint32_t priority, 309 uint32_t priority,
308 uint32_t anonymity, 310 uint32_t anonymity,
309 uint32_t replication, 311 uint32_t replication,
310 struct GNUNET_TIME_Absolute expiration, 312 struct GNUNET_TIME_Absolute expiration,
311 PluginPutCont cont, 313 PluginPutCont cont,
312 void *cont_cls) 314 void *cont_cls)
313{ 315{
314 struct Plugin *plugin = cls; 316 struct Plugin *plugin = cls;
315 uint32_t utype = type;
316 struct GNUNET_HashCode vhash; 317 struct GNUNET_HashCode vhash;
318 PGresult *ret;
319
320 GNUNET_CRYPTO_hash (data,
321 size,
322 &vhash);
323
324 if (!absent)
325 {
326 struct GNUNET_PQ_QueryParam params[] = {
327 GNUNET_PQ_query_param_uint32 (&priority),
328 GNUNET_PQ_query_param_uint32 (&replication),
329 GNUNET_PQ_query_param_absolute_time (&expiration),
330 GNUNET_PQ_query_param_auto_from_type (key),
331 GNUNET_PQ_query_param_auto_from_type (&vhash),
332 GNUNET_PQ_query_param_end
333 };
334 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
335 "update",
336 params);
337 if (GNUNET_OK !=
338 GNUNET_POSTGRES_check_result (plugin->dbh,
339 ret,
340 PGRES_COMMAND_OK,
341 "PQexecPrepared",
342 "update"))
343 {
344 cont (cont_cls,
345 key,
346 size,
347 GNUNET_SYSERR,
348 _("Postgress exec failure"));
349 return;
350 }
351 /* What an awful API, this function really does return a string */
352 bool affected = 0 != strcmp ("0", PQcmdTuples (ret));
353 PQclear (ret);
354 if (affected)
355 {
356 cont (cont_cls,
357 key,
358 size,
359 GNUNET_NO,
360 NULL);
361 return;
362 }
363 }
364
365 uint32_t utype = type;
317 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, 366 uint64_t rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
318 UINT64_MAX); 367 UINT64_MAX);
319 PGresult *ret;
320 struct GNUNET_PQ_QueryParam params[] = { 368 struct GNUNET_PQ_QueryParam params[] = {
321 GNUNET_PQ_query_param_uint32 (&replication), 369 GNUNET_PQ_query_param_uint32 (&replication),
322 GNUNET_PQ_query_param_uint32 (&utype), 370 GNUNET_PQ_query_param_uint32 (&utype),
@@ -330,7 +378,6 @@ postgres_plugin_put (void *cls,
330 GNUNET_PQ_query_param_end 378 GNUNET_PQ_query_param_end
331 }; 379 };
332 380
333 GNUNET_CRYPTO_hash (data, size, &vhash);
334 ret = GNUNET_PQ_exec_prepared (plugin->dbh, 381 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
335 "put", 382 "put",
336 params); 383 params);
@@ -750,67 +797,6 @@ postgres_plugin_get_expiration (void *cls,
750 797
751 798
752/** 799/**
753 * Update the priority, replication and expiration for a particular
754 * unique ID in the datastore. If the expiration time in value is
755 * different than the time found in the datastore, the higher value
756 * should be kept. The specified priority and replication is added
757 * to the existing value.
758 *
759 * @param cls our `struct Plugin *`
760 * @param uid unique identifier of the datum
761 * @param priority by how much should the priority
762 * change?
763 * @param replication by how much should the replication
764 * change?
765 * @param expire new expiration time should be the
766 * MAX of any existing expiration time and
767 * this value
768 * @param cont continuation called with success or failure status
769 * @param cons_cls continuation closure
770 */
771static void
772postgres_plugin_update (void *cls,
773 uint64_t uid,
774 uint32_t priority,
775 uint32_t replication,
776 struct GNUNET_TIME_Absolute expire,
777 PluginUpdateCont cont,
778 void *cont_cls)
779{
780 struct Plugin *plugin = cls;
781 uint32_t oid = (uint32_t) uid;
782 struct GNUNET_PQ_QueryParam params[] = {
783 GNUNET_PQ_query_param_uint32 (&priority),
784 GNUNET_PQ_query_param_uint32 (&replication),
785 GNUNET_PQ_query_param_absolute_time (&expire),
786 GNUNET_PQ_query_param_uint32 (&oid),
787 GNUNET_PQ_query_param_end
788 };
789 PGresult *ret;
790
791 ret = GNUNET_PQ_exec_prepared (plugin->dbh,
792 "update",
793 params);
794 if (GNUNET_OK !=
795 GNUNET_POSTGRES_check_result (plugin->dbh,
796 ret,
797 PGRES_COMMAND_OK,
798 "PQexecPrepared",
799 "update"))
800 {
801 cont (cont_cls,
802 GNUNET_SYSERR,
803 NULL);
804 return;
805 }
806 PQclear (ret);
807 cont (cont_cls,
808 GNUNET_OK,
809 NULL);
810}
811
812
813/**
814 * Get all of the keys in the datastore. 800 * Get all of the keys in the datastore.
815 * 801 *
816 * @param cls closure with the `struct Plugin *` 802 * @param cls closure with the `struct Plugin *`
@@ -891,7 +877,6 @@ libgnunet_plugin_datastore_postgres_init (void *cls)
891 api->cls = plugin; 877 api->cls = plugin;
892 api->estimate_size = &postgres_plugin_estimate_size; 878 api->estimate_size = &postgres_plugin_estimate_size;
893 api->put = &postgres_plugin_put; 879 api->put = &postgres_plugin_put;
894 api->update = &postgres_plugin_update;
895 api->get_key = &postgres_plugin_get_key; 880 api->get_key = &postgres_plugin_get_key;
896 api->get_replication = &postgres_plugin_get_replication; 881 api->get_replication = &postgres_plugin_get_replication;
897 api->get_expiration = &postgres_plugin_get_expiration; 882 api->get_expiration = &postgres_plugin_get_expiration;
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c
index 1f874e190..469dd7717 100644
--- a/src/datastore/plugin_datastore_sqlite.c
+++ b/src/datastore/plugin_datastore_sqlite.c
@@ -95,7 +95,7 @@ struct Plugin
95 /** 95 /**
96 * Precompiled SQL for update. 96 * Precompiled SQL for update.
97 */ 97 */
98 sqlite3_stmt *updPrio; 98 sqlite3_stmt *update;
99 99
100 /** 100 /**
101 * Get maximum repl value in database. 101 * Get maximum repl value in database.
@@ -356,8 +356,8 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
356 "SET prio = prio + ?, " 356 "SET prio = prio + ?, "
357 "repl = repl + ?, " 357 "repl = repl + ?, "
358 "expire = MAX(expire, ?) " 358 "expire = MAX(expire, ?) "
359 "WHERE _ROWID_ = ?", 359 "WHERE hash = ? AND vhash = ?",
360 &plugin->updPrio)) || 360 &plugin->update)) ||
361 (SQLITE_OK != 361 (SQLITE_OK !=
362 sq_prepare (plugin->dbh, 362 sq_prepare (plugin->dbh,
363 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?", 363 "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
@@ -450,8 +450,8 @@ database_shutdown (struct Plugin *plugin)
450 450
451 if (NULL != plugin->delRow) 451 if (NULL != plugin->delRow)
452 sqlite3_finalize (plugin->delRow); 452 sqlite3_finalize (plugin->delRow);
453 if (NULL != plugin->updPrio) 453 if (NULL != plugin->update)
454 sqlite3_finalize (plugin->updPrio); 454 sqlite3_finalize (plugin->update);
455 if (NULL != plugin->updRepl) 455 if (NULL != plugin->updRepl)
456 sqlite3_finalize (plugin->updRepl); 456 sqlite3_finalize (plugin->updRepl);
457 if (NULL != plugin->selRepl) 457 if (NULL != plugin->selRepl)
@@ -541,6 +541,7 @@ delete_by_rowid (struct Plugin *plugin,
541 * 541 *
542 * @param cls closure 542 * @param cls closure
543 * @param key key for the item 543 * @param key key for the item
544 * @param absent true if the key was not found in the bloom filter
544 * @param size number of bytes in @a data 545 * @param size number of bytes in @a data
545 * @param data content stored 546 * @param data content stored
546 * @param type type of the content 547 * @param type type of the content
@@ -554,6 +555,7 @@ delete_by_rowid (struct Plugin *plugin,
554static void 555static void
555sqlite_plugin_put (void *cls, 556sqlite_plugin_put (void *cls,
556 const struct GNUNET_HashCode *key, 557 const struct GNUNET_HashCode *key,
558 bool absent,
557 uint32_t size, 559 uint32_t size,
558 const void *data, 560 const void *data,
559 enum GNUNET_BLOCK_Type type, 561 enum GNUNET_BLOCK_Type type,
@@ -564,8 +566,63 @@ sqlite_plugin_put (void *cls,
564 PluginPutCont cont, 566 PluginPutCont cont,
565 void *cont_cls) 567 void *cont_cls)
566{ 568{
567 uint64_t rvalue; 569 struct Plugin *plugin = cls;
568 struct GNUNET_HashCode vhash; 570 struct GNUNET_HashCode vhash;
571 char *msg = NULL;
572
573 GNUNET_CRYPTO_hash (data,
574 size,
575 &vhash);
576
577 if (!absent)
578 {
579 struct GNUNET_SQ_QueryParam params[] = {
580 GNUNET_SQ_query_param_uint32 (&priority),
581 GNUNET_SQ_query_param_uint32 (&replication),
582 GNUNET_SQ_query_param_absolute_time (&expiration),
583 GNUNET_SQ_query_param_auto_from_type (key),
584 GNUNET_SQ_query_param_auto_from_type (&vhash),
585 GNUNET_SQ_query_param_end
586 };
587
588 if (GNUNET_OK !=
589 GNUNET_SQ_bind (plugin->update,
590 params))
591 {
592 cont (cont_cls,
593 key,
594 size,
595 GNUNET_SYSERR,
596 _("sqlite bind failure"));
597 return;
598 }
599 if (SQLITE_DONE != sqlite3_step (plugin->update))
600 {
601 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
602 "sqlite3_step");
603 cont (cont_cls,
604 key,
605 size,
606 GNUNET_SYSERR,
607 msg);
608 GNUNET_free_non_null (msg);
609 return;
610 }
611 int changes = sqlite3_changes (plugin->dbh);
612 GNUNET_SQ_reset (plugin->dbh,
613 plugin->update);
614 if (0 != changes)
615 {
616 cont (cont_cls,
617 key,
618 size,
619 GNUNET_NO,
620 NULL);
621 return;
622 }
623 }
624
625 uint64_t rvalue;
569 uint32_t type32 = (uint32_t) type; 626 uint32_t type32 = (uint32_t) type;
570 struct GNUNET_SQ_QueryParam params[] = { 627 struct GNUNET_SQ_QueryParam params[] = {
571 GNUNET_SQ_query_param_uint32 (&replication), 628 GNUNET_SQ_query_param_uint32 (&replication),
@@ -579,11 +636,9 @@ sqlite_plugin_put (void *cls,
579 GNUNET_SQ_query_param_fixed_size (data, size), 636 GNUNET_SQ_query_param_fixed_size (data, size),
580 GNUNET_SQ_query_param_end 637 GNUNET_SQ_query_param_end
581 }; 638 };
582 struct Plugin *plugin = cls;
583 int n; 639 int n;
584 int ret; 640 int ret;
585 sqlite3_stmt *stmt; 641 sqlite3_stmt *stmt;
586 char *msg = NULL;
587 642
588 if (size > MAX_ITEM_SIZE) 643 if (size > MAX_ITEM_SIZE)
589 { 644 {
@@ -598,15 +653,13 @@ sqlite_plugin_put (void *cls,
598 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration), 653 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
599 GNUNET_YES), 654 GNUNET_YES),
600 GNUNET_STRINGS_absolute_time_to_string (expiration)); 655 GNUNET_STRINGS_absolute_time_to_string (expiration));
601 GNUNET_CRYPTO_hash (data, size, &vhash);
602 stmt = plugin->insertContent; 656 stmt = plugin->insertContent;
603 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 657 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
604 if (GNUNET_OK != 658 if (GNUNET_OK !=
605 GNUNET_SQ_bind (stmt, 659 GNUNET_SQ_bind (stmt,
606 params)) 660 params))
607 { 661 {
608 cont (cont_cls, key, size, GNUNET_SYSERR, msg); 662 cont (cont_cls, key, size, GNUNET_SYSERR, NULL);
609 GNUNET_free_non_null(msg);
610 return; 663 return;
611 } 664 }
612 n = sqlite3_step (stmt); 665 n = sqlite3_step (stmt);
@@ -646,79 +699,6 @@ sqlite_plugin_put (void *cls,
646 699
647 700
648/** 701/**
649 * Update the priority, replication and expiration for a particular
650 * unique ID in the datastore. If the expiration time in value is
651 * different than the time found in the datastore, the higher value
652 * should be kept. The specified priority and replication is added
653 * to the existing value.
654 *
655 * @param cls the plugin context (state for this module)
656 * @param uid unique identifier of the datum
657 * @param priority by how much should the priority
658 * change?
659 * @param replication by how much should the replication
660 * change?
661 * @param expire new expiration time should be the
662 * MAX of any existing expiration time and
663 * this value
664 * @param cont continuation called with success or failure status
665 * @param cons_cls closure for @a cont
666 */
667static void
668sqlite_plugin_update (void *cls,
669 uint64_t uid,
670 uint32_t priority,
671 uint32_t replication,
672 struct GNUNET_TIME_Absolute expire,
673 PluginUpdateCont cont,
674 void *cont_cls)
675{
676 struct Plugin *plugin = cls;
677 struct GNUNET_SQ_QueryParam params[] = {
678 GNUNET_SQ_query_param_uint32 (&priority),
679 GNUNET_SQ_query_param_uint32 (&replication),
680 GNUNET_SQ_query_param_absolute_time (&expire),
681 GNUNET_SQ_query_param_uint64 (&uid),
682 GNUNET_SQ_query_param_end
683 };
684 int n;
685 char *msg = NULL;
686
687 if (GNUNET_OK !=
688 GNUNET_SQ_bind (plugin->updPrio,
689 params))
690 {
691 cont (cont_cls, GNUNET_SYSERR, msg);
692 GNUNET_free_non_null(msg);
693 return;
694 }
695 n = sqlite3_step (plugin->updPrio);
696 GNUNET_SQ_reset (plugin->dbh,
697 plugin->updPrio);
698 switch (n)
699 {
700 case SQLITE_DONE:
701 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n");
702 cont (cont_cls, GNUNET_OK, NULL);
703 return;
704 case SQLITE_BUSY:
705 LOG_SQLITE_MSG (plugin, &msg,
706 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
707 "sqlite3_step");
708 cont (cont_cls, GNUNET_NO, msg);
709 GNUNET_free_non_null(msg);
710 return;
711 default:
712 LOG_SQLITE_MSG (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
713 "sqlite3_step");
714 cont (cont_cls, GNUNET_SYSERR, msg);
715 GNUNET_free_non_null(msg);
716 return;
717 }
718}
719
720
721/**
722 * Execute statement that gets a row and call the callback 702 * Execute statement that gets a row and call the callback
723 * with the result. Resets the statement afterwards. 703 * with the result. Resets the statement afterwards.
724 * 704 *
@@ -1300,7 +1280,6 @@ libgnunet_plugin_datastore_sqlite_init (void *cls)
1300 api->cls = &plugin; 1280 api->cls = &plugin;
1301 api->estimate_size = &sqlite_plugin_estimate_size; 1281 api->estimate_size = &sqlite_plugin_estimate_size;
1302 api->put = &sqlite_plugin_put; 1282 api->put = &sqlite_plugin_put;
1303 api->update = &sqlite_plugin_update;
1304 api->get_key = &sqlite_plugin_get_key; 1283 api->get_key = &sqlite_plugin_get_key;
1305 api->get_replication = &sqlite_plugin_get_replication; 1284 api->get_replication = &sqlite_plugin_get_replication;
1306 api->get_expiration = &sqlite_plugin_get_expiration; 1285 api->get_expiration = &sqlite_plugin_get_expiration;
diff --git a/src/datastore/plugin_datastore_template.c b/src/datastore/plugin_datastore_template.c
index 8e44f020d..704d586bc 100644
--- a/src/datastore/plugin_datastore_template.c
+++ b/src/datastore/plugin_datastore_template.c
@@ -62,6 +62,7 @@ template_plugin_estimate_size (void *cls, unsigned long long *estimate)
62 * 62 *
63 * @param cls closure 63 * @param cls closure
64 * @param key key for the item 64 * @param key key for the item
65 * @param absent true if the key was not found in the bloom filter
65 * @param size number of bytes in data 66 * @param size number of bytes in data
66 * @param data content stored 67 * @param data content stored
67 * @param type type of the content 68 * @param type type of the content
@@ -73,11 +74,17 @@ template_plugin_estimate_size (void *cls, unsigned long long *estimate)
73 * @param cont_cls continuation closure 74 * @param cont_cls continuation closure
74 */ 75 */
75static void 76static void
76template_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t size, 77template_plugin_put (void *cls,
77 const void *data, enum GNUNET_BLOCK_Type type, 78 const struct GNUNET_HashCode *key,
78 uint32_t priority, uint32_t anonymity, 79 bool absent,
80 uint32_t size,
81 const void *data,
82 enum GNUNET_BLOCK_Type type,
83 uint32_t priority,
84 uint32_t anonymity,
79 uint32_t replication, 85 uint32_t replication,
80 struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, 86 struct GNUNET_TIME_Absolute expiration,
87 PluginPutCont cont,
81 void *cont_cls) 88 void *cont_cls)
82{ 89{
83 GNUNET_break (0); 90 GNUNET_break (0);
@@ -151,39 +158,6 @@ template_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
151 158
152 159
153/** 160/**
154 * Update the priority, replication and expiration for a particular
155 * unique ID in the datastore. If the expiration time in value is
156 * different than the time found in the datastore, the higher value
157 * should be kept. The specified priority and replication is added
158 * to the existing value.
159 *
160 * @param cls our "struct Plugin*"
161 * @param uid unique identifier of the datum
162 * @param priority by how much should the priority
163 * change?
164 * @param replication by how much should the replication
165 * change?
166 * @param expire new expiration time should be the
167 * MAX of any existing expiration time and
168 * this value
169 * @param cont continuation called with success or failure status
170 * @param cons_cls continuation closure
171 */
172static void
173template_plugin_update (void *cls,
174 uint64_t uid,
175 uint32_t priority,
176 uint32_t replication,
177 struct GNUNET_TIME_Absolute expire,
178 PluginUpdateCont cont,
179 void *cont_cls)
180{
181 GNUNET_break (0);
182 cont (cont_cls, GNUNET_SYSERR, "not implemented");
183}
184
185
186/**
187 * Call the given processor on an item with zero anonymity. 161 * Call the given processor on an item with zero anonymity.
188 * 162 *
189 * @param cls our "struct Plugin*" 163 * @param cls our "struct Plugin*"
@@ -248,7 +222,6 @@ libgnunet_plugin_datastore_template_init (void *cls)
248 api->cls = plugin; 222 api->cls = plugin;
249 api->estimate_size = &template_plugin_estimate_size; 223 api->estimate_size = &template_plugin_estimate_size;
250 api->put = &template_plugin_put; 224 api->put = &template_plugin_put;
251 api->update = &template_plugin_update;
252 api->get_key = &template_plugin_get_key; 225 api->get_key = &template_plugin_get_key;
253 api->get_replication = &template_plugin_get_replication; 226 api->get_replication = &template_plugin_get_replication;
254 api->get_expiration = &template_plugin_get_expiration; 227 api->get_expiration = &template_plugin_get_expiration;
diff --git a/src/datastore/test_plugin_datastore.c b/src/datastore/test_plugin_datastore.c
index 1867d6755..0c34a5f66 100644
--- a/src/datastore/test_plugin_datastore.c
+++ b/src/datastore/test_plugin_datastore.c
@@ -49,7 +49,6 @@ enum RunPhase
49 RP_ERROR = 0, 49 RP_ERROR = 0,
50 RP_PUT, 50 RP_PUT,
51 RP_GET, 51 RP_GET,
52 RP_UPDATE,
53 RP_ITER_ZERO, 52 RP_ITER_ZERO,
54 RP_REPL_GET, 53 RP_REPL_GET,
55 RP_EXPI_GET, 54 RP_EXPI_GET,
@@ -168,8 +167,13 @@ do_put (struct CpsRunContext *crc)
168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
169 "putting type %u, anon %u under key %s\n", i + 1, i, 168 "putting type %u, anon %u under key %s\n", i + 1, i,
170 GNUNET_h2s (&key)); 169 GNUNET_h2s (&key));
171 crc->api->put (crc->api->cls, &key, size, value, i + 1 /* type */ , 170 crc->api->put (crc->api->cls,
172 prio, i /* anonymity */ , 171 &key,
172 false /* absent */,
173 size,
174 value, i + 1 /* type */ ,
175 prio,
176 i /* anonymity */ ,
173 0 /* replication */ , 177 0 /* replication */ ,
174 GNUNET_TIME_relative_to_absolute 178 GNUNET_TIME_relative_to_absolute
175 (GNUNET_TIME_relative_multiply 179 (GNUNET_TIME_relative_multiply
@@ -177,7 +181,8 @@ do_put (struct CpsRunContext *crc)
177 60 * 60 * 60 * 1000 + 181 60 * 60 * 60 * 1000 +
178 GNUNET_CRYPTO_random_u32 182 GNUNET_CRYPTO_random_u32
179 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), 183 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))),
180 put_continuation, crc); 184 put_continuation,
185 crc);
181 i++; 186 i++;
182} 187}
183 188
@@ -264,19 +269,6 @@ cleaning_task (void *cls)
264 269
265 270
266static void 271static void
267update_continuation (void *cls,
268 int status,
269 const char *msg)
270{
271 struct CpsRunContext *crc = cls;
272
273 GNUNET_assert (GNUNET_OK == status);
274 crc->phase++;
275 GNUNET_SCHEDULER_add_now (&test, crc);
276}
277
278
279static void
280test (void *cls) 272test (void *cls)
281{ 273{
282 struct CpsRunContext *crc = cls; 274 struct CpsRunContext *crc = cls;
@@ -316,16 +308,6 @@ test (void *cls)
316 &iterate_one_shot, 308 &iterate_one_shot,
317 crc); 309 crc);
318 break; 310 break;
319 case RP_UPDATE:
320 crc->api->update (crc->api->cls,
321 guid,
322 1,
323 1,
324 GNUNET_TIME_UNIT_ZERO_ABS,
325 &update_continuation,
326 crc);
327 break;
328
329 case RP_ITER_ZERO: 311 case RP_ITER_ZERO:
330 if (crc->cnt == 1) 312 if (crc->cnt == 1)
331 { 313 {