diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-04-25 16:18:31 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-04-25 16:18:31 +0200 |
commit | 4dc79497d7f745996068e62e973e34d220580323 (patch) | |
tree | e6d429d3cf2240ec3459f1d4533201dc40b27015 /src/namestore/plugin_namestore_flat.c | |
parent | bdbb7c684f2c9711989d2543ecc08a95be23e6c4 (diff) | |
download | gnunet-4dc79497d7f745996068e62e973e34d220580323.tar.gz gnunet-4dc79497d7f745996068e62e973e34d220580323.zip |
extend namestore API to enable faster iterations by returning more than one result at a time
Diffstat (limited to 'src/namestore/plugin_namestore_flat.c')
-rw-r--r-- | src/namestore/plugin_namestore_flat.c | 100 |
1 files changed, 73 insertions, 27 deletions
diff --git a/src/namestore/plugin_namestore_flat.c b/src/namestore/plugin_namestore_flat.c index 305fe7ba1..e9ed1cc4f 100644 --- a/src/namestore/plugin_namestore_flat.c +++ b/src/namestore/plugin_namestore_flat.c | |||
@@ -86,6 +86,7 @@ struct Plugin | |||
86 | 86 | ||
87 | }; | 87 | }; |
88 | 88 | ||
89 | |||
89 | struct FlatFileEntry | 90 | struct FlatFileEntry |
90 | { | 91 | { |
91 | /** | 92 | /** |
@@ -501,9 +502,7 @@ namestore_flat_lookup_records (void *cls, | |||
501 | size_t key_len; | 502 | size_t key_len; |
502 | 503 | ||
503 | if (NULL == zone) | 504 | if (NULL == zone) |
504 | { | ||
505 | return GNUNET_SYSERR; | 505 | return GNUNET_SYSERR; |
506 | } | ||
507 | key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); | 506 | key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); |
508 | key = GNUNET_malloc (key_len); | 507 | key = GNUNET_malloc (key_len); |
509 | GNUNET_memcpy (key, | 508 | GNUNET_memcpy (key, |
@@ -532,30 +531,77 @@ namestore_flat_lookup_records (void *cls, | |||
532 | } | 531 | } |
533 | 532 | ||
534 | 533 | ||
534 | /** | ||
535 | * Closure for #iterate_zones. | ||
536 | */ | ||
537 | struct IterateContext | ||
538 | { | ||
539 | /** | ||
540 | * How many more records should we skip before returning results? | ||
541 | */ | ||
542 | uint64_t offset; | ||
543 | |||
544 | /** | ||
545 | * How many more records should we return? | ||
546 | */ | ||
547 | uint64_t limit; | ||
548 | |||
549 | /** | ||
550 | * Target zone. | ||
551 | */ | ||
552 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone; | ||
553 | |||
554 | /** | ||
555 | * Function to call on each record. | ||
556 | */ | ||
557 | GNUNET_NAMESTORE_RecordIterator iter; | ||
558 | |||
559 | /** | ||
560 | * Closure for @e iter. | ||
561 | */ | ||
562 | void *iter_cls; | ||
563 | |||
564 | }; | ||
565 | |||
566 | |||
567 | /** | ||
568 | * Helper function for #namestore_flat_iterate_records(). | ||
569 | * | ||
570 | * @param cls a `struct IterateContext` | ||
571 | * @param key unused | ||
572 | * @param value a `struct FlatFileEntry` | ||
573 | * @return #GNUNET_YES to continue the iteration | ||
574 | */ | ||
535 | static int | 575 | static int |
536 | iterate_zones (void *cls, | 576 | iterate_zones (void *cls, |
537 | const struct GNUNET_HashCode *key, | 577 | const struct GNUNET_HashCode *key, |
538 | void *value) | 578 | void *value) |
539 | { | 579 | { |
540 | struct Plugin *plugin = cls; | 580 | struct IterateContext *ic = cls; |
541 | struct FlatFileEntry *entry = value; | 581 | struct FlatFileEntry *entry = value; |
542 | 582 | ||
543 | (void) key; | 583 | (void) key; |
544 | if ((plugin->target_offset > plugin->offset) || | 584 | if (0 == ic->limit) |
545 | ( (NULL != plugin->iter_zone) && | 585 | return GNUNET_NO; |
546 | (0 != memcmp (entry->private_key, | 586 | if ( (NULL != it->zone) && |
547 | plugin->iter_zone, | 587 | (0 != memcmp (entry->private_key, |
548 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))))) { | 588 | ic->zone, |
549 | plugin->offset++; | 589 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) ) |
590 | return GNUNET_YES; | ||
591 | if (ic->offset > 0) | ||
592 | { | ||
593 | ic->offset--; | ||
550 | return GNUNET_YES; | 594 | return GNUNET_YES; |
551 | } | 595 | } |
552 | plugin->iter (plugin->iter_cls, | 596 | ic->iter (ic->iter_cls, |
553 | entry->private_key, | 597 | entry->private_key, |
554 | entry->label, | 598 | entry->label, |
555 | entry->record_count, | 599 | entry->record_count, |
556 | entry->record_data); | 600 | entry->record_data); |
557 | plugin->iter_result_found = GNUNET_YES; | 601 | ic->limit--; |
558 | return GNUNET_NO; | 602 | if (0 == ic->limit) |
603 | return GNUNET_NO; | ||
604 | return GNUNET_YES; | ||
559 | } | 605 | } |
560 | 606 | ||
561 | 607 | ||
@@ -566,31 +612,31 @@ iterate_zones (void *cls, | |||
566 | * @param cls closure (internal context for the plugin) | 612 | * @param cls closure (internal context for the plugin) |
567 | * @param zone hash of public key of the zone, NULL to iterate over all zones | 613 | * @param zone hash of public key of the zone, NULL to iterate over all zones |
568 | * @param offset offset in the list of all matching records | 614 | * @param offset offset in the list of all matching records |
615 | * @param limit maximum number of results to return to @a iter | ||
569 | * @param iter function to call with the result | 616 | * @param iter function to call with the result |
570 | * @param iter_cls closure for @a iter | 617 | * @param iter_cls closure for @a iter |
571 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | 618 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no more results, #GNUNET_SYSERR on error |
572 | */ | 619 | */ |
573 | static int | 620 | static int |
574 | namestore_flat_iterate_records (void *cls, | 621 | namestore_flat_iterate_records (void *cls, |
575 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 622 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, |
576 | uint64_t offset, | 623 | uint64_t offset, |
624 | uint64_t limit, | ||
577 | GNUNET_NAMESTORE_RecordIterator iter, | 625 | GNUNET_NAMESTORE_RecordIterator iter, |
578 | void *iter_cls) | 626 | void *iter_cls) |
579 | { | 627 | { |
580 | struct Plugin *plugin = cls; | 628 | struct Plugin *plugin = cls; |
629 | struct IterateContext ic; | ||
581 | 630 | ||
582 | /* FIXME: maybe use separate closure to better handle | 631 | ic.offset = offset; |
583 | recursive calls? */ | 632 | ic.limit = limit; |
584 | plugin->target_offset = offset; | 633 | ic.iter = iter; |
585 | plugin->offset = 0; | 634 | ic.iter_cls = iter_cls; |
586 | plugin->iter = iter; | 635 | ic.zone = zone; |
587 | plugin->iter_cls = iter_cls; | ||
588 | plugin->iter_zone = zone; | ||
589 | plugin->iter_result_found = GNUNET_NO; | ||
590 | GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, | 636 | GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, |
591 | &iterate_zones, | 637 | &iterate_zones, |
592 | plugin); | 638 | &ic); |
593 | return plugin->iter_result_found; | 639 | return (0 == ic.limit) ? GNUNET_OK : GNUNET_NO; |
594 | } | 640 | } |
595 | 641 | ||
596 | 642 | ||