aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_namestore_flat.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-04-25 16:18:31 +0200
committerChristian Grothoff <christian@grothoff.org>2018-04-25 16:18:31 +0200
commit4dc79497d7f745996068e62e973e34d220580323 (patch)
treee6d429d3cf2240ec3459f1d4533201dc40b27015 /src/namestore/plugin_namestore_flat.c
parentbdbb7c684f2c9711989d2543ecc08a95be23e6c4 (diff)
downloadgnunet-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.c100
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
89struct FlatFileEntry 90struct 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 */
537struct 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 */
535static int 575static int
536iterate_zones (void *cls, 576iterate_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 */
573static int 620static int
574namestore_flat_iterate_records (void *cls, 621namestore_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