Author: grothoff Date: 2008-02-17 20:47:19 -0700 (Sun, 17 Feb 2008) New Revision: 6359
Modified: GNUnet/src/applications/fs/gap/fs.c GNUnet/src/applications/fs/gap/plan.c GNUnet/src/applications/fs/gap/plan.h GNUnet/src/applications/fs/gap/querymanager.c GNUnet/src/applications/fs/gap/querymanager.h GNUnet/src/applications/fs/gap/shared.c GNUnet/src/applications/fs/gap/shared.h Log: better stats and bloomfilter local data immediately Modified: GNUnet/src/applications/fs/gap/fs.c =================================================================== --- GNUnet/src/applications/fs/gap/fs.c 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/fs.c 2008-02-18 03:47:19 UTC (rev 6359) @@ -388,6 +388,11 @@ return coreAPI->sendValueToClient (sock, ret); } +struct FPPClosure { + struct GNUNET_ClientHandle *sock; + struct ResponseList * seen; +}; + /** * Any response that we get should be passed * back to the client. If the response is unique, @@ -398,7 +403,9 @@ const GNUNET_DatastoreValue * value, void *closure, unsigned long long uid) { - struct GNUNET_ClientHandle *sock = closure; + struct FPPClosure * cls = closure; + struct GNUNET_ClientHandle *sock = cls->sock; + struct ResponseList * rl; const DBlock *dblock; CS_fs_reply_content_MESSAGE *msg; unsigned int size; @@ -431,6 +438,12 @@ GNUNET_free (msg); if (type == GNUNET_ECRS_BLOCKTYPE_DATA) return GNUNET_SYSERR; /* unique response */ + rl = GNUNET_malloc(sizeof(struct ResponseList)); + GNUNET_hash(dblock, + size, + &rl->hash); + rl->next = cls->seen; + cls->seen = rl; return GNUNET_OK; } @@ -443,8 +456,10 @@ static int handle_cs_query_start_request (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * req) -{ +{ static GNUNET_PeerIdentity all_zeros; + struct FPPClosure fpp; + struct ResponseList * pos; const CS_fs_request_search_MESSAGE *rs; unsigned int keyCount; unsigned int type; @@ -468,17 +483,19 @@ GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER, "FS received QUERY (query: `%s', type: %u)\n", &enc, type); #endif + fpp.sock = sock; + fpp.seen = NULL; if (type == GNUNET_ECRS_BLOCKTYPE_DATA) { if ((1 == datastore->get (&rs->query[0], - type, &fast_path_processor, sock)) || + type, &fast_path_processor, &fpp)) || (1 == datastore->get (&rs->query[0], GNUNET_ECRS_BLOCKTYPE_ONDEMAND, - &fast_path_processor, sock))) - return GNUNET_OK; + &fast_path_processor, &fpp))) + goto CLEANUP; } else - datastore->get (&rs->query[0], type, &fast_path_processor, sock); + datastore->get (&rs->query[0], type, &fast_path_processor, &fpp); anonymityLevel = ntohl (rs->anonymityLevel); keyCount = 1 + (ntohs (req->size) - @@ -487,7 +504,15 @@ memcmp (&all_zeros, &rs->target, sizeof (GNUNET_PeerIdentity)) != 0; GNUNET_FS_QUERYMANAGER_start_query (&rs->query[0], keyCount, anonymityLevel, type, sock, - have_target ? &rs->target : NULL); + have_target ? &rs->target : NULL, + fpp.seen); + CLEANUP: + while (fpp.seen != NULL) + { + pos = fpp.seen; + fpp.seen = pos->next; + GNUNET_free(pos); + } return GNUNET_OK; } Modified: GNUnet/src/applications/fs/gap/plan.c =================================================================== --- GNUnet/src/applications/fs/gap/plan.c 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/plan.c 2008-02-18 03:47:19 UTC (rev 6359) @@ -519,8 +519,10 @@ * @param client maybe NULL, in which case peer is significant * @param peer sender of the request (if not a local client) * @param request to plan + * @return GNUNET_YES if the request is being planned, GNUNET_NO if not, + * GNUNET_SYSERR on error */ -void +int GNUNET_FS_PLAN_request (struct GNUNET_ClientHandle *client, PID_INDEX peer, struct RequestList *request) { @@ -563,7 +565,7 @@ if (total_score == 0) { GNUNET_mutex_unlock (GNUNET_FS_lock); - return; /* no peers available */ + return GNUNET_NO; /* no peers available */ } entropy = 0; @@ -632,6 +634,7 @@ GNUNET_free (rank); } GNUNET_mutex_unlock (GNUNET_FS_lock); + return target_count > 0 ? GNUNET_YES : GNUNET_NO; } /** Modified: GNUnet/src/applications/fs/gap/plan.h =================================================================== --- GNUnet/src/applications/fs/gap/plan.h 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/plan.h 2008-02-18 03:47:19 UTC (rev 6359) @@ -35,8 +35,9 @@ * Plan the transmission of the given request. * Use the history of the request and the client * to schedule the request for transmission. + * @return GNUNET_YES if planning succeeded */ -void +int GNUNET_FS_PLAN_request (struct GNUNET_ClientHandle *client, PID_INDEX peer, struct RequestList *request); Modified: GNUnet/src/applications/fs/gap/querymanager.c =================================================================== --- GNUnet/src/applications/fs/gap/querymanager.c 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/querymanager.c 2008-02-18 03:47:19 UTC (rev 6359) @@ -87,6 +87,37 @@ /** + * How many bytes should a bloomfilter be if + * we have already seen entry_count responses? + * Note that GAP_BLOOMFILTER_K gives us the + * number of bits set per entry. Furthermore, + * we should not re-size the filter too often + * (to keep it cheap). + * + * Since other peers will also add entries but + * not resize the filter, we should generally + * pick a slightly larger size than what the + * strict math would suggest. + * + * @return must be a power of two and smaller + * or equal to 2^15. + */ +static unsigned int +compute_bloomfilter_size (unsigned int entry_count) +{ + unsigned short size; + unsigned short max = 1 << 15; + unsigned int ideal = (entry_count * GAP_BLOOMFILTER_K) / 4; + + if (entry_count > max) + return max; + size = 8; + while ((size < max) && (size < ideal)) + size *= 2; + return size; +} + +/** * A client is asking us to run a query. The query should be issued * until either a unique response has been obtained or until the * client disconnects. @@ -97,19 +128,20 @@ GNUNET_FS_QUERYMANAGER_start_query (const GNUNET_HashCode * query, unsigned int key_count, unsigned int anonymityLevel, - unsigned int type, + unsigned int type, struct GNUNET_ClientHandle *client, - const GNUNET_PeerIdentity * target) + const GNUNET_PeerIdentity * target, + const struct ResponseList * seen) { struct ClientDataList *cl; struct RequestList *request; + const struct ResponseList * pos; GNUNET_GE_ASSERT (NULL, key_count > 0); if (stats != NULL) { stats->change (stat_gap_client_query_tracked, 1); stats->change (stat_gap_client_query_received, 1); - stats->change (stat_gap_client_query_injected, 1); } request = GNUNET_malloc (sizeof (struct RequestList) + @@ -121,7 +153,31 @@ request->primary_target = GNUNET_FS_PT_intern (target); request->response_client = client; request->policy = GNUNET_FS_RoutingPolicy_ALL; - memcpy (&request->queries[0], query, sizeof (GNUNET_HashCode) * key_count); + memcpy (&request->queries[0], query, sizeof (GNUNET_HashCode) * key_count); + if (seen != NULL) + { + pos = seen; + while (pos != NULL) + { + request->bloomfilter_entry_count++; + pos = pos->next; + } + request->bloomfilter_size = compute_bloomfilter_size (request->bloomfilter_entry_count); + request->bloomfilter_mutator = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, -1); + request->bloomfilter = GNUNET_bloomfilter_init (NULL, + NULL, + request->bloomfilter_size, + GAP_BLOOMFILTER_K); + if (stats != NULL) + stats->change(stat_gap_client_bf_updates, 1); + pos = seen; + while (pos != NULL) + { + GNUNET_FS_SHARED_mark_response_seen(request, + &pos->hash); + pos = pos->next; + } + } GNUNET_mutex_lock (GNUNET_FS_lock); cl = clients; while ((cl != NULL) && (cl->client != client)) @@ -136,7 +192,9 @@ } request->next = cl->requests; cl->requests = request; - GNUNET_FS_PLAN_request (client, 0, request); + if ( (GNUNET_YES == GNUNET_FS_PLAN_request (client, 0, request)) && + (stats != NULL) ) + stats->change (stat_gap_client_query_injected, 1); if (request->anonymityLevel == 0) { request->last_dht_get = GNUNET_get_time (); @@ -146,37 +204,6 @@ GNUNET_mutex_unlock (GNUNET_FS_lock); } -/** - * How many bytes should a bloomfilter be if - * we have already seen entry_count responses? - * Note that GAP_BLOOMFILTER_K gives us the - * number of bits set per entry. Furthermore, - * we should not re-size the filter too often - * (to keep it cheap). - * - * Since other peers will also add entries but - * not resize the filter, we should generally - * pick a slightly larger size than what the - * strict math would suggest. - * - * @return must be a power of two and smaller - * or equal to 2^15. - */ -static unsigned int -compute_bloomfilter_size (unsigned int entry_count) -{ - unsigned short size; - unsigned short max = 1 << 15; - unsigned int ideal = (entry_count * GAP_BLOOMFILTER_K) / 4; - - if (entry_count > max) - return max; - size = 8; - while ((size < max) && (size < ideal)) - size *= 2; - return size; -} - struct IteratorClosure { struct ResponseList *pos; @@ -429,8 +456,8 @@ (request->last_ttl_used * GNUNET_CRON_SECONDS + request->last_request_time < now)) { - GNUNET_FS_PLAN_request (client->client, 0, request); - if (stats != NULL) + if ( (GNUNET_OK == GNUNET_FS_PLAN_request (client->client, 0, request)) && + (stats != NULL) ) stats->change (stat_gap_client_query_injected, 1); } Modified: GNUnet/src/applications/fs/gap/querymanager.h =================================================================== --- GNUnet/src/applications/fs/gap/querymanager.h 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/querymanager.h 2008-02-18 03:47:19 UTC (rev 6359) @@ -29,6 +29,7 @@ #include "gnunet_util.h" #include "gnunet_core.h" #include "ecrs_core.h" +#include "shared.h" int GNUNET_FS_QUERYMANAGER_init (GNUNET_CoreAPIForPlugins * capi); @@ -48,7 +49,8 @@ unsigned int anonymityLevel, unsigned int type, struct GNUNET_ClientHandle *client, - const GNUNET_PeerIdentity * target); + const GNUNET_PeerIdentity * target, + const struct ResponseList * seen); /** * Handle the given response (by forwarding it to Modified: GNUnet/src/applications/fs/gap/shared.c =================================================================== --- GNUnet/src/applications/fs/gap/shared.c 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/shared.c 2008-02-18 03:47:19 UTC (rev 6359) @@ -130,13 +130,16 @@ */ void GNUNET_FS_SHARED_mark_response_seen (struct RequestList *rl, - GNUNET_HashCode * hc) + const GNUNET_HashCode * hc) { struct ResponseList *seen; GNUNET_HashCode m; - GNUNET_FS_HELPER_mingle_hash (hc, rl->bloomfilter_mutator, &m); - GNUNET_bloomfilter_add (rl->bloomfilter, &m); + if (rl->bloomfilter != NULL) + { + GNUNET_FS_HELPER_mingle_hash (hc, rl->bloomfilter_mutator, &m); + GNUNET_bloomfilter_add (rl->bloomfilter, &m); + } /* update seen list */ seen = GNUNET_malloc (sizeof (struct ResponseList)); seen->hash = *hc; Modified: GNUnet/src/applications/fs/gap/shared.h =================================================================== --- GNUnet/src/applications/fs/gap/shared.h 2008-02-18 03:12:48 UTC (rev 6358) +++ GNUnet/src/applications/fs/gap/shared.h 2008-02-18 03:47:19 UTC (rev 6359) @@ -305,7 +305,7 @@ */ void GNUNET_FS_SHARED_mark_response_seen (struct RequestList *rl, - GNUNET_HashCode * hc); + const GNUNET_HashCode * hc); /** * If the data portion and type of the value match our value in the _______________________________________________ GNUnet-SVN mailing list GNUnet-SVN@gnu.org http://lists.gnu.org/mailman/listinfo/gnunet-svn