diff options
author | David Barksdale <amatus@amat.us> | 2017-04-16 12:39:43 -0500 |
---|---|---|
committer | David Barksdale <amatus@amat.us> | 2017-04-16 12:42:34 -0500 |
commit | 4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch) | |
tree | a2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/plugin_datastore_heap.c | |
parent | cacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff) | |
download | gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip |
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore/plugin_datastore_heap.c')
-rw-r--r-- | src/datastore/plugin_datastore_heap.c | 170 |
1 files changed, 109 insertions, 61 deletions
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; |