diff options
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 194 | ||||
-rw-r--r-- | src/datastore/perf_plugin_datastore.c | 13 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_heap.c | 170 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_mysql.c | 127 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_postgres.c | 129 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_sqlite.c | 149 | ||||
-rw-r--r-- | src/datastore/plugin_datastore_template.c | 49 | ||||
-rw-r--r-- | src/datastore/test_plugin_datastore.c | 36 | ||||
-rw-r--r-- | src/include/gnunet_datastore_plugin.h | 75 |
9 files changed, 345 insertions, 597 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 | */ | ||
739 | struct 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 | */ |
763 | static void | 745 | static void |
764 | put_continuation (void *cls, | 746 | put_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 | */ | ||
806 | static void | ||
807 | execute_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 | */ | ||
832 | static void | ||
833 | check_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 | */ | ||
863 | static int | ||
864 | check_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 | */ | ||
200 | struct 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 | */ | ||
242 | static int | ||
243 | update_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 | */ |
212 | static void | 291 | static void |
213 | heap_plugin_put (void *cls, | 292 | heap_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 | */ | ||
572 | static void | ||
573 | heap_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, | |||
343 | static void | 344 | static void |
344 | mysql_plugin_put (void *cls, | 345 | mysql_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 | */ | ||
433 | static void | ||
434 | mysql_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 | */ |
301 | static void | 302 | static void |
302 | postgres_plugin_put (void *cls, | 303 | postgres_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 | */ | ||
771 | static void | ||
772 | postgres_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, | |||
554 | static void | 555 | static void |
555 | sqlite_plugin_put (void *cls, | 556 | sqlite_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 | */ | ||
667 | static void | ||
668 | sqlite_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 | */ |
75 | static void | 76 | static void |
76 | template_plugin_put (void *cls, const struct GNUNET_HashCode * key, uint32_t size, | 77 | template_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 | */ | ||
172 | static void | ||
173 | template_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 | ||
266 | static void | 271 | static void |
267 | update_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 | |||
279 | static void | ||
280 | test (void *cls) | 272 | test (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 | { |
diff --git a/src/include/gnunet_datastore_plugin.h b/src/include/gnunet_datastore_plugin.h index 516ba525c..28c8241b1 100644 --- a/src/include/gnunet_datastore_plugin.h +++ b/src/include/gnunet_datastore_plugin.h | |||
@@ -134,7 +134,8 @@ typedef void | |||
134 | * @param cls closure | 134 | * @param cls closure |
135 | * @param key key for the item stored | 135 | * @param key key for the item stored |
136 | * @param size size of the item stored | 136 | * @param size size of the item stored |
137 | * @param status #GNUNET_OK or #GNUNET_SYSERROR | 137 | * @param status #GNUNET_OK if inserted, #GNUNET_NO if updated, |
138 | * or #GNUNET_SYSERROR if error | ||
138 | * @param msg error message on error | 139 | * @param msg error message on error |
139 | */ | 140 | */ |
140 | typedef void | 141 | typedef void |
@@ -152,6 +153,7 @@ typedef void | |||
152 | * | 153 | * |
153 | * @param cls closure | 154 | * @param cls closure |
154 | * @param key key for the item | 155 | * @param key key for the item |
156 | * @param absent true if the key was not found in the bloom filter | ||
155 | * @param size number of bytes in @a data | 157 | * @param size number of bytes in @a data |
156 | * @param data content stored | 158 | * @param data content stored |
157 | * @param type type of the content | 159 | * @param type type of the content |
@@ -165,15 +167,16 @@ typedef void | |||
165 | typedef void | 167 | typedef void |
166 | (*PluginPut) (void *cls, | 168 | (*PluginPut) (void *cls, |
167 | const struct GNUNET_HashCode *key, | 169 | const struct GNUNET_HashCode *key, |
168 | uint32_t size, | 170 | bool absent, |
169 | const void *data, | 171 | uint32_t size, |
170 | enum GNUNET_BLOCK_Type type, | 172 | const void *data, |
171 | uint32_t priority, | 173 | enum GNUNET_BLOCK_Type type, |
172 | uint32_t anonymity, | 174 | uint32_t priority, |
173 | uint32_t replication, | 175 | uint32_t anonymity, |
174 | struct GNUNET_TIME_Absolute expiration, | 176 | uint32_t replication, |
175 | PluginPutCont cont, | 177 | struct GNUNET_TIME_Absolute expiration, |
176 | void *cont_cls); | 178 | PluginPutCont cont, |
179 | void *cont_cls); | ||
177 | 180 | ||
178 | 181 | ||
179 | /** | 182 | /** |
@@ -248,48 +251,6 @@ typedef void | |||
248 | 251 | ||
249 | 252 | ||
250 | /** | 253 | /** |
251 | * Update continuation. | ||
252 | * | ||
253 | * @param cls closure | ||
254 | * @param status #GNUNET_OK or #GNUNET_SYSERR | ||
255 | * @param msg error message on error | ||
256 | */ | ||
257 | typedef void | ||
258 | (*PluginUpdateCont) (void *cls, | ||
259 | int status, | ||
260 | const char *msg); | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Update the priority, replication and expiration for a particular | ||
265 | * unique ID in the datastore. If the expiration time in value is | ||
266 | * different than the time found in the datastore, the higher value | ||
267 | * should be kept. The specified priority and replication is added | ||
268 | * to the existing value. | ||
269 | * | ||
270 | * @param cls closure | ||
271 | * @param uid unique identifier of the datum | ||
272 | * @param priority by how much should the priority | ||
273 | * change? | ||
274 | * @param replication by how much should the replication | ||
275 | * change? | ||
276 | * @param expire new expiration time should be the | ||
277 | * MAX of any existing expiration time and | ||
278 | * this value | ||
279 | * @param cont continuation called with success or failure status | ||
280 | * @param cons_cls continuation closure | ||
281 | */ | ||
282 | typedef void | ||
283 | (*PluginUpdate) (void *cls, | ||
284 | uint64_t uid, | ||
285 | uint32_t priority, | ||
286 | uint32_t replication, | ||
287 | struct GNUNET_TIME_Absolute expire, | ||
288 | PluginUpdateCont cont, | ||
289 | void *cont_cls); | ||
290 | |||
291 | |||
292 | /** | ||
293 | * Select a single item from the datastore (among those applicable). | 254 | * Select a single item from the datastore (among those applicable). |
294 | * | 255 | * |
295 | * @param cls closure | 256 | * @param cls closure |
@@ -342,16 +303,6 @@ struct GNUNET_DATASTORE_PluginFunctions | |||
342 | PluginPut put; | 303 | PluginPut put; |
343 | 304 | ||
344 | /** | 305 | /** |
345 | * Update the priority for a particular key in the datastore. If | ||
346 | * the expiration time in value is different than the time found in | ||
347 | * the datastore, the higher value should be kept. For the | ||
348 | * anonymity level, the lower value is to be used. The specified | ||
349 | * priority should be added to the existing priority, ignoring the | ||
350 | * priority in value. | ||
351 | */ | ||
352 | PluginUpdate update; | ||
353 | |||
354 | /** | ||
355 | * Get a particular datum matching a given hash from the datastore. | 306 | * Get a particular datum matching a given hash from the datastore. |
356 | */ | 307 | */ |
357 | PluginGetKey get_key; | 308 | PluginGetKey get_key; |