aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-12-11 19:27:34 +0100
committerChristian Grothoff <christian@grothoff.org>2018-12-11 19:27:34 +0100
commitc1dd4d02762d51d1ac4078407cda2796aff8faf4 (patch)
tree612004af9190770e9c75235005873c92afc862c4 /src/namestore
parentb362752b69f705754327dfb7e025260d97289ad9 (diff)
downloadgnunet-c1dd4d02762d51d1ac4078407cda2796aff8faf4.tar.gz
gnunet-c1dd4d02762d51d1ac4078407cda2796aff8faf4.zip
cache NICK results in namestore to avoid unnecessary load on the DB; improve sqlite DB style, use WAL for sqlite DB
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/gnunet-service-namestore.c106
-rw-r--r--src/namestore/plugin_namestore_sqlite.c1
2 files changed, 106 insertions, 1 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index d9fa5b3fc..d9e9a9e82 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -46,6 +46,10 @@
46 */ 46 */
47#define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES 47#define MONITOR_STALL_WARN_DELAY GNUNET_TIME_UNIT_MINUTES
48 48
49/**
50 * Size of the cache used by #get_nick_record()
51 */
52#define NC_SIZE 16
49 53
50/** 54/**
51 * A namestore client 55 * A namestore client
@@ -292,6 +296,33 @@ struct StoreActivity
292 296
293 297
294/** 298/**
299 * Entry in list of cached nick resolutions.
300 */
301struct NickCache
302{
303 /**
304 * Zone the cache entry is for.
305 */
306 struct GNUNET_CRYPTO_EcdsaPrivateKey zone;
307
308 /**
309 * Cached record data.
310 */
311 struct GNUNET_GNSRECORD_Data *rd;
312
313 /**
314 * Timestamp when this cache entry was used last.
315 */
316 struct GNUNET_TIME_Absolute last_used;
317};
318
319
320/**
321 * We cache nick records to reduce DB load.
322 */
323static struct NickCache nick_cache[NC_SIZE];
324
325/**
295 * Public key of all zeros. 326 * Public key of all zeros.
296 */ 327 */
297static const struct GNUNET_CRYPTO_EcdsaPrivateKey zero; 328static const struct GNUNET_CRYPTO_EcdsaPrivateKey zero;
@@ -481,6 +512,48 @@ lookup_nick_it (void *cls,
481 512
482 513
483/** 514/**
515 * Add entry to the cache for @a zone and @a nick
516 *
517 * @param zone zone key to cache under
518 * @param nick nick entry to cache
519 */
520static void
521cache_nick (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
522 const struct GNUNET_GNSRECORD_Data *nick)
523{
524 struct NickCache *oldest;
525
526 oldest = NULL;
527 for (unsigned int i=0;i<NC_SIZE;i++)
528 {
529 struct NickCache *pos = &nick_cache[i];
530
531 if ( (NULL == oldest) ||
532 (oldest->last_used.abs_value_us >
533 pos->last_used.abs_value_us) )
534 oldest = pos;
535 if (0 == memcmp (zone,
536 &pos->zone,
537 sizeof (*zone)))
538 {
539 oldest = pos;
540 break;
541 }
542 }
543 GNUNET_free_non_null (oldest->rd);
544 oldest->zone = *zone;
545 oldest->rd = GNUNET_malloc (sizeof (*nick) +
546 nick->data_size);
547 *oldest->rd = *nick;
548 oldest->rd->data = &oldest->rd[1];
549 memcpy (&oldest->rd[1],
550 nick->data,
551 nick->data_size);
552 oldest->last_used = GNUNET_TIME_absolute_get ();
553}
554
555
556/**
484 * Return the NICK record for the zone (if it exists). 557 * Return the NICK record for the zone (if it exists).
485 * 558 *
486 * @param zone private key for the zone to look for nick 559 * @param zone private key for the zone to look for nick
@@ -493,6 +566,27 @@ get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone)
493 struct GNUNET_GNSRECORD_Data *nick; 566 struct GNUNET_GNSRECORD_Data *nick;
494 int res; 567 int res;
495 568
569 /* check cache first */
570 for (unsigned int i=0;i<NC_SIZE;i++)
571 {
572 struct NickCache *pos = &nick_cache[i];
573 if ( (NULL != pos->rd) &&
574 (0 == memcmp (zone,
575 &pos->zone,
576 sizeof (*zone))) )
577 {
578 nick = GNUNET_malloc (sizeof (*nick) +
579 pos->rd->data_size);
580 *nick = *pos->rd;
581 nick->data = &nick[1];
582 memcpy (&nick[1],
583 pos->rd->data,
584 pos->rd->data_size);
585 pos->last_used = GNUNET_TIME_absolute_get ();
586 return nick;
587 }
588 }
589
496 nick = NULL; 590 nick = NULL;
497 res = GSN_database->lookup_records (GSN_database->cls, 591 res = GSN_database->lookup_records (GSN_database->cls,
498 zone, 592 zone,
@@ -508,6 +602,10 @@ get_nick_record (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone)
508 GNUNET_GNSRECORD_z2s (&pub)); 602 GNUNET_GNSRECORD_z2s (&pub));
509 return NULL; 603 return NULL;
510 } 604 }
605
606 /* update cache */
607 cache_nick (zone,
608 nick);
511 return nick; 609 return nick;
512} 610}
513 611
@@ -663,7 +761,7 @@ send_lookup_response (struct NamestoreClient *nc,
663 GNUNET_SERVICE_client_drop (nc->client); 761 GNUNET_SERVICE_client_drop (nc->client);
664 return; 762 return;
665 } 763 }
666 if (rd_ser_len >= UINT16_MAX - name_len - sizeof (*zir_msg)) 764 if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof (*zir_msg))
667 { 765 {
668 GNUNET_break (0); 766 GNUNET_break (0);
669 GNUNET_SERVICE_client_drop (nc->client); 767 GNUNET_SERVICE_client_drop (nc->client);
@@ -1445,6 +1543,12 @@ handle_record_store (void *cls,
1445 conv_name)) || 1543 conv_name)) ||
1446 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type) ) 1544 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type) )
1447 rd_clean_off++; 1545 rd_clean_off++;
1546
1547 if ( (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT,
1548 conv_name)) &&
1549 (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) )
1550 cache_nick (&rp_msg->private_key,
1551 &rd[i]);
1448 } 1552 }
1449 res = GSN_database->store_records (GSN_database->cls, 1553 res = GSN_database->store_records (GSN_database->cls,
1450 &rp_msg->private_key, 1554 &rp_msg->private_key,
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index 23af3960d..e68a47a7b 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -122,6 +122,7 @@ database_setup (struct Plugin *plugin)
122 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"), 122 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
123 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""), 123 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
124 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"), 124 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
125 GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
125 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"), 126 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
126 GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records (" 127 GNUNET_SQ_make_execute ("CREATE TABLE IF NOT EXISTS ns098records ("
127 " uid INTEGER PRIMARY KEY," 128 " uid INTEGER PRIMARY KEY,"