aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-10-25 23:47:39 +0000
committerChristian Grothoff <christian@grothoff.org>2015-10-25 23:47:39 +0000
commit7c55f94e78c72d3b78a5c6007e3658ae30e1f64b (patch)
tree77cb53d80cbb79053a68c71a270586e6e0dcb1ef
parent124f3e77a5e022f5f7ab49df49023d0080bcbbb4 (diff)
downloadgnunet-7c55f94e78c72d3b78a5c6007e3658ae30e1f64b.tar.gz
gnunet-7c55f94e78c72d3b78a5c6007e3658ae30e1f64b.zip
-use hash in prd query to reduce memory consumption of CP request_map
-rw-r--r--src/fs/gnunet-service-fs_cp.c27
-rw-r--r--src/fs/gnunet-service-fs_pe.c69
-rw-r--r--src/fs/gnunet-service-fs_pr.c11
-rw-r--r--src/fs/gnunet-service-fs_pr.h27
4 files changed, 83 insertions, 51 deletions
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c
index 7066b0698..1d52f28f9 100644
--- a/src/fs/gnunet-service-fs_cp.c
+++ b/src/fs/gnunet-service-fs_cp.c
@@ -250,7 +250,7 @@ struct GSF_ConnectedPeer
250 struct GNUNET_SCHEDULER_Task *rc_delay_task; 250 struct GNUNET_SCHEDULER_Task *rc_delay_task;
251 251
252 /** 252 /**
253 * Active requests from this neighbour, map of query to 'struct PeerRequest'. 253 * Active requests from this neighbour, map of query to `struct PeerRequest`.
254 */ 254 */
255 struct GNUNET_CONTAINER_MultiHashMap *request_map; 255 struct GNUNET_CONTAINER_MultiHashMap *request_map;
256 256
@@ -646,7 +646,8 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer,
646 cp->rc = 646 cp->rc =
647 GNUNET_ATS_reserve_bandwidth (GSF_ats, peer, DBLOCK_SIZE, 647 GNUNET_ATS_reserve_bandwidth (GSF_ats, peer, DBLOCK_SIZE,
648 &ats_reserve_callback, cp); 648 &ats_reserve_callback, cp);
649 cp->request_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); 649 cp->request_map = GNUNET_CONTAINER_multihashmap_create (128,
650 GNUNET_YES);
650 GNUNET_break (GNUNET_OK == 651 GNUNET_break (GNUNET_OK ==
651 GNUNET_CONTAINER_multipeermap_put (cp_map, 652 GNUNET_CONTAINER_multipeermap_put (cp_map,
652 GSF_connected_peer_get_identity2_ (cp), 653 GSF_connected_peer_get_identity2_ (cp),
@@ -811,8 +812,10 @@ free_pending_request (struct PeerRequest *peerreq,
811 GNUNET_SCHEDULER_cancel (peerreq->kill_task); 812 GNUNET_SCHEDULER_cancel (peerreq->kill_task);
812 peerreq->kill_task = NULL; 813 peerreq->kill_task = NULL;
813 } 814 }
814 GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"), 815 GNUNET_STATISTICS_update (GSF_stats,
815 -1, GNUNET_NO); 816 gettext_noop ("# P2P searches active"),
817 -1,
818 GNUNET_NO);
816 GNUNET_break (GNUNET_YES == 819 GNUNET_break (GNUNET_YES ==
817 GNUNET_CONTAINER_multihashmap_remove (cp->request_map, 820 GNUNET_CONTAINER_multihashmap_remove (cp->request_map,
818 query, 821 query,
@@ -1288,6 +1291,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
1288 uint32_t ttl_decrement; 1291 uint32_t ttl_decrement;
1289 struct TestExistClosure tec; 1292 struct TestExistClosure tec;
1290 GNUNET_PEER_Id spid; 1293 GNUNET_PEER_Id spid;
1294 const struct GSF_PendingRequestData *prd;
1291 1295
1292 msize = ntohs (message->size); 1296 msize = ntohs (message->size);
1293 if (msize < sizeof (struct GetMessage)) 1297 if (msize < sizeof (struct GetMessage))
@@ -1452,20 +1456,25 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other,
1452 spid, 1456 spid,
1453 GNUNET_PEER_intern (other), 1457 GNUNET_PEER_intern (other),
1454 NULL, 0, /* replies_seen */ 1458 NULL, 0, /* replies_seen */
1455 &handle_p2p_reply, peerreq); 1459 &handle_p2p_reply,
1460 peerreq);
1456 GNUNET_assert (NULL != pr); 1461 GNUNET_assert (NULL != pr);
1462 prd = GSF_pending_request_get_data_ (pr);
1457 peerreq->pr = pr; 1463 peerreq->pr = pr;
1458 GNUNET_break (GNUNET_OK == 1464 GNUNET_break (GNUNET_OK ==
1459 GNUNET_CONTAINER_multihashmap_put (cp->request_map, 1465 GNUNET_CONTAINER_multihashmap_put (cp->request_map,
1460 &gm->query, 1466 &prd->query,
1461 peerreq, 1467 peerreq,
1462 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 1468 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
1463 GNUNET_STATISTICS_update (GSF_stats, 1469 GNUNET_STATISTICS_update (GSF_stats,
1464 gettext_noop 1470 gettext_noop
1465 ("# P2P query messages received and processed"), 1, 1471 ("# P2P query messages received and processed"),
1472 1,
1473 GNUNET_NO);
1474 GNUNET_STATISTICS_update (GSF_stats,
1475 gettext_noop ("# P2P searches active"),
1476 1,
1466 GNUNET_NO); 1477 GNUNET_NO);
1467 GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"),
1468 1, GNUNET_NO);
1469 return pr; 1478 return pr;
1470} 1479}
1471 1480
diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c
index ede109c2d..9743d1cb2 100644
--- a/src/fs/gnunet-service-fs_pe.c
+++ b/src/fs/gnunet-service-fs_pe.c
@@ -59,7 +59,7 @@ struct PeerPlan;
59 * to a given plan entry.) 59 * to a given plan entry.)
60 * 60 *
61 * Similarly head and tail of the "PR" MDLL are stored 61 * Similarly head and tail of the "PR" MDLL are stored
62 * with the 'struct GSF_PendingRequest'. (We need 62 * with the `struct GSF_PendingRequest`. (We need
63 * to be able to lookup all plan entries corresponding 63 * to be able to lookup all plan entries corresponding
64 * to a given pending request.) 64 * to a given pending request.)
65 */ 65 */
@@ -87,12 +87,14 @@ struct GSF_PendingRequestPlanBijection
87 struct GSF_PendingRequestPlanBijection *prev_PE; 87 struct GSF_PendingRequestPlanBijection *prev_PE;
88 88
89 /** 89 /**
90 * Associated request plan. 90 * Associated request plan (tells us one of the peers that
91 * we plan to forward the request to).
91 */ 92 */
92 struct GSF_RequestPlan *rp; 93 struct GSF_RequestPlan *rp;
93 94
94 /** 95 /**
95 * Associated pending request. 96 * Associated pending request (identifies request details
97 * and one of the origins of the request).
96 */ 98 */
97 struct GSF_PendingRequest *pr; 99 struct GSF_PendingRequest *pr;
98 100
@@ -101,8 +103,8 @@ struct GSF_PendingRequestPlanBijection
101 103
102/** 104/**
103 * Information we keep per request per peer. This is a doubly-linked 105 * Information we keep per request per peer. This is a doubly-linked
104 * list (with head and tail in the 'struct GSF_PendingRequestData') 106 * list (with head and tail in the `struct GSF_PendingRequestData`)
105 * with one entry in each heap of each 'struct PeerPlan'. Each 107 * with one entry in each heap of each `struct PeerPlan`. Each
106 * entry tracks information relevant for this request and this peer. 108 * entry tracks information relevant for this request and this peer.
107 */ 109 */
108struct GSF_RequestPlan 110struct GSF_RequestPlan
@@ -129,7 +131,9 @@ struct GSF_RequestPlan
129 struct PeerPlan *pp; 131 struct PeerPlan *pp;
130 132
131 /** 133 /**
132 * Head of list of associated pending requests. 134 * Head of list of associated pending requests. This tells us
135 * which incoming requests from other peers this plan entry
136 * corresponds to.
133 */ 137 */
134 struct GSF_PendingRequestPlanBijection *pe_head; 138 struct GSF_PendingRequestPlanBijection *pe_head;
135 139
@@ -167,19 +171,20 @@ struct GSF_RequestPlan
167struct PeerPlan 171struct PeerPlan
168{ 172{
169 /** 173 /**
170 * Heap with pending queries (struct GSF_RequestPlan), higher weights mean higher priority. 174 * Heap with pending queries (`struct GSF_RequestPlan`), higher weights mean higher priority.
171 */ 175 */
172 struct GNUNET_CONTAINER_Heap *priority_heap; 176 struct GNUNET_CONTAINER_Heap *priority_heap;
173 177
174 /** 178 /**
175 * Heap with pending queries (struct GSF_RequestPlan), by transmission time, lowest first. 179 * Heap with pending queries (`struct GSF_RequestPlan`), by transmission time, lowest first.
176 */ 180 */
177 struct GNUNET_CONTAINER_Heap *delay_heap; 181 struct GNUNET_CONTAINER_Heap *delay_heap;
178 182
179 /** 183 /**
180 * Map of queries to plan entries. All entries in the priority_heap or delay_heap 184 * Map of queries to plan entries. All entries in the @e priority_heap
181 * should be in the plan map. Note that it IS possible for the plan map to have 185 * or @e delay_heap should be in the @e plan_map. Note that it is
182 * multiple entries for the same query. 186 * possible for the @e plan_map to have multiple entries for the same
187 * query.
183 */ 188 */
184 struct GNUNET_CONTAINER_MultiHashMap *plan_map; 189 struct GNUNET_CONTAINER_MultiHashMap *plan_map;
185 190
@@ -196,7 +201,7 @@ struct PeerPlan
196 /** 201 /**
197 * Current task for executing the plan. 202 * Current task for executing the plan.
198 */ 203 */
199 struct GNUNET_SCHEDULER_Task * task; 204 struct GNUNET_SCHEDULER_Task *task;
200}; 205};
201 206
202 207
@@ -222,7 +227,7 @@ static unsigned long long plan_count;
222 * requests for the same key and we just return _one_ of them; this 227 * requests for the same key and we just return _one_ of them; this
223 * particular one might complete while another one might still be 228 * particular one might complete while another one might still be
224 * active, hence the lifetime of the returned hash code is NOT 229 * active, hence the lifetime of the returned hash code is NOT
225 * necessarily identical to that of the 'struct GSF_RequestPlan' 230 * necessarily identical to that of the `struct GSF_RequestPlan`
226 * given. 231 * given.
227 * 232 *
228 * @param rp a request plan 233 * @param rp a request plan
@@ -253,7 +258,8 @@ schedule_peer_transmission (void *cls,
253 * @param rp request to plan 258 * @param rp request to plan
254 */ 259 */
255static void 260static void
256plan (struct PeerPlan *pp, struct GSF_RequestPlan *rp) 261plan (struct PeerPlan *pp,
262 struct GSF_RequestPlan *rp)
257{ 263{
258#define N ((double)128.0) 264#define N ((double)128.0)
259 /** 265 /**
@@ -366,8 +372,7 @@ get_latest (const struct GSF_RequestPlan *rp)
366 for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE) 372 for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE)
367 { 373 {
368 prd = GSF_pending_request_get_data_ (bi->pr); 374 prd = GSF_pending_request_get_data_ (bi->pr);
369 if (prd->ttl.abs_value_us > 375 if (prd->ttl.abs_value_us > rprd->ttl.abs_value_us)
370 rprd->ttl.abs_value_us)
371 { 376 {
372 ret = bi->pr; 377 ret = bi->pr;
373 rprd = prd; 378 rprd = prd;
@@ -383,10 +388,12 @@ get_latest (const struct GSF_RequestPlan *rp)
383 * @param cls closure 388 * @param cls closure
384 * @param buf_size number of bytes available in @a buf 389 * @param buf_size number of bytes available in @a buf
385 * @param buf where to copy the message, NULL on error (peer disconnect) 390 * @param buf where to copy the message, NULL on error (peer disconnect)
386 * @return number of bytes copied to 'buf', can be 0 (without indicating an error) 391 * @return number of bytes copied to @a buf, can be 0 (without indicating an error)
387 */ 392 */
388static size_t 393static size_t
389transmit_message_callback (void *cls, size_t buf_size, void *buf) 394transmit_message_callback (void *cls,
395 size_t buf_size,
396 void *buf)
390{ 397{
391 struct PeerPlan *pp = cls; 398 struct PeerPlan *pp = cls;
392 struct GSF_RequestPlan *rp; 399 struct GSF_RequestPlan *rp;
@@ -414,7 +421,9 @@ transmit_message_callback (void *cls, size_t buf_size, void *buf)
414 pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); 421 pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp);
415 return 0; 422 return 0;
416 } 423 }
417 msize = GSF_pending_request_get_message_ (get_latest (rp), buf_size, buf); 424 msize = GSF_pending_request_get_message_ (get_latest (rp),
425 buf_size,
426 buf);
418 if (msize > buf_size) 427 if (msize > buf_size)
419 { 428 {
420 if (NULL != pp->task) 429 if (NULL != pp->task)
@@ -476,7 +485,8 @@ schedule_peer_transmission (void *cls,
476 rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap); 485 rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap);
477 if (NULL == rp) 486 if (NULL == rp)
478 { 487 {
479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No active requests for plan %p.\n", 488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489 "No active requests for plan %p.\n",
480 pp); 490 pp);
481 return; /* both queues empty */ 491 return; /* both queues empty */
482 } 492 }
@@ -486,11 +496,14 @@ schedule_peer_transmission (void *cls,
486 GNUNET_STRINGS_relative_time_to_string (delay, 496 GNUNET_STRINGS_relative_time_to_string (delay,
487 GNUNET_YES), 497 GNUNET_YES),
488 pp); 498 pp);
489 GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# delay heap timeout (ms)"), 499 GNUNET_STATISTICS_set (GSF_stats,
500 gettext_noop ("# delay heap timeout (ms)"),
490 delay.rel_value_us / 1000LL, GNUNET_NO); 501 delay.rel_value_us / 1000LL, GNUNET_NO);
491 502
492 pp->task = 503 pp->task =
493 GNUNET_SCHEDULER_add_delayed (delay, &schedule_peer_transmission, pp); 504 GNUNET_SCHEDULER_add_delayed (delay,
505 &schedule_peer_transmission,
506 pp);
494 return; 507 return;
495 } 508 }
496#if INSANE_STATISTICS 509#if INSANE_STATISTICS
@@ -503,8 +516,10 @@ schedule_peer_transmission (void *cls,
503 GNUNET_assert (NULL != rp); 516 GNUNET_assert (NULL != rp);
504 msize = GSF_pending_request_get_message_ (get_latest (rp), 0, NULL); 517 msize = GSF_pending_request_get_message_ (get_latest (rp), 0, NULL);
505 pp->pth = 518 pp->pth =
506 GSF_peer_transmit_ (pp->cp, GNUNET_YES, rp->priority, 519 GSF_peer_transmit_ (pp->cp, GNUNET_YES,
507 GNUNET_TIME_UNIT_FOREVER_REL, msize, 520 rp->priority,
521 GNUNET_TIME_UNIT_FOREVER_REL,
522 msize,
508 &transmit_message_callback, pp); 523 &transmit_message_callback, pp);
509 GNUNET_assert (NULL != pp->pth); 524 GNUNET_assert (NULL != pp->pth);
510} 525}
@@ -516,8 +531,14 @@ schedule_peer_transmission (void *cls,
516struct MergeContext 531struct MergeContext
517{ 532{
518 533
534 /**
535 * Request we are trying to merge.
536 */
519 struct GSF_PendingRequest *pr; 537 struct GSF_PendingRequest *pr;
520 538
539 /**
540 * Set to #GNUNET_YES if we succeeded to merge.
541 */
521 int merged; 542 int merged;
522 543
523}; 544};
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index b507992b4..21b00e80e 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -289,7 +289,8 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
289 enum GNUNET_BLOCK_Type type, 289 enum GNUNET_BLOCK_Type type,
290 const struct GNUNET_HashCode *query, 290 const struct GNUNET_HashCode *query,
291 const struct GNUNET_PeerIdentity *target, 291 const struct GNUNET_PeerIdentity *target,
292 const char *bf_data, size_t bf_size, 292 const char *bf_data,
293 size_t bf_size,
293 uint32_t mingle, 294 uint32_t mingle,
294 uint32_t anonymity_level, 295 uint32_t anonymity_level,
295 uint32_t priority, 296 uint32_t priority,
@@ -325,7 +326,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
325 if (NULL != target) 326 if (NULL != target)
326 { 327 {
327 pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr; 328 pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr;
328 memcpy (eptr, target, sizeof (struct GNUNET_PeerIdentity)); 329 memcpy (eptr,
330 target,
331 sizeof (struct GNUNET_PeerIdentity));
329 } 332 }
330 pr->public_data.anonymity_level = anonymity_level; 333 pr->public_data.anonymity_level = anonymity_level;
331 pr->public_data.priority = priority; 334 pr->public_data.priority = priority;
@@ -397,7 +400,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options,
397 UINT32_MAX, 400 UINT32_MAX,
398 GNUNET_TIME_UNIT_FOREVER_ABS, 401 GNUNET_TIME_UNIT_FOREVER_ABS,
399 GNUNET_TIME_UNIT_FOREVER_ABS, 402 GNUNET_TIME_UNIT_FOREVER_ABS,
400 GNUNET_BLOCK_TYPE_ANY, NULL, 0); 403 GNUNET_BLOCK_TYPE_ANY,
404 NULL,
405 0);
401 GSF_pending_request_cancel_ (dpr, 406 GSF_pending_request_cancel_ (dpr,
402 GNUNET_YES); 407 GNUNET_YES);
403 } 408 }
diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h
index d022d8640..547595b67 100644
--- a/src/fs/gnunet-service-fs_pr.h
+++ b/src/fs/gnunet-service-fs_pr.h
@@ -179,25 +179,22 @@ struct GSF_PendingRequestData
179 * @param eval evaluation of the result 179 * @param eval evaluation of the result
180 * @param pr handle to the original pending request 180 * @param pr handle to the original pending request
181 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" 181 * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
182 * @param expiration when does 'data' expire? 182 * @param expiration when does @a data expire?
183 * @param last_transmission the last time we've tried to get this block (FOREVER if unknown) 183 * @param last_transmission the last time we've tried to get this block (FOREVER if unknown)
184 * @param type type of the block 184 * @param type type of the block
185 * @param data response data, NULL on request expiration 185 * @param data response data, NULL on request expiration
186 * @param data_len number of bytes in data 186 * @param data_len number of bytes in @a data
187 */ 187 */
188typedef void (*GSF_PendingRequestReplyHandler) (void *cls, 188typedef void
189 enum 189(*GSF_PendingRequestReplyHandler) (void *cls,
190 GNUNET_BLOCK_EvaluationResult 190 enum GNUNET_BLOCK_EvaluationResult eval,
191 eval, 191 struct GSF_PendingRequest *pr,
192 struct GSF_PendingRequest * pr, 192 uint32_t reply_anonymity_level,
193 uint32_t reply_anonymity_level, 193 struct GNUNET_TIME_Absolute expiration,
194 struct GNUNET_TIME_Absolute 194 struct GNUNET_TIME_Absolute last_transmission,
195 expiration, 195 enum GNUNET_BLOCK_Type type,
196 struct GNUNET_TIME_Absolute 196 const void *data,
197 last_transmission, 197 size_t data_len);
198 enum GNUNET_BLOCK_Type type,
199 const void *data,
200 size_t data_len);
201 198
202 199
203/** 200/**