From e59aabf0eb8ce56d3414254ab9c7b6cc90dd05c3 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 18 Jul 2012 12:26:34 +0000 Subject: [PATCH] -trying to fix high CPU load caused by DHT --- src/dht/gnunet-service-dht_routing.c | 58 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index c1dca4e21..796991b5b 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c @@ -322,6 +322,48 @@ expire_oldest_entry () } +/** + * Try to combine multiple recent requests for the same value + * (if they come from the same peer). + * + * @param cls the new 'struct RecentRequest' (to discard upon successful combination) + * @param key the query + * @param value the existing 'struct RecentRequest' (to update upon successful combination) + * @return GNUNET_OK (continue to iterate), + * GNUNET_SYSERR if the request was successfully combined + */ +static int +try_combine_recent (void *cls, const struct GNUNET_HashCode * key, void *value) +{ + struct RecentRequest *in = cls; + struct RecentRequest *rr = value; + + if ( (0 != memcmp (&in->peer, + &rr->peer, + sizeof (struct GNUNET_PeerIdentity))) || + (in->type != rr->type) || + (in->xquery_size != rr->xquery_size) || + (0 != memcmp (in->xquery, + rr->xquery, + in->xquery_size)) ) + return GNUNET_OK; + if (in->reply_bf_mutator != rr->reply_bf_mutator) + { + rr->reply_bf_mutator = in->reply_bf_mutator; + GNUNET_CONTAINER_bloomfilter_free (rr->reply_bf); + rr->reply_bf = in->reply_bf; + } + else + { + GNUNET_CONTAINER_bloomfilter_or2 (rr->reply_bf, + in->reply_bf, + GNUNET_CONTAINER_bloomfilter_get_size (in->reply_bf)); + GNUNET_CONTAINER_bloomfilter_free (in->reply_bf); + } + GNUNET_free (in); + return GNUNET_SYSERR; +} + /** * Add a new entry to our routing table. @@ -354,15 +396,25 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size); recent_req->peer = *sender; recent_req->key = *key; - recent_req->heap_node = - GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, - GNUNET_TIME_absolute_get ().abs_value); recent_req->reply_bf = GNUNET_CONTAINER_bloomfilter_copy (reply_bf); recent_req->type = type; recent_req->options = options; recent_req->xquery = &recent_req[1]; recent_req->xquery_size = xquery_size; recent_req->reply_bf_mutator = reply_bf_mutator; + if (GNUNET_SYSERR == + GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, key, + &try_combine_recent, recent_req)) + { + GNUNET_STATISTICS_update (GDS_stats, + gettext_noop + ("# DHT requests combined"), + 1, GNUNET_NO); + return; + } + recent_req->heap_node = + GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, + GNUNET_TIME_absolute_get ().abs_value); GNUNET_CONTAINER_multihashmap_put (recent_map, key, recent_req, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); -- 2.25.1