aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/arm/gnunet-arm.c17
-rw-r--r--src/namecache/plugin_namecache_sqlite.c63
-rw-r--r--src/namestore/gnunet-service-namestore.c106
-rw-r--r--src/namestore/plugin_namestore_sqlite.c1
4 files changed, 142 insertions, 45 deletions
diff --git a/src/arm/gnunet-arm.c b/src/arm/gnunet-arm.c
index 28d1f7592..fa0374bc5 100644
--- a/src/arm/gnunet-arm.c
+++ b/src/arm/gnunet-arm.c
@@ -74,7 +74,7 @@ static char *term;
74/** 74/**
75 * Set to the name of the config file used. 75 * Set to the name of the config file used.
76 */ 76 */
77static const char *config_file; 77static char *config_file;
78 78
79/** 79/**
80 * Set to the directory where runtime files are stored. 80 * Set to the directory where runtime files are stored.
@@ -172,6 +172,7 @@ delete_files ()
172static void 172static void
173shutdown_task (void *cls) 173shutdown_task (void *cls)
174{ 174{
175 (void) cls;
175 if (NULL != al_task) 176 if (NULL != al_task)
176 { 177 {
177 GNUNET_SCHEDULER_cancel (al_task); 178 GNUNET_SCHEDULER_cancel (al_task);
@@ -284,6 +285,7 @@ conn_status (void *cls,
284{ 285{
285 static int once; 286 static int once;
286 287
288 (void) cls;
287 if ( (GNUNET_SYSERR == connected) && 289 if ( (GNUNET_SYSERR == connected) &&
288 (0 == once) ) 290 (0 == once) )
289 { 291 {
@@ -312,6 +314,7 @@ start_callback (void *cls,
312 enum GNUNET_ARM_RequestStatus rs, 314 enum GNUNET_ARM_RequestStatus rs,
313 enum GNUNET_ARM_Result result) 315 enum GNUNET_ARM_Result result)
314{ 316{
317 (void) cls;
315 op = NULL; 318 op = NULL;
316 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 319 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
317 { 320 {
@@ -355,6 +358,7 @@ stop_callback (void *cls,
355{ 358{
356 char *msg; 359 char *msg;
357 360
361 (void) cls;
358 op = NULL; 362 op = NULL;
359 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 363 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
360 { 364 {
@@ -405,6 +409,7 @@ init_callback (void *cls,
405 enum GNUNET_ARM_RequestStatus rs, 409 enum GNUNET_ARM_RequestStatus rs,
406 enum GNUNET_ARM_Result result) 410 enum GNUNET_ARM_Result result)
407{ 411{
412 (void) cls;
408 op = NULL; 413 op = NULL;
409 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 414 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
410 { 415 {
@@ -452,6 +457,7 @@ term_callback (void *cls,
452{ 457{
453 char *msg; 458 char *msg;
454 459
460 (void) cls;
455 op = NULL; 461 op = NULL;
456 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 462 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
457 { 463 {
@@ -501,6 +507,7 @@ list_callback (void *cls,
501{ 507{
502 unsigned int i; 508 unsigned int i;
503 509
510 (void) cls;
504 op = NULL; 511 op = NULL;
505 if (GNUNET_ARM_REQUEST_SENT_OK != rs) 512 if (GNUNET_ARM_REQUEST_SENT_OK != rs)
506 { 513 {
@@ -538,6 +545,7 @@ list_callback (void *cls,
538static void 545static void
539action_loop (void *cls) 546action_loop (void *cls)
540{ 547{
548 (void) cls;
541 al_task = NULL; 549 al_task = NULL;
542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
543 "Running requested actions\n"); 551 "Running requested actions\n");
@@ -637,6 +645,7 @@ srv_status (void *cls,
637{ 645{
638 const char *msg; 646 const char *msg;
639 647
648 (void) cls;
640 switch (status) 649 switch (status)
641 { 650 {
642 case GNUNET_ARM_SERVICE_MONITORING_STARTED: 651 case GNUNET_ARM_SERVICE_MONITORING_STARTED:
@@ -679,6 +688,7 @@ srv_status (void *cls,
679static void 688static void
680timeout_task_cb (void *cls) 689timeout_task_cb (void *cls)
681{ 690{
691 (void) cls;
682 timeout_task = NULL; 692 timeout_task = NULL;
683 ret = 2; 693 ret = 2;
684 GNUNET_SCHEDULER_shutdown (); 694 GNUNET_SCHEDULER_shutdown ();
@@ -699,8 +709,9 @@ run (void *cls,
699 const char *cfgfile, 709 const char *cfgfile,
700 const struct GNUNET_CONFIGURATION_Handle *c) 710 const struct GNUNET_CONFIGURATION_Handle *c)
701{ 711{
702 char *armconfig; 712 (void) cls;
703 713 (void) args;
714 (void) cfgfile;
704 cfg = GNUNET_CONFIGURATION_dup (c); 715 cfg = GNUNET_CONFIGURATION_dup (c);
705 if (GNUNET_OK != 716 if (GNUNET_OK !=
706 GNUNET_CONFIGURATION_get_value_string (cfg, 717 GNUNET_CONFIGURATION_get_value_string (cfg,
diff --git a/src/namecache/plugin_namecache_sqlite.c b/src/namecache/plugin_namecache_sqlite.c
index f67831708..b355d37ba 100644
--- a/src/namecache/plugin_namecache_sqlite.c
+++ b/src/namecache/plugin_namecache_sqlite.c
@@ -168,6 +168,18 @@ create_indices (sqlite3 * dbh)
168static int 168static int
169database_setup (struct Plugin *plugin) 169database_setup (struct Plugin *plugin)
170{ 170{
171 struct GNUNET_SQ_ExecuteStatement es[] = {
172 GNUNET_SQ_make_try_execute ("PRAGMA temp_store=MEMORY"),
173 GNUNET_SQ_make_try_execute ("PRAGMA synchronous=NORMAL"),
174 GNUNET_SQ_make_try_execute ("PRAGMA legacy_file_format=OFF"),
175 GNUNET_SQ_make_try_execute ("PRAGMA auto_vacuum=INCREMENTAL"),
176 GNUNET_SQ_make_try_execute ("PRAGMA encoding=\"UTF-8\""),
177 GNUNET_SQ_make_try_execute ("PRAGMA locking_mode=EXCLUSIVE"),
178 GNUNET_SQ_make_try_execute ("PRAGMA page_size=4092"),
179 GNUNET_SQ_make_try_execute ("PRAGMA journal_mode=WAL"),
180 GNUNET_SQ_EXECUTE_STATEMENT_END
181 };
182
171 sqlite3_stmt *stmt; 183 sqlite3_stmt *stmt;
172 char *afsdir; 184 char *afsdir;
173#if ENULL_DEFINED 185#if ENULL_DEFINED
@@ -208,47 +220,16 @@ database_setup (struct Plugin *plugin)
208 sqlite3_errmsg (plugin->dbh)); 220 sqlite3_errmsg (plugin->dbh));
209 return GNUNET_SYSERR; 221 return GNUNET_SYSERR;
210 } 222 }
211 CHECK (SQLITE_OK == 223 if (GNUNET_OK !=
212 sqlite3_exec (plugin->dbh, 224 GNUNET_SQ_exec_statements (plugin->dbh,
213 "PRAGMA temp_store=MEMORY", 225 es))
214 NULL, NULL, 226 {
215 ENULL)); 227 GNUNET_break (0);
216 CHECK (SQLITE_OK == 228 LOG (GNUNET_ERROR_TYPE_ERROR,
217 sqlite3_exec (plugin->dbh, 229 _("Failed to setup database at `%s'\n"),
218 "PRAGMA synchronous=NORMAL", 230 plugin->fn);
219 NULL, NULL, 231 return GNUNET_SYSERR;
220 ENULL)); 232 }
221 CHECK (SQLITE_OK ==
222 sqlite3_exec (plugin->dbh,
223 "PRAGMA legacy_file_format=OFF",
224 NULL, NULL,
225 ENULL));
226 CHECK (SQLITE_OK ==
227 sqlite3_exec (plugin->dbh,
228 "PRAGMA auto_vacuum=INCREMENTAL",
229 NULL, NULL,
230 ENULL));
231 CHECK (SQLITE_OK ==
232 sqlite3_exec (plugin->dbh,
233 "PRAGMA encoding=\"UTF-8\"",
234 NULL, NULL,
235 ENULL));
236 CHECK (SQLITE_OK ==
237 sqlite3_exec (plugin->dbh,
238 "PRAGMA locking_mode=EXCLUSIVE",
239 NULL, NULL,
240 ENULL));
241 CHECK (SQLITE_OK ==
242 sqlite3_exec (plugin->dbh,
243 "PRAGMA page_size=4092",
244 NULL, NULL,
245 ENULL));
246 CHECK (SQLITE_OK ==
247 sqlite3_exec (plugin->dbh,
248 "PRAGMA journal_mode=WAL",
249 NULL, NULL,
250 ENULL));
251
252 CHECK (SQLITE_OK == 233 CHECK (SQLITE_OK ==
253 sqlite3_busy_timeout (plugin->dbh, 234 sqlite3_busy_timeout (plugin->dbh,
254 BUSY_TIMEOUT_MS)); 235 BUSY_TIMEOUT_MS));
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,"