aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/plugin_datastore_heap.c
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-04-16 20:46:21 -0500
committerDavid Barksdale <amatus@amat.us>2017-04-16 20:49:27 -0500
commita58d36b8da7afa42410bac54f57d5f3b6b6c4391 (patch)
tree87b00f07dda6a5c28a9d65ef9c05044cab2336fd /src/datastore/plugin_datastore_heap.c
parent4907330f51ffd48af1f7bac6f43c7c7f78c37818 (diff)
downloadgnunet-a58d36b8da7afa42410bac54f57d5f3b6b6c4391.tar.gz
gnunet-a58d36b8da7afa42410bac54f57d5f3b6b6c4391.zip
[datastore] Create remove plugin API call
The only use of vhash in the get_key call was for removing, split that out into its own function. This simplifies the get_key call and removes the need for some indexes, speeding up insertion into the database.
Diffstat (limited to 'src/datastore/plugin_datastore_heap.c')
-rw-r--r--src/datastore/plugin_datastore_heap.c202
1 files changed, 139 insertions, 63 deletions
diff --git a/src/datastore/plugin_datastore_heap.c b/src/datastore/plugin_datastore_heap.c
index 6dbc15ebd..9950f7ab2 100644
--- a/src/datastore/plugin_datastore_heap.c
+++ b/src/datastore/plugin_datastore_heap.c
@@ -433,11 +433,6 @@ struct GetContext
433 struct Value *value; 433 struct Value *value;
434 434
435 /** 435 /**
436 * Requested value hash.
437 */
438 const struct GNUNET_HashCode *vhash;
439
440 /**
441 * Requested type. 436 * Requested type.
442 */ 437 */
443 enum GNUNET_BLOCK_Type type; 438 enum GNUNET_BLOCK_Type type;
@@ -465,17 +460,10 @@ get_iterator (void *cls,
465{ 460{
466 struct GetContext *gc = cls; 461 struct GetContext *gc = cls;
467 struct Value *value = val; 462 struct Value *value = val;
468 struct GNUNET_HashCode vh;
469 463
470 if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) && 464 if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) &&
471 (gc->type != value->type) ) 465 (gc->type != value->type) )
472 return GNUNET_OK; 466 return GNUNET_OK;
473 if (NULL != gc->vhash)
474 {
475 GNUNET_CRYPTO_hash (&value[1], value->size, &vh);
476 if (0 != memcmp (&vh, gc->vhash, sizeof (struct GNUNET_HashCode)))
477 return GNUNET_OK;
478 }
479 if (gc->random) 467 if (gc->random)
480 { 468 {
481 gc->value = value; 469 gc->value = value;
@@ -498,23 +486,20 @@ get_iterator (void *cls,
498 * @param next_uid return the result with lowest uid >= next_uid 486 * @param next_uid return the result with lowest uid >= next_uid
499 * @param random if true, return a random result instead of using next_uid 487 * @param random if true, return a random result instead of using next_uid
500 * @param key maybe NULL (to match all entries) 488 * @param key maybe NULL (to match all entries)
501 * @param vhash hash of the value, maybe NULL (to
502 * match all values that have the right key).
503 * Note that for DBlocks there is no difference
504 * betwen key and vhash, but for other blocks
505 * there may be!
506 * @param type entries of which type are relevant? 489 * @param type entries of which type are relevant?
507 * Use 0 for any type. 490 * Use 0 for any type.
508 * @param proc function to call on each matching value; 491 * @param proc function to call on the matching value;
509 * will be called with NULL if nothing matches 492 * will be called with NULL if nothing matches
510 * @param proc_cls closure for proc 493 * @param proc_cls closure for @a proc
511 */ 494 */
512static void 495static void
513heap_plugin_get_key (void *cls, uint64_t next_uid, bool random, 496heap_plugin_get_key (void *cls,
514 const struct GNUNET_HashCode *key, 497 uint64_t next_uid,
515 const struct GNUNET_HashCode *vhash, 498 bool random,
516 enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, 499 const struct GNUNET_HashCode *key,
517 void *proc_cls) 500 enum GNUNET_BLOCK_Type type,
501 PluginDatumProcessor proc,
502 void *proc_cls)
518{ 503{
519 struct Plugin *plugin = cls; 504 struct Plugin *plugin = cls;
520 struct GetContext gc; 505 struct GetContext gc;
@@ -522,7 +507,6 @@ heap_plugin_get_key (void *cls, uint64_t next_uid, bool random,
522 gc.value = NULL; 507 gc.value = NULL;
523 gc.next_uid = next_uid; 508 gc.next_uid = next_uid;
524 gc.random = random; 509 gc.random = random;
525 gc.vhash = vhash;
526 gc.type = type; 510 gc.type = type;
527 if (NULL == key) 511 if (NULL == key)
528 { 512 {
@@ -542,20 +526,17 @@ heap_plugin_get_key (void *cls, uint64_t next_uid, bool random,
542 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 526 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
543 return; 527 return;
544 } 528 }
545 if (GNUNET_NO == 529 GNUNET_assert (GNUNET_OK ==
546 proc (proc_cls, 530 proc (proc_cls,
547 &gc.value->key, 531 &gc.value->key,
548 gc.value->size, 532 gc.value->size,
549 &gc.value[1], 533 &gc.value[1],
550 gc.value->type, 534 gc.value->type,
551 gc.value->priority, 535 gc.value->priority,
552 gc.value->anonymity, 536 gc.value->anonymity,
553 gc.value->replication, 537 gc.value->replication,
554 gc.value->expiration, 538 gc.value->expiration,
555 (uint64_t) (intptr_t) gc.value)) 539 (uint64_t) (intptr_t) gc.value));
556 {
557 delete_value (plugin, gc.value);
558 }
559} 540}
560 541
561 542
@@ -599,18 +580,17 @@ heap_plugin_get_replication (void *cls,
599 value->replication); 580 value->replication);
600 value = GNUNET_CONTAINER_heap_walk_get_next (plugin->by_replication); 581 value = GNUNET_CONTAINER_heap_walk_get_next (plugin->by_replication);
601 } 582 }
602 if (GNUNET_NO == 583 GNUNET_assert (GNUNET_OK ==
603 proc (proc_cls, 584 proc (proc_cls,
604 &value->key, 585 &value->key,
605 value->size, 586 value->size,
606 &value[1], 587 &value[1],
607 value->type, 588 value->type,
608 value->priority, 589 value->priority,
609 value->anonymity, 590 value->anonymity,
610 value->replication, 591 value->replication,
611 value->expiration, 592 value->expiration,
612 (uint64_t) (intptr_t) value)) 593 (uint64_t) (intptr_t) value));
613 delete_value (plugin, value);
614} 594}
615 595
616 596
@@ -690,18 +670,17 @@ heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
690 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 670 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
691 return; 671 return;
692 } 672 }
693 if (GNUNET_NO == 673 GNUNET_assert (GNUNET_OK ==
694 proc (proc_cls, 674 proc (proc_cls,
695 &value->key, 675 &value->key,
696 value->size, 676 value->size,
697 &value[1], 677 &value[1],
698 value->type, 678 value->type,
699 value->priority, 679 value->priority,
700 value->anonymity, 680 value->anonymity,
701 value->replication, 681 value->replication,
702 value->expiration, 682 value->expiration,
703 (uint64_t) (intptr_t) value)) 683 (uint64_t) (intptr_t) value));
704 delete_value (plugin, value);
705} 684}
706 685
707 686
@@ -779,6 +758,102 @@ heap_get_keys (void *cls,
779 758
780 759
781/** 760/**
761 * Closure for iterator called during 'remove_key'.
762 */
763struct RemoveContext
764{
765
766 /**
767 * Value found.
768 */
769 struct Value *value;
770
771 /**
772 * Size of data.
773 */
774 uint32_t size;
775
776 /**
777 * Data to remove.
778 */
779 const void *data;
780
781};
782
783
784/**
785 * Obtain the matching value with the lowest uid >= next_uid.
786 *
787 * @param cls the 'struct GetContext'
788 * @param key unused
789 * @param val the 'struct Value'
790 * @return GNUNET_YES (continue iteration), GNUNET_NO if result was found
791 */
792static int
793remove_iterator (void *cls,
794 const struct GNUNET_HashCode *key,
795 void *val)
796{
797 struct RemoveContext *rc = cls;
798 struct Value *value = val;
799
800 if (value->size != rc->size)
801 return GNUNET_YES;
802 if (0 != memcmp (value->data, rc->data, rc->size))
803 return GNUNET_YES;
804 rc->value = value;
805 return GNUNET_NO;
806}
807
808
809/**
810 * Remove a particular key in the datastore.
811 *
812 * @param cls closure
813 * @param key key for the content
814 * @param size number of bytes in data
815 * @param data content stored
816 * @param cont continuation called with success or failure status
817 * @param cont_cls continuation closure for @a cont
818 */
819static void
820heap_plugin_remove_key (void *cls,
821 const struct GNUNET_HashCode *key,
822 uint32_t size,
823 const void *data,
824 PluginRemoveCont cont,
825 void *cont_cls)
826{
827 struct Plugin *plugin = cls;
828 struct RemoveContext rc;
829
830 rc.value = NULL;
831 rc.size = size;
832 rc.data = data;
833 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue,
834 key,
835 &remove_iterator,
836 &rc);
837 if (NULL == rc.value)
838 {
839 cont (cont_cls,
840 key,
841 size,
842 GNUNET_NO,
843 NULL);
844 return;
845 }
846 delete_value (plugin,
847 rc.value);
848 cont (cont_cls,
849 key,
850 size,
851 GNUNET_OK,
852 NULL);
853}
854
855
856/**
782 * Entry point for the plugin. 857 * Entry point for the plugin.
783 * 858 *
784 * @param cls the "struct GNUNET_DATASTORE_PluginEnvironment*" 859 * @param cls the "struct GNUNET_DATASTORE_PluginEnvironment*"
@@ -813,6 +888,7 @@ libgnunet_plugin_datastore_heap_init (void *cls)
813 api->get_zero_anonymity = &heap_plugin_get_zero_anonymity; 888 api->get_zero_anonymity = &heap_plugin_get_zero_anonymity;
814 api->drop = &heap_plugin_drop; 889 api->drop = &heap_plugin_drop;
815 api->get_keys = &heap_get_keys; 890 api->get_keys = &heap_get_keys;
891 api->remove_key = &heap_plugin_remove_key;
816 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "heap", 892 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "heap",
817 _("Heap database running\n")); 893 _("Heap database running\n"));
818 return api; 894 return api;