aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-service-fs_indexing.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-10-14 18:08:15 +0000
committerChristian Grothoff <christian@grothoff.org>2012-10-14 18:08:15 +0000
commita4582ea33040edb25b836eb4533ba085fe70752e (patch)
tree540631186b8b3e3215e994c5fc8470d1c70c39a6 /src/fs/gnunet-service-fs_indexing.c
parent3e5b028393108ce4708bec4a60cdf3e6df90c557 (diff)
downloadgnunet-a4582ea33040edb25b836eb4533ba085fe70752e.tar.gz
gnunet-a4582ea33040edb25b836eb4533ba085fe70752e.zip
-use DLL, nicer use of indexing map, improve ability to use future hash map memory optimization
Diffstat (limited to 'src/fs/gnunet-service-fs_indexing.c')
-rw-r--r--src/fs/gnunet-service-fs_indexing.c90
1 files changed, 47 insertions, 43 deletions
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index 1324b22d7..06c7eaf13 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -43,11 +43,16 @@ struct IndexInfo
43{ 43{
44 44
45 /** 45 /**
46 * This is a linked list. 46 * This is a doubly linked list.
47 */ 47 */
48 struct IndexInfo *next; 48 struct IndexInfo *next;
49 49
50 /** 50 /**
51 * This is a doubly linked list.
52 */
53 struct IndexInfo *prev;
54
55 /**
51 * Name of the indexed file. Memory allocated 56 * Name of the indexed file. Memory allocated
52 * at the end of this struct (do not free). 57 * at the end of this struct (do not free).
53 */ 58 */
@@ -73,12 +78,17 @@ struct IndexInfo
73 78
74 79
75/** 80/**
76 * Linked list of indexed files. 81 * Head of linked list of indexed files.
82 */
83static struct IndexInfo *indexed_files_head;
84
85/**
86 * Tail of linked list of indexed files.
77 */ 87 */
78static struct IndexInfo *indexed_files; 88static struct IndexInfo *indexed_files_tail;
79 89
80/** 90/**
81 * Maps hash over content of indexed files to the respective filename. 91 * Maps hash over content of indexed files to the respective 'struct IndexInfo'.
82 * The filenames are pointers into the indexed_files linked list and 92 * The filenames are pointers into the indexed_files linked list and
83 * do not need to be freed. 93 * do not need to be freed.
84 */ 94 */
@@ -121,15 +131,11 @@ write_index_list ()
121 GNUNET_free (fn); 131 GNUNET_free (fn);
122 return; 132 return;
123 } 133 }
124 pos = indexed_files; 134 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
125 while (pos != NULL)
126 {
127 if ((GNUNET_OK != 135 if ((GNUNET_OK !=
128 GNUNET_BIO_write (wh, &pos->file_id, sizeof (struct GNUNET_HashCode))) || 136 GNUNET_BIO_write (wh, &pos->file_id, sizeof (struct GNUNET_HashCode))) ||
129 (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename))) 137 (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename)))
130 break; 138 break;
131 pos = pos->next;
132 }
133 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 139 if (GNUNET_OK != GNUNET_BIO_write_close (wh))
134 { 140 {
135 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 141 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -189,15 +195,16 @@ read_index_list ()
189 pos->filename = (const char *) &pos[1]; 195 pos->filename = (const char *) &pos[1];
190 memcpy (&pos[1], fname, slen); 196 memcpy (&pos[1], fname, slen);
191 if (GNUNET_SYSERR == 197 if (GNUNET_SYSERR ==
192 GNUNET_CONTAINER_multihashmap_put (ifm, &hc, (void *) pos->filename, 198 GNUNET_CONTAINER_multihashmap_put (ifm, &pos->file_id, pos,
193 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 199 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
194 { 200 {
195 GNUNET_free (pos); 201 GNUNET_free (pos);
196 } 202 }
197 else 203 else
198 { 204 {
199 pos->next = indexed_files; 205 GNUNET_CONTAINER_DLL_insert (indexed_files_head,
200 indexed_files = pos; 206 indexed_files_tail,
207 pos);
201 } 208 }
202 GNUNET_free (fname); 209 GNUNET_free (fname);
203 } 210 }
@@ -216,25 +223,28 @@ read_index_list ()
216static void 223static void
217signal_index_ok (struct IndexInfo *ii) 224signal_index_ok (struct IndexInfo *ii)
218{ 225{
226 struct IndexInfo *ir;
219 if (GNUNET_SYSERR == 227 if (GNUNET_SYSERR ==
220 GNUNET_CONTAINER_multihashmap_put (ifm, &ii->file_id, 228 GNUNET_CONTAINER_multihashmap_put (ifm, &ii->file_id,
221 (void *) ii->filename, 229 ii,
222 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 230 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
223 { 231 {
232 ir = GNUNET_CONTAINER_multihashmap_get (ifm,
233 &ii->file_id);
224 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 234 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
225 _ 235 _
226 ("Index request received for file `%s' is already indexed as `%s'. Permitting anyway.\n"), 236 ("Index request received for file `%s' is already indexed as `%s'. Permitting anyway.\n"),
227 ii->filename, 237 ii->filename,
228 (const char *) GNUNET_CONTAINER_multihashmap_get (ifm, 238 ir->filename);
229 &ii->file_id));
230 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0, 239 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
231 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK); 240 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK);
232 GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES); 241 GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES);
233 GNUNET_free (ii); 242 GNUNET_free (ii);
234 return; 243 return;
235 } 244 }
236 ii->next = indexed_files; 245 GNUNET_CONTAINER_DLL_insert (indexed_files_head,
237 indexed_files = ii; 246 indexed_files_tail,
247 ii);
238 write_index_list (); 248 write_index_list ();
239 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0, 249 GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0,
240 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK); 250 GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK);
@@ -373,8 +383,7 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client,
373 383
374 tc = GNUNET_SERVER_transmit_context_create (client); 384 tc = GNUNET_SERVER_transmit_context_create (client);
375 iim = (struct IndexInfoMessage *) buf; 385 iim = (struct IndexInfoMessage *) buf;
376 pos = indexed_files; 386 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
377 while (NULL != pos)
378 { 387 {
379 fn = pos->filename; 388 fn = pos->filename;
380 slen = strlen (fn) + 1; 389 slen = strlen (fn) + 1;
@@ -390,7 +399,6 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client,
390 iim->file_id = pos->file_id; 399 iim->file_id = pos->file_id;
391 memcpy (&iim[1], fn, slen); 400 memcpy (&iim[1], fn, slen);
392 GNUNET_SERVER_transmit_context_append_message (tc, &iim->header); 401 GNUNET_SERVER_transmit_context_append_message (tc, &iim->header);
393 pos = pos->next;
394 } 402 }
395 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 403 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
396 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END); 404 GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END);
@@ -411,8 +419,6 @@ GNUNET_FS_handle_unindex (void *cls, struct GNUNET_SERVER_Client *client,
411{ 419{
412 const struct UnindexMessage *um; 420 const struct UnindexMessage *um;
413 struct IndexInfo *pos; 421 struct IndexInfo *pos;
414 struct IndexInfo *prev;
415 struct IndexInfo *next;
416 struct GNUNET_SERVER_TransmitContext *tc; 422 struct GNUNET_SERVER_TransmitContext *tc;
417 int found; 423 int found;
418 424
@@ -424,29 +430,20 @@ GNUNET_FS_handle_unindex (void *cls, struct GNUNET_SERVER_Client *client,
424 return; 430 return;
425 } 431 }
426 found = GNUNET_NO; 432 found = GNUNET_NO;
427 prev = NULL; 433 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
428 pos = indexed_files;
429 while (NULL != pos)
430 { 434 {
431 next = pos->next;
432 if (0 == memcmp (&pos->file_id, &um->file_id, sizeof (struct GNUNET_HashCode))) 435 if (0 == memcmp (&pos->file_id, &um->file_id, sizeof (struct GNUNET_HashCode)))
433 { 436 {
434 if (prev == NULL) 437 GNUNET_CONTAINER_DLL_remove (indexed_files_head,
435 indexed_files = next; 438 indexed_files_tail,
436 else 439 pos);
437 prev->next = next;
438 GNUNET_break (GNUNET_OK == 440 GNUNET_break (GNUNET_OK ==
439 GNUNET_CONTAINER_multihashmap_remove (ifm, &pos->file_id, 441 GNUNET_CONTAINER_multihashmap_remove (ifm, &pos->file_id,
440 (void *) 442 pos));
441 pos->filename));
442 GNUNET_free (pos); 443 GNUNET_free (pos);
443 found = GNUNET_YES; 444 found = GNUNET_YES;
445 break;
444 } 446 }
445 else
446 {
447 prev = pos;
448 }
449 pos = next;
450 } 447 }
451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
452 "Client requested unindexing of file `%s': %s\n", 449 "Client requested unindexing of file `%s': %s\n",
@@ -519,6 +516,7 @@ GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t s
519 const char *fn; 516 const char *fn;
520 struct GNUNET_DISK_FileHandle *fh; 517 struct GNUNET_DISK_FileHandle *fh;
521 uint64_t off; 518 uint64_t off;
519 struct IndexInfo *ii;
522 520
523 if (size != sizeof (struct OnDemandBlock)) 521 if (size != sizeof (struct OnDemandBlock))
524 { 522 {
@@ -529,7 +527,8 @@ GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t s
529 } 527 }
530 odb = (const struct OnDemandBlock *) data; 528 odb = (const struct OnDemandBlock *) data;
531 off = GNUNET_ntohll (odb->offset); 529 off = GNUNET_ntohll (odb->offset);
532 fn = (const char *) GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id); 530 ii = GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id);
531 fn = ii->filename;
533 if ((NULL == fn) || (0 != ACCESS (fn, R_OK))) 532 if ((NULL == fn) || (0 != ACCESS (fn, R_OK)))
534 { 533 {
535 GNUNET_STATISTICS_update (GSF_stats, 534 GNUNET_STATISTICS_update (GSF_stats,
@@ -588,15 +587,20 @@ GNUNET_FS_indexing_done ()
588{ 587{
589 struct IndexInfo *pos; 588 struct IndexInfo *pos;
590 589
591 GNUNET_CONTAINER_multihashmap_destroy (ifm); 590 while (NULL != (pos = indexed_files_head))
592 ifm = NULL;
593 while (NULL != (pos = indexed_files))
594 { 591 {
595 indexed_files = pos->next; 592 GNUNET_CONTAINER_DLL_remove (indexed_files_head,
593 indexed_files_tail,
594 pos);
596 if (pos->fhc != NULL) 595 if (pos->fhc != NULL)
597 GNUNET_CRYPTO_hash_file_cancel (pos->fhc); 596 GNUNET_CRYPTO_hash_file_cancel (pos->fhc);
597 GNUNET_break (GNUNET_OK ==
598 GNUNET_CONTAINER_multihashmap_remove (ifm,
599 &pos->file_id, pos));
598 GNUNET_free (pos); 600 GNUNET_free (pos);
599 } 601 }
602 GNUNET_CONTAINER_multihashmap_destroy (ifm);
603 ifm = NULL;
600 cfg = NULL; 604 cfg = NULL;
601} 605}
602 606
@@ -613,7 +617,7 @@ GNUNET_FS_indexing_init (const struct GNUNET_CONFIGURATION_Handle *c,
613{ 617{
614 cfg = c; 618 cfg = c;
615 dsh = d; 619 dsh = d;
616 ifm = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); 620 ifm = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_YES);
617 read_index_list (); 621 read_index_list ();
618 return GNUNET_OK; 622 return GNUNET_OK;
619} 623}