[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r7813 - in GNUnet: . src/applications/fs/ecrs src/applicati
From: |
gnunet |
Subject: |
[GNUnet-SVN] r7813 - in GNUnet: . src/applications/fs/ecrs src/applications/fs/fsui src/applications/fs/gap src/include src/util/containers |
Date: |
Thu, 30 Oct 2008 18:25:06 -0600 (MDT) |
Author: grothoff
Date: 2008-10-30 18:25:05 -0600 (Thu, 30 Oct 2008)
New Revision: 7813
Modified:
GNUnet/src/applications/fs/ecrs/uri.c
GNUnet/src/applications/fs/fsui/deserialize.c
GNUnet/src/applications/fs/fsui/fsui.c
GNUnet/src/applications/fs/fsui/fsui.h
GNUnet/src/applications/fs/fsui/search.c
GNUnet/src/applications/fs/fsui/serialize.c
GNUnet/src/applications/fs/fsui/upload.c
GNUnet/src/applications/fs/gap/querymanager.c
GNUnet/src/applications/fs/gap/test_multi_results.c
GNUnet/src/include/gnunet_ecrs_lib.h
GNUnet/src/include/gnunet_util_containers.h
GNUnet/src/util/containers/multihashmap.c
GNUnet/todo
Log:
adding code to improve compleixty, more testing needed
Modified: GNUnet/src/applications/fs/ecrs/uri.c
===================================================================
--- GNUnet/src/applications/fs/ecrs/uri.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/ecrs/uri.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -84,6 +84,36 @@
#include "gnunet_protocols.h"
#include "gnunet_ecrs_lib.h"
+void
+GNUNET_ECRS_uri_to_key(const struct GNUNET_ECRS_URI * uri,
+ GNUNET_HashCode * key)
+{
+ memset(key, 0, sizeof(GNUNET_HashCode));
+ switch (uri->type)
+ {
+ case chk:
+ *key = uri->data.fi.chk.query;
+ return;
+ case sks:
+ GNUNET_hash(uri->data.sks.identifier,
+ strlen(uri->data.sks.identifier),
+ key);
+ break;
+ case ksk:
+ if (uri->data.ksk.keywordCount > 0)
+ GNUNET_hash(uri->data.ksk.keywords[0],
+ strlen(uri->data.ksk.keywords[0]),
+ key);
+ break;
+ case loc:
+ GNUNET_hash(&uri->data.loc.fi,
+ sizeof(GNUNET_EC_FileIdentifier) +
sizeof(GNUNET_RSA_PublicKey),
+ key);
+ break;
+ }
+}
+
+
/**
* In URI-encoding, does the given character
* need to be encoded using %-encoding?
Modified: GNUnet/src/applications/fs/fsui/deserialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/deserialize.c 2008-10-30 12:07:52 UTC
(rev 7812)
+++ GNUnet/src/applications/fs/fsui/deserialize.c 2008-10-31 00:25:05 UTC
(rev 7813)
@@ -492,7 +492,7 @@
* @param search_count length of search_list
* @param search_list list of ECRS search requests
*/
-struct SearchResultList *
+struct GNUNET_MultiHashMap *
read_result_list (struct GNUNET_GE_Context *ectx,
ReadBuffer * rb,
unsigned int search_count,
@@ -502,15 +502,13 @@
unsigned int remaining;
unsigned int probeSucc;
unsigned int probeFail;
+ struct GNUNET_MultiHashMap * map;
struct SearchResultList *ret;
- struct SearchResultList *head;
- struct SearchResultList *tail;
+ GNUNET_HashCode urik;
unsigned int i;
unsigned int idx;
- ret = NULL;
- head = NULL;
- tail = NULL;
+ map = GNUNET_multi_hash_map_create(4);
while (1)
{
if (GNUNET_OK != read_uint (rb, &matching))
@@ -527,6 +525,8 @@
GNUNET_free (ret);
break;
}
+ GNUNET_ECRS_uri_to_key(ret->fi.uri,
+ &urik);
ret->matchingSearchCount = matching;
ret->mandatoryMatchesRemaining = remaining;
ret->probeSuccess = probeSucc;
@@ -541,7 +541,6 @@
ret->probeFailure = 0;
}
ret->test_download = NULL;
- ret->next = NULL;
ret->matchingSearches = NULL;
i = 0;
GNUNET_array_grow (ret->matchingSearches, i, ret->matchingSearchCount);
@@ -553,7 +552,7 @@
GNUNET_array_grow (ret->matchingSearches,
ret->matchingSearchCount, 0);
GNUNET_free (ret);
- return head;
+ return map;
}
if (idx == 0)
{
@@ -566,15 +565,23 @@
ret->matchingSearches[i] = search_list[idx - 1];
}
}
- if (head == NULL)
- head = ret;
- if (tail != NULL)
- tail->next = ret;
- tail = ret;
+ GNUNET_multi_hash_map_put(map,
+ &urik,
+ ret,
+ GNUNET_MultiHashMapOption_MULTIPLE);
}
- return head;
+ return map;
}
+static int
+free_entry(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ GNUNET_free(value);
+ return GNUNET_OK;
+}
+
/**
* Read in all of the FSUI-searches that we are
* performing.
@@ -585,7 +592,6 @@
int big;
GNUNET_FSUI_SearchList *list;
GNUNET_FSUI_SearchList *last;
- struct SearchResultList *srp;
struct SearchRecordList *srl;
struct SearchRecordList **srla;
char *buf;
@@ -673,12 +679,11 @@
} /* end OUTER: 'while(1)' */
ERR:
/* error - deallocate 'list' */
- while (list->resultsReceived != NULL)
- {
- srp = list->resultsReceived;
- list->resultsReceived = srp->next;
- GNUNET_free (srp);
- }
+ GNUNET_multi_hash_map_iterate(list->resultsReceived,
+ &free_entry,
+ NULL);
+ GNUNET_multi_hash_map_destroy(list->resultsReceived);
+
while (list->searches != NULL)
{
srl = list->searches;
Modified: GNUnet/src/applications/fs/fsui/fsui.c
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/fsui/fsui.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -61,7 +61,115 @@
srl->test_download_start_time = 0;
}
+static int
+process_probes(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ struct GNUNET_FSUI_SearchList *sl = cls;
+ struct SearchResultList *srl = value;
+ unsigned long long off;
+ unsigned long long len;
+ GNUNET_CronTime now;
+ GNUNET_FSUI_Event event;
+ now = GNUNET_get_time ();
+ if (srl->test_download != NULL)
+ {
+ if (srl->test_download_start_time == 0)
+ {
+ /* probe was successful, kill */
+ GNUNET_ECRS_file_download_partial_stop (srl->test_download);
+ srl->test_download = NULL;
+ srl->probeSuccess++;
+ event.type = GNUNET_FSUI_search_update;
+ event.data.SearchUpdate.sc.pos = sl;
+ event.data.SearchUpdate.sc.cctx = sl->cctx;
+ event.data.SearchUpdate.fi = srl->fi;
+ event.data.SearchUpdate.searchURI = sl->uri;
+ event.data.SearchUpdate.availability_rank =
+ srl->probeSuccess - srl->probeFailure;
+ event.data.SearchUpdate.availability_certainty =
+ srl->probeSuccess + srl->probeFailure;
+ event.data.SearchUpdate.applicability_rank =
+ srl->matchingSearchCount;
+ sl->ctx->ecb (sl->ctx->ecbClosure, &event);
+ sl->ctx->active_probes--;
+ srl->last_probe_time = now;
+ }
+ else
+ {
+ /* consider stopping */
+ if ((now - srl->test_download_start_time)
+ >
+ SQUARE (srl->probeSuccess + srl->probeFailure +
+ 1) * GNUNET_FSUI_PROBE_TIME_FACTOR)
+ {
+ /* timeout hit! */
+ GNUNET_ECRS_file_download_partial_stop
+ (srl->test_download);
+ srl->test_download = NULL;
+ srl->probeFailure++;
+ event.type = GNUNET_FSUI_search_update;
+ event.data.SearchUpdate.sc.pos = sl;
+ event.data.SearchUpdate.sc.cctx = sl->cctx;
+ event.data.SearchUpdate.fi = srl->fi;
+ event.data.SearchUpdate.searchURI = sl->uri;
+ event.data.SearchUpdate.availability_rank =
+ srl->probeSuccess - srl->probeFailure;
+ event.data.SearchUpdate.availability_certainty =
+ srl->probeSuccess + srl->probeFailure;
+ event.data.SearchUpdate.applicability_rank =
+ srl->matchingSearchCount;
+ sl->ctx->ecb (sl->ctx->ecbClosure, &event);
+ sl->ctx->active_probes--;
+ srl->last_probe_time = now;
+ }
+ }
+ }
+ else
+ {
+ len = GNUNET_ECRS_uri_get_file_size (srl->fi.uri);
+ if (len == 0)
+ srl->probeSuccess = -1; /* MAX */
+ /* consider starting */
+ if (((srl->probeSuccess + srl->probeFailure) <
+ GNUNET_FSUI_MAX_PROBES)
+ &&
+ ((srl->last_probe_time <
+ now +
+ GNUNET_FSUI_PROBE_DELAY * SQUARE (sl->ctx->active_probes) +
+ GNUNET_random_u64 (GNUNET_RANDOM_QUALITY_WEAK,
+ GNUNET_FSUI_PROBE_DELAY)))
+ && (sl->ctx->active_probes < GNUNET_FSUI_HARD_PROBE_LIMIT))
+ {
+ off = len / GNUNET_ECRS_DBLOCK_SIZE;
+ if (off > 0)
+ off = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, off);
+ off *= GNUNET_ECRS_DBLOCK_SIZE;
+ if (len - off < GNUNET_ECRS_DBLOCK_SIZE)
+ len = len - off;
+ else
+ len = GNUNET_ECRS_DBLOCK_SIZE;
+ srl->test_download
+ = GNUNET_ECRS_file_download_partial_start (sl->ctx->ectx,
+ sl->ctx->cfg,
+ sl->probe_context,
+ srl->fi.uri,
+ NULL, off, len,
+ 1, GNUNET_YES,
+ &test_download_progress,
+ srl);
+ if (srl->test_download != NULL)
+ {
+ srl->test_download_start_time = now;
+ sl->ctx->active_probes++;
+ }
+ }
+ }
+ return GNUNET_OK;
+}
+
/**
* Cron job for download load management.
*/
@@ -70,12 +178,7 @@
{
GNUNET_FSUI_Context *ctx = c;
GNUNET_FSUI_DownloadList *dpos;
- struct SearchResultList *srl;
struct GNUNET_FSUI_SearchList *sl;
- unsigned long long off;
- unsigned long long len;
- GNUNET_CronTime now;
- GNUNET_FSUI_Event event;
GNUNET_mutex_lock (ctx->lock);
dpos = ctx->activeDownloads.child;
@@ -92,109 +195,12 @@
dpos = dpos->next;
}
ctx->min_block_resume = ctx->next_min_block_resume;
- now = GNUNET_get_time ();
sl = ctx->activeSearches;
while (sl != NULL)
{
- srl = sl->resultsReceived;
- while (srl != NULL)
- {
- if (srl->test_download != NULL)
- {
- if (srl->test_download_start_time == 0)
- {
- /* probe was successful, kill */
- GNUNET_ECRS_file_download_partial_stop (srl->test_download);
- srl->test_download = NULL;
- srl->probeSuccess++;
- event.type = GNUNET_FSUI_search_update;
- event.data.SearchUpdate.sc.pos = sl;
- event.data.SearchUpdate.sc.cctx = sl->cctx;
- event.data.SearchUpdate.fi = srl->fi;
- event.data.SearchUpdate.searchURI = sl->uri;
- event.data.SearchUpdate.availability_rank =
- srl->probeSuccess - srl->probeFailure;
- event.data.SearchUpdate.availability_certainty =
- srl->probeSuccess + srl->probeFailure;
- event.data.SearchUpdate.applicability_rank =
- srl->matchingSearchCount;
- ctx->ecb (ctx->ecbClosure, &event);
- ctx->active_probes--;
- srl->last_probe_time = now;
- }
- else
- {
- /* consider stopping */
- if ((now - srl->test_download_start_time)
- >
- SQUARE (srl->probeSuccess + srl->probeFailure +
- 1) * GNUNET_FSUI_PROBE_TIME_FACTOR)
- {
- /* timeout hit! */
- GNUNET_ECRS_file_download_partial_stop
- (srl->test_download);
- srl->test_download = NULL;
- srl->probeFailure++;
- event.type = GNUNET_FSUI_search_update;
- event.data.SearchUpdate.sc.pos = sl;
- event.data.SearchUpdate.sc.cctx = sl->cctx;
- event.data.SearchUpdate.fi = srl->fi;
- event.data.SearchUpdate.searchURI = sl->uri;
- event.data.SearchUpdate.availability_rank =
- srl->probeSuccess - srl->probeFailure;
- event.data.SearchUpdate.availability_certainty =
- srl->probeSuccess + srl->probeFailure;
- event.data.SearchUpdate.applicability_rank =
- srl->matchingSearchCount;
- ctx->ecb (ctx->ecbClosure, &event);
- ctx->active_probes--;
- srl->last_probe_time = now;
- }
- }
- }
- else
- {
- len = GNUNET_ECRS_uri_get_file_size (srl->fi.uri);
- if (len == 0)
- srl->probeSuccess = -1; /* MAX */
- /* consider starting */
- if (((srl->probeSuccess + srl->probeFailure) <
- GNUNET_FSUI_MAX_PROBES)
- &&
- ((srl->last_probe_time <
- now +
- GNUNET_FSUI_PROBE_DELAY * SQUARE (ctx->active_probes) +
- GNUNET_random_u64 (GNUNET_RANDOM_QUALITY_WEAK,
- GNUNET_FSUI_PROBE_DELAY)))
- && (ctx->active_probes < GNUNET_FSUI_HARD_PROBE_LIMIT))
- {
- off = len / GNUNET_ECRS_DBLOCK_SIZE;
- if (off > 0)
- off = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, off);
- off *= GNUNET_ECRS_DBLOCK_SIZE;
- if (len - off < GNUNET_ECRS_DBLOCK_SIZE)
- len = len - off;
- else
- len = GNUNET_ECRS_DBLOCK_SIZE;
- srl->test_download
- = GNUNET_ECRS_file_download_partial_start (ctx->ectx,
- ctx->cfg,
-
sl->probe_context,
- srl->fi.uri,
- NULL, off, len,
- 1, GNUNET_YES,
-
&test_download_progress,
- srl);
- if (srl->test_download != NULL)
- {
- srl->test_download_start_time = now;
- ctx->active_probes++;
- }
- }
- }
-
- srl = srl->next;
- }
+ GNUNET_multi_hash_map_iterate(sl->resultsReceived,
+ &process_probes,
+ sl);
sl = sl->next;
}
GNUNET_mutex_unlock (ctx->lock);
@@ -317,6 +323,43 @@
}
}
+static int
+count_mandatory_zero(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ unsigned int * count = cls;
+ struct SearchResultList *pos = value;
+
+ if (pos->mandatoryMatchesRemaining == 0)
+ (*count)++;
+ return GNUNET_OK;
+}
+
+static int
+process_mandatory_zero(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ GNUNET_FSUI_Event * event = cls;
+ struct SearchResultList *pos = value;
+
+ if (pos->mandatoryMatchesRemaining == 0)
+ {
+
((GNUNET_ECRS_FileInfo*)event->data.SearchResumed.fis)[event->data.SearchResumed.fisSize]
+ = pos->fi;
+
event->data.SearchResumed.availability_rank[event->data.SearchResumed.fisSize]
+ = pos->probeSuccess - pos->probeFailure;
+
event->data.SearchResumed.availability_certainty[event->data.SearchResumed.fisSize]
+ = pos->probeSuccess + pos->probeFailure;
+ event->data.SearchResumed.applicability_rank
[event->data.SearchResumed.fisSize]
+ = pos->matchingSearchCount;
+ event->data.SearchResumed.fisSize++;
+ }
+ return GNUNET_OK;
+}
+
+
/**
* Start FSUI manager. Use the given progress callback to notify the
* UI about events. Start processing pending activities that were
@@ -336,14 +379,8 @@
GNUNET_FSUI_Context *ret;
GNUNET_FSUI_SearchList *list;
GNUNET_FSUI_UnindexList *xlist;
- struct SearchResultList *pos;
struct SearchRecordList *rec;
unsigned int valid;
- unsigned int i;
- GNUNET_ECRS_FileInfo *fis;
- int *av_ranks;
- unsigned int *av_certs;
- unsigned int *ap_ranks;
char *fn;
unsigned long long size;
@@ -394,54 +431,36 @@
while (list != NULL)
{
valid = 0;
- pos = list->resultsReceived;
- while (pos != NULL)
- {
- if (pos->mandatoryMatchesRemaining == 0)
- valid++;
- pos = pos->next;
- }
- fis = NULL;
- av_ranks = NULL;
- av_certs = NULL;
- ap_ranks = NULL;
+ GNUNET_multi_hash_map_iterate(list->resultsReceived,
+ &count_mandatory_zero,
+ &valid);
+ memset(&event, 0, sizeof(GNUNET_FSUI_Event));
if (valid > 0)
{
- fis = GNUNET_malloc (sizeof (GNUNET_ECRS_FileInfo) * valid);
- av_ranks = GNUNET_malloc (sizeof (int) * valid);
- av_certs = GNUNET_malloc (sizeof (unsigned int) * valid);
- ap_ranks = GNUNET_malloc (sizeof (unsigned int) * valid);
- pos = list->resultsReceived;
- i = 0;
- while (pos != NULL)
- {
- if (pos->mandatoryMatchesRemaining == 0)
- {
- fis[i] = pos->fi;
- av_ranks[i] = pos->probeSuccess - pos->probeFailure;
- av_certs[i] = pos->probeSuccess + pos->probeFailure;
- ap_ranks[i] = pos->matchingSearchCount;
- i++;
- }
- pos = pos->next;
- }
- }
+ event.data.SearchResumed.fis
+ = GNUNET_malloc (sizeof (GNUNET_ECRS_FileInfo) * valid);
+ event.data.SearchResumed.availability_rank
+ = GNUNET_malloc (sizeof (int) * valid);
+ event.data.SearchResumed.availability_certainty
+ = GNUNET_malloc (sizeof (unsigned int) * valid);
+ event.data.SearchResumed.applicability_rank
+ = GNUNET_malloc (sizeof (unsigned int) * valid);
+ GNUNET_multi_hash_map_iterate(list->resultsReceived,
+ &process_mandatory_zero,
+ &event);
+ }
event.type = GNUNET_FSUI_search_resumed;
event.data.SearchResumed.sc.pos = list;
event.data.SearchResumed.sc.cctx = NULL;
- event.data.SearchResumed.fis = fis;
- event.data.SearchResumed.fisSize = valid;
+ GNUNET_GE_ASSERT(NULL, event.data.SearchResumed.fisSize == valid);
event.data.SearchResumed.anonymityLevel = list->anonymityLevel;
event.data.SearchResumed.searchURI = list->uri;
event.data.SearchResumed.state = list->state;
- event.data.SearchResumed.availability_rank = av_ranks;
- event.data.SearchResumed.availability_certainty = av_certs;
- event.data.SearchResumed.applicability_rank = ap_ranks;
list->cctx = cb (closure, &event);
- GNUNET_free_non_null (fis);
- GNUNET_free_non_null (av_ranks);
- GNUNET_free_non_null (av_certs);
- GNUNET_free_non_null (ap_ranks);
+ GNUNET_free_non_null ((void*)event.data.SearchResumed.fis);
+ GNUNET_free_non_null (event.data.SearchResumed.availability_rank);
+ GNUNET_free_non_null (event.data.SearchResumed.availability_certainty);
+ GNUNET_free_non_null (event.data.SearchResumed.applicability_rank);
list = list->next;
}
/* 2b) signal download restarts */
@@ -665,6 +684,37 @@
}
}
+static int
+stop_download_probe(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ struct SearchResultList *res = value;
+ struct GNUNET_FSUI_Context * ctx = cls;
+
+ if (res->test_download != NULL)
+ {
+ GNUNET_ECRS_file_download_partial_stop (res->test_download);
+ res->test_download = NULL;
+ ctx->active_probes--;
+ }
+ return GNUNET_OK;
+}
+
+static int
+free_result_data(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ struct SearchResultList *res = value;
+
+ GNUNET_meta_data_destroy (res->fi.meta);
+ GNUNET_ECRS_uri_destroy (res->fi.uri);
+ GNUNET_free (res->matchingSearches);
+ GNUNET_free (res);
+ return GNUNET_OK;
+}
+
/**
* Stop all processes under FSUI control (serialize state, continue
* later if possible).
@@ -678,7 +728,6 @@
GNUNET_FSUI_UnindexList *xpos;
GNUNET_FSUI_UploadList *upos;
struct SearchRecordList *rec;
- struct SearchResultList *res;
GNUNET_FSUI_Event event;
void *unused;
@@ -720,17 +769,10 @@
rec->search = NULL;
rec = rec->next;
}
- res = spos->resultsReceived;
- while (res != NULL)
- {
- if (res->test_download != NULL)
- {
- GNUNET_ECRS_file_download_partial_stop (res->test_download);
- res->test_download = NULL;
- ctx->active_probes--;
- }
- res = res->next;
- }
+ GNUNET_multi_hash_map_iterate(spos->resultsReceived,
+ &stop_download_probe,
+ ctx);
+
if (spos->state != GNUNET_FSUI_PENDING)
spos->state++; /* _JOINED */
}
@@ -823,15 +865,10 @@
GNUNET_ECRS_uri_destroy (rec->uri);
GNUNET_free (rec);
}
- while (spos->resultsReceived != NULL)
- {
- res = spos->resultsReceived;
- spos->resultsReceived = res->next;
- GNUNET_meta_data_destroy (res->fi.meta);
- GNUNET_ECRS_uri_destroy (res->fi.uri);
- GNUNET_free (res->matchingSearches);
- GNUNET_free (res);
- }
+ GNUNET_multi_hash_map_iterate(spos->resultsReceived,
+ &free_result_data,
+ NULL);
+ GNUNET_multi_hash_map_destroy(spos->resultsReceived);
GNUNET_free (spos);
}
/* 4b) free unindex memory */
Modified: GNUnet/src/applications/fs/fsui/fsui.h
===================================================================
--- GNUnet/src/applications/fs/fsui/fsui.h 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/fsui/fsui.h 2008-10-31 00:25:05 UTC (rev
7813)
@@ -75,8 +75,6 @@
struct SearchResultList
{
- struct SearchResultList *next;
-
/**
* Test download (if any).
*/
@@ -140,7 +138,7 @@
struct SearchRecordList *next;
/**
- * Handles to the ECRS SearchContexts.
+ * Handle to the ECRS SearchContext.
*/
struct GNUNET_ECRS_SearchContext *search;
@@ -179,7 +177,7 @@
/**
* Searches are kept in a simple linked list.
*/
- struct GNUNET_FSUI_SearchList *next;
+ struct GNUNET_FSUI_SearchList * next;
/**
* Context for this search
@@ -188,12 +186,12 @@
/**
* Context used for availability probes and the
- * ECRS searches
+ * ECRS searches.
*/
struct GNUNET_FS_SearchContext *probe_context;
/**
- * Handles to the ECRS SearchContexts.
+ * Handles to the Search records (one for each keyword).
*/
struct SearchRecordList *searches;
@@ -208,9 +206,9 @@
struct GNUNET_FSUI_DownloadList **my_downloads;
/**
- * List of all results found so far.
+ * HashMap (using query of URI as key) of all results found so far.
*/
- struct SearchResultList *resultsReceived;
+ struct GNUNET_MultiHashMap *resultsReceived;
/**
* Client context for the search.
Modified: GNUnet/src/applications/fs/fsui/search.c
===================================================================
--- GNUnet/src/applications/fs/fsui/search.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/fsui/search.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -78,6 +78,86 @@
}
}
+struct ProcessClosure {
+ const GNUNET_HashCode * key;
+ GNUNET_FSUI_SearchList * pos;
+ const GNUNET_ECRS_FileInfo * fi;
+};
+
+static int
+process_existing(const GNUNET_HashCode * key,
+ void * value,
+ void * arg)
+{
+ struct SearchResultList *srl = value;
+ struct ProcessClosure * pc = arg;
+ struct SearchRecordList *rec;
+ int update;
+ unsigned int i;
+
+ if (! GNUNET_ECRS_uri_test_equal (pc->fi->uri, srl->fi.uri))
+ return GNUNET_OK;
+
+ for (i = 0; i < srl->matchingSearchCount; i++)
+ {
+ /* why do we have this first uri_test_sks here?
+ what case does it address? should it be moved
+ outside of the iterator??? */
+ if ((GNUNET_ECRS_uri_test_sks (pc->pos->uri)) ||
+ (0 == memcmp (pc->key,
+ &srl->matchingSearches[i]->key,
+ sizeof (GNUNET_HashCode))))
+ {
+#if DEBUG_SEARCH
+ fprintf (stderr,
+ "Received search result that I have seen before.\n");
+#endif
+ return GNUNET_SYSERR; /* seen before */
+ }
+ }
+
+
+ /* not seen before, find corresponding keyword! */
+ rec = pc->pos->searches;
+ while ((rec != NULL) &&
+ (0 != memcmp (pc->key, &rec->key, sizeof (GNUNET_HashCode))))
+ rec = rec->next;
+ if (rec == NULL)
+ {
+ GNUNET_GE_BREAK (NULL, 0);
+ return GNUNET_SYSERR; /* should have matching search */
+ }
+ GNUNET_array_append (srl->matchingSearches,
+ srl->matchingSearchCount, rec);
+ if (rec->is_required)
+ {
+ if (srl->mandatoryMatchesRemaining > 0)
+ srl->mandatoryMatchesRemaining--;
+ else
+ GNUNET_GE_BREAK (NULL, 0);
+ update = 0;
+#if DEBUG_SEARCH
+ fprintf (stderr, "Received mandatory search result\n");
+#endif
+ }
+ else
+ {
+ update = 1;
+#if DEBUG_SEARCH
+ fprintf (stderr, "Received optional search result\n");
+#endif
+ }
+ if (srl->mandatoryMatchesRemaining == 0)
+ {
+#if DEBUG_SEARCH
+ fprintf (stderr, "Passing result to client\n");
+#endif
+ processResult (pc->pos, srl, update);
+ }
+ return GNUNET_SYSERR;
+}
+
+
/**
* Process results found by ECRS.
*/
@@ -87,100 +167,75 @@
int isRoot, void *cls)
{
GNUNET_FSUI_SearchList *pos = cls;
- unsigned int i;
struct GNUNET_GE_Context *ectx;
struct SearchResultList *srl;
struct SearchRecordList *rec;
- int update;
GNUNET_HashCode nsid;
+ GNUNET_HashCode urik;
+ int ret;
+ struct ProcessClosure pc;
+ char * root;
+ pc.key = key;
+ pc.fi = fi;
+ pc.pos = pos;
ectx = pos->ctx->ectx;
GNUNET_URITRACK_track (ectx, pos->ctx->cfg, fi);
+
+ GNUNET_ECRS_uri_to_key(fi->uri,
+ &urik);
+ ret = GNUNET_multi_hash_map_get_multiple(pos->resultsReceived,
+ &urik,
+ &process_existing,
+ &pc);
+ if (ret < 0)
+ return GNUNET_OK; /* done! */
+
if (isRoot)
{
- GNUNET_NS_namespace_set_root (ectx, pos->ctx->cfg, fi->uri);
GNUNET_ECRS_uri_get_namespace_from_sks (fi->uri, &nsid);
- GNUNET_pseudonym_add (ectx, pos->ctx->cfg, &nsid, fi->meta);
- return GNUNET_OK;
+ root = GNUNET_NS_namespace_get_root(ectx, pos->ctx->cfg, &nsid);
+ if (root == NULL)
+ {
+ GNUNET_NS_namespace_set_root (ectx, pos->ctx->cfg, fi->uri);
+ GNUNET_pseudonym_add (ectx, pos->ctx->cfg, &nsid, fi->meta);
+ /* if we do not return here, we essentially are telling
+ the client about the NS ad; we should probably do this
+ after hacking the clients to support it! */
+ return GNUNET_OK;
+ }
+ else
+ {
+ /* not new */
+ GNUNET_free(root);
+ return GNUNET_OK;
+ }
}
- srl = pos->resultsReceived;
- while (srl != NULL)
- {
- if (GNUNET_ECRS_uri_test_equal (fi->uri, srl->fi.uri))
- {
- for (i = 0; i < srl->matchingSearchCount; i++)
- {
- if ((GNUNET_ECRS_uri_test_sks (pos->uri)) ||
- (0 == memcmp (key,
- &srl->matchingSearches[i]->key,
- sizeof (GNUNET_HashCode))))
- {
-#if DEBUG_SEARCH
- fprintf (stderr,
- "Received search result that I have seen
before.\n");
-#endif
- return GNUNET_OK; /* seen before */
- }
- }
- /* not seen before, find corresponding search! */
- rec = pos->searches;
- while ((rec != NULL) &&
- (0 != memcmp (key, &rec->key, sizeof (GNUNET_HashCode))))
- rec = rec->next;
- if (rec == NULL)
- {
- GNUNET_GE_BREAK (NULL, 0);
- return GNUNET_OK; /* should have matching search */
- }
- GNUNET_array_append (srl->matchingSearches,
- srl->matchingSearchCount, rec);
- if (rec->is_required)
- {
- if (srl->mandatoryMatchesRemaining > 0)
- srl->mandatoryMatchesRemaining--;
- else
- GNUNET_GE_BREAK (NULL, 0);
- update = 0;
-#if DEBUG_SEARCH
- fprintf (stderr, "Received mandatory search result\n");
-#endif
- }
- else
- {
- update = 1;
-#if DEBUG_SEARCH
- fprintf (stderr, "Received optional search result\n");
-#endif
- }
- if (srl->mandatoryMatchesRemaining == 0)
- {
-#if DEBUG_SEARCH
- fprintf (stderr, "Passing result to client\n");
-#endif
- processResult (pos, srl, update);
- }
- return GNUNET_OK;
- }
- srl = srl->next;
- }
+
/* new result */
rec = pos->searches;
while ((rec != NULL) &&
+ (!isRoot) &&
(!GNUNET_ECRS_uri_test_sks (pos->uri)) &&
(0 != memcmp (key, &rec->key, sizeof (GNUNET_HashCode))))
rec = rec->next;
- if (rec == NULL)
+ if ( (rec == NULL) && (! isRoot) )
{
GNUNET_GE_BREAK (NULL, 0);
return GNUNET_OK; /* should have matching search */
}
srl = GNUNET_malloc (sizeof (struct SearchResultList));
memset (srl, 0, sizeof (struct SearchResultList));
- GNUNET_array_append (srl->matchingSearches, srl->matchingSearchCount, rec);
+ if ( (!GNUNET_ECRS_uri_test_sks (pos->uri)) &&
+ (!isRoot))
+ GNUNET_array_append (srl->matchingSearches, srl->matchingSearchCount, rec);
+ else
+ rec = NULL;
srl->fi.meta = GNUNET_meta_data_duplicate (fi->meta);
srl->fi.uri = GNUNET_ECRS_uri_duplicate (fi->uri);
- srl->mandatoryMatchesRemaining = pos->mandatory_keyword_count;
- if (rec->is_required)
+ srl->mandatoryMatchesRemaining = (isRoot)? 0: pos->mandatory_keyword_count;
+ if ( (rec != NULL) &&
+ (rec->is_required) )
{
if (srl->mandatoryMatchesRemaining > 0)
srl->mandatoryMatchesRemaining--;
@@ -196,8 +251,10 @@
fprintf (stderr, "Received new optional result\n");
#endif
}
- srl->next = pos->resultsReceived;
- pos->resultsReceived = srl;
+ GNUNET_multi_hash_map_put(pos->resultsReceived,
+ &urik,
+ srl,
+ GNUNET_MultiHashMapOption_MULTIPLE);
if (srl->mandatoryMatchesRemaining == 0)
{
#if DEBUG_SEARCH
@@ -291,6 +348,7 @@
pos->ctx = ctx;
pos->start_time = GNUNET_get_time ();
pos->uri = GNUNET_ECRS_uri_duplicate (uri);
+ pos->resultsReceived = GNUNET_multi_hash_map_create(4);
event.type = GNUNET_FSUI_search_started;
event.data.SearchStarted.sc.pos = pos;
event.data.SearchStarted.sc.cctx = NULL;
@@ -347,6 +405,7 @@
event.data.SearchStopped.sc.cctx = NULL;
pos->cctx = pos->ctx->ecb (pos->ctx->ecbClosure, &event);
GNUNET_ECRS_uri_destroy (pos->uri);
+ GNUNET_multi_hash_map_destroy(pos->resultsReceived);
GNUNET_free (pos);
return NULL;
}
@@ -358,6 +417,43 @@
return pos;
}
+static int
+stop_result_probe(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ struct SearchResultList *srl = value;
+ struct GNUNET_FSUI_Context * ctx = cls;
+
+ if (srl->test_download != NULL)
+ {
+ GNUNET_ECRS_file_download_partial_stop (srl->test_download);
+ srl->test_download = NULL;
+ ctx->active_probes--;
+ }
+ return GNUNET_OK;
+}
+
+static int
+free_result_data(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ struct SearchResultList *srl = value;
+ struct GNUNET_FSUI_Context * ctx = cls;
+
+ if (srl->test_download != NULL)
+ {
+ GNUNET_ECRS_file_download_partial_stop (srl->test_download);
+ ctx->active_probes--;
+ }
+ GNUNET_meta_data_destroy (srl->fi.meta);
+ GNUNET_ECRS_uri_destroy (srl->fi.uri);
+ GNUNET_free_non_null (srl->matchingSearches);
+ GNUNET_free (srl);
+ return GNUNET_OK;
+}
+
/**
* Abort a search.
*/
@@ -366,7 +462,6 @@
{
GNUNET_FSUI_Event event;
struct SearchRecordList *rec;
- struct SearchResultList *srl;
struct GNUNET_FSUI_Context *ctx;
ctx = sl->ctx;
@@ -396,18 +491,9 @@
/* clean up a bit more: we don't need matchingSearches
anymore, and the pointers are now invalid! */
GNUNET_mutex_lock (ctx->lock);
- srl = sl->resultsReceived;
- while (srl != NULL)
- {
- GNUNET_array_grow (srl->matchingSearches, srl->matchingSearchCount, 0);
- if (srl->test_download != NULL)
- {
- GNUNET_ECRS_file_download_partial_stop (srl->test_download);
- srl->test_download = NULL;
- ctx->active_probes--;
- }
- srl = srl->next;
- }
+ GNUNET_multi_hash_map_iterate(sl->resultsReceived,
+ &stop_result_probe,
+ ctx);
event.type = GNUNET_FSUI_search_aborted;
event.data.SearchAborted.sc.pos = sl;
event.data.SearchAborted.sc.cctx = sl->cctx;
@@ -424,7 +510,6 @@
{
GNUNET_FSUI_Event event;
struct SearchRecordList *rec;
- struct SearchResultList *srl;
struct GNUNET_FSUI_Context *ctx;
ctx = sl->ctx;
@@ -446,17 +531,9 @@
rec = rec->next;
}
GNUNET_mutex_lock (ctx->lock);
- srl = sl->resultsReceived;
- while (srl != NULL)
- {
- if (srl->test_download != NULL)
- {
- GNUNET_ECRS_file_download_partial_stop (srl->test_download);
- srl->test_download = NULL;
- ctx->active_probes--;
- }
- srl = srl->next;
- }
+ GNUNET_multi_hash_map_iterate(sl->resultsReceived,
+ &stop_result_probe,
+ ctx);
event.type = GNUNET_FSUI_search_paused;
event.data.SearchPaused.sc.pos = sl;
event.data.SearchPaused.sc.cctx = sl->cctx;
@@ -518,7 +595,6 @@
GNUNET_FSUI_SearchList *prev;
int i;
struct SearchRecordList *rec;
- struct SearchResultList *srl;
struct GNUNET_FSUI_Context *ctx;
ctx = sl->ctx;
@@ -564,23 +640,14 @@
event.data.SearchStopped.sc.cctx = pos->cctx;
pos->ctx->ecb (pos->ctx->ecbClosure, &event);
GNUNET_ECRS_uri_destroy (pos->uri);
- while (sl->resultsReceived != NULL)
- {
- srl = sl->resultsReceived;
- sl->resultsReceived = srl->next;
- GNUNET_array_grow (srl->matchingSearches, srl->matchingSearchCount, 0);
- GNUNET_ECRS_uri_destroy (srl->fi.uri);
- GNUNET_meta_data_destroy (srl->fi.meta);
- if (srl->test_download != NULL)
- {
- GNUNET_ECRS_file_download_partial_stop (srl->test_download);
- ctx->active_probes--;
- }
- GNUNET_free (srl);
- }
+ GNUNET_multi_hash_map_iterate(sl->resultsReceived,
+ &free_result_data,
+ ctx);
+ GNUNET_multi_hash_map_destroy(sl->resultsReceived);
+ sl->resultsReceived = NULL;
if (pos->probe_context != NULL)
GNUNET_FS_destroy_search_context (pos->probe_context);
- GNUNET_free (pos);
+ GNUNET_free (pos); /* same as sl! */
return GNUNET_OK;
}
Modified: GNUnet/src/applications/fs/fsui/serialize.c
===================================================================
--- GNUnet/src/applications/fs/fsui/serialize.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/fsui/serialize.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -244,55 +244,50 @@
WRITEINT (wb, -1);
}
-/**
- * Write all of the results received so far
- * for this search.
- *
- * @param search_count length of search_list
- * @param search_list list of ECRS search requests
- * @param pos results to write
- */
-void
-write_result_list (struct GNUNET_GE_Context *ectx,
- WriteBuffer * wb,
- struct SearchRecordList *search_list,
- struct SearchResultList *pos)
+struct WriteResultContext {
+ struct GNUNET_GE_Context * ectx;
+ WriteBuffer * wb;
+ struct SearchRecordList * search_list;
+};
+
+static int
+write_result_entry (const GNUNET_HashCode * key,
+ void * value,
+ void * ctx)
{
+ struct WriteResultContext * wrc = ctx;
+ struct SearchResultList *pos = value;
unsigned int i;
unsigned int idx;
struct SearchRecordList *spos;
- while (pos != NULL)
+ WRITEINT (wrc->wb, pos->matchingSearchCount);
+ WRITEINT (wrc->wb, pos->mandatoryMatchesRemaining);
+ WRITEINT (wrc->wb, pos->probeSuccess);
+ WRITEINT (wrc->wb, pos->probeFailure);
+ writeFileInfo (wrc->ectx, wrc->wb, &pos->fi);
+ i = pos->matchingSearchCount;
+ while (i-- > 0)
{
- WRITEINT (wb, pos->matchingSearchCount);
- WRITEINT (wb, pos->mandatoryMatchesRemaining);
- WRITEINT (wb, pos->probeSuccess);
- WRITEINT (wb, pos->probeFailure);
- writeFileInfo (ectx, wb, &pos->fi);
- i = pos->matchingSearchCount;
- while (i-- > 0)
- {
- idx = 1;
- spos = search_list;
- while ((spos != NULL) && (spos != pos->matchingSearches[i]))
- {
- idx++;
- spos = spos->next;
- }
- if (spos == NULL)
- idx = 0;
- WRITEINT (wb, idx);
- }
- pos = pos->next;
+ idx = 1;
+ spos = wrc->search_list;
+ while ((spos != NULL) && (spos != pos->matchingSearches[i]))
+ {
+ idx++;
+ spos = spos->next;
+ }
+ if (spos == NULL)
+ idx = 0;
+ WRITEINT (wrc->wb, idx);
}
- WRITEINT (wb, -1);
+ return GNUNET_OK;
}
-
static void
writeSearches (WriteBuffer * wb, struct GNUNET_FSUI_Context *ctx)
{
GNUNET_FSUI_SearchList *spos;
+ struct WriteResultContext wrc;
spos = ctx->activeSearches;
while (spos != NULL)
@@ -308,8 +303,13 @@
WRITEINT (wb, spos->mandatory_keyword_count);
writeURI (wb, spos->uri);
write_search_record_list (ctx->ectx, wb, spos->searches);
- write_result_list (ctx->ectx,
- wb, spos->searches, spos->resultsReceived);
+ wrc.ectx = ctx->ectx;
+ wrc.wb = wb;
+ wrc.search_list = spos->searches;
+ GNUNET_multi_hash_map_iterate(spos->resultsReceived,
+ &write_result_entry,
+ &wrc);
+ WRITEINT (wb, -1); /* result list terminator */
spos = spos->next;
}
WRITEINT (wb, 0);
Modified: GNUnet/src/applications/fs/fsui/upload.c
===================================================================
--- GNUnet/src/applications/fs/fsui/upload.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/applications/fs/fsui/upload.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -487,6 +487,7 @@
(copied here to allow free later) */
loc = GNUNET_ECRS_uri_duplicate (utc->uri);
}
+ uri = NULL;
if (utc->shared->individualKeywords == GNUNET_YES)
{
/* need to convert to URI *before*
Modified: GNUnet/src/applications/fs/gap/querymanager.c
===================================================================
--- GNUnet/src/applications/fs/gap/querymanager.c 2008-10-30 12:07:52 UTC
(rev 7812)
+++ GNUnet/src/applications/fs/gap/querymanager.c 2008-10-31 00:25:05 UTC
(rev 7813)
@@ -124,6 +124,16 @@
return size;
}
+static int
+mark_response_seen(const GNUNET_HashCode * key,
+ void * value,
+ void * cls)
+{
+ GNUNET_FS_SHARED_mark_response_seen(key,
+ cls);
+ return GNUNET_OK;
+}
+
/**
* 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
@@ -178,7 +188,7 @@
stats->change (stat_gap_client_bf_updates, 1);
GNUNET_multi_hash_map_iterate(seen,
- (GNUNET_HashCodeIterator)
&GNUNET_FS_SHARED_mark_response_seen,
+ &mark_response_seen,
request);
}
GNUNET_mutex_lock (GNUNET_FS_lock);
@@ -297,12 +307,14 @@
* GNUNET_NO if this is the last entry
*/
static int
-response_bf_iterator (GNUNET_HashCode * next, void *arg)
+response_bf_iterator (const GNUNET_HashCode * key,
+ void * value,
+ void *arg)
{
struct IteratorClosure *cls = arg;
GNUNET_HashCode n;
- GNUNET_FS_HELPER_mingle_hash (next, cls->mingle_number, &n);
+ GNUNET_FS_HELPER_mingle_hash (key, cls->mingle_number, &n);
GNUNET_bloomfilter_add(cls->filter,
&n);
return GNUNET_YES;
@@ -396,9 +408,10 @@
GNUNET_GAP_BLOOMFILTER_K);
ic.filter = rl->bloomfilter;
ic.mingle_number = rl->bloomfilter_mutator;
- GNUNET_multi_hash_map_iterate(rl->responses,
- &response_bf_iterator,
- &ic);
+ if (rl->responses != NULL)
+ GNUNET_multi_hash_map_iterate(rl->responses,
+ &response_bf_iterator,
+ &ic);
if (stats != NULL)
stats->change (stat_gap_client_bf_updates, 1);
}
Modified: GNUnet/src/applications/fs/gap/test_multi_results.c
===================================================================
--- GNUnet/src/applications/fs/gap/test_multi_results.c 2008-10-30 12:07:52 UTC
(rev 7812)
+++ GNUnet/src/applications/fs/gap/test_multi_results.c 2008-10-31 00:25:05 UTC
(rev 7813)
@@ -150,7 +150,9 @@
int
main (int argc, char **argv)
{
+#if START_PEERS
struct GNUNET_TESTING_DaemonContext *peers;
+#endif
int ret;
int i;
char buf[128];
@@ -179,7 +181,9 @@
if (GNUNET_OK != GNUNET_TESTING_connect_daemons (2077 + (10 * i),
2087 + (10 * i)))
{
+#if START_PEERS
GNUNET_TESTING_stop_daemons (peers);
+#endif
fprintf (stderr, "Failed to connect the peers!\n");
GNUNET_GC_free (cfg);
return -1;
Modified: GNUnet/src/include/gnunet_ecrs_lib.h
===================================================================
--- GNUnet/src/include/gnunet_ecrs_lib.h 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/include/gnunet_ecrs_lib.h 2008-10-31 00:25:05 UTC (rev
7813)
@@ -105,6 +105,13 @@
struct GNUNET_ECRS_URI;
/**
+ * Get a unique key from a URI. This is for putting URIs
+ * into HashMaps. The key may change between ECRS implementations.
+ */
+void GNUNET_ECRS_uri_to_key(const struct GNUNET_ECRS_URI * uri,
+ GNUNET_HashCode * key);
+
+/**
* Convert a URI to a UTF-8 String.
*/
char *GNUNET_ECRS_uri_to_string (const struct GNUNET_ECRS_URI *uri);
Modified: GNUnet/src/include/gnunet_util_containers.h
===================================================================
--- GNUnet/src/include/gnunet_util_containers.h 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/include/gnunet_util_containers.h 2008-10-31 00:25:05 UTC (rev
7813)
@@ -343,6 +343,18 @@
GNUNET_MultiHashMapOption_UNIQUE_FAST
};
+/**
+ * Iterator over HashCodes.
+ *
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+typedef int (*GNUNET_HashMapIterator) (const GNUNET_HashCode * key,
+ void * value,
+ void * cls);
+
+
struct GNUNET_MultiHashMap *
GNUNET_multi_hash_map_create(unsigned int len);
@@ -369,10 +381,15 @@
unsigned int GNUNET_multi_hash_map_size(const struct GNUNET_MultiHashMap* map);
int GNUNET_multi_hash_map_iterate(const struct GNUNET_MultiHashMap* map,
- GNUNET_HashCodeIterator iterator,
+ GNUNET_HashMapIterator iterator,
void * cls);
+int GNUNET_multi_hash_map_get_multiple(const struct GNUNET_MultiHashMap* map,
+ const GNUNET_HashCode * key,
+ GNUNET_HashMapIterator iterator,
+ void * cls);
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
Modified: GNUnet/src/util/containers/multihashmap.c
===================================================================
--- GNUnet/src/util/containers/multihashmap.c 2008-10-30 12:07:52 UTC (rev
7812)
+++ GNUnet/src/util/containers/multihashmap.c 2008-10-31 00:25:05 UTC (rev
7813)
@@ -103,7 +103,7 @@
int
GNUNET_multi_hash_map_iterate(const struct GNUNET_MultiHashMap* map,
- GNUNET_HashCodeIterator it,
+ GNUNET_HashMapIterator it,
void * cls)
{
int count;
@@ -118,6 +118,7 @@
{
if (GNUNET_OK !=
it(&e->key,
+ e->value,
cls))
return GNUNET_SYSERR;
count++;
@@ -273,4 +274,29 @@
return GNUNET_OK;
}
+int
+GNUNET_multi_hash_map_get_multiple(const struct GNUNET_MultiHashMap* map,
+ const GNUNET_HashCode * key,
+ GNUNET_HashMapIterator it,
+ void * cls)
+{
+ int count;
+ struct MapEntry* e;
+
+ count = 0;
+ e = map->map[idx_of(map, key)];
+ while (e != NULL)
+ {
+ if (GNUNET_OK !=
+ it(&e->key,
+ e->value,
+ cls))
+ return GNUNET_SYSERR;
+ count++;
+ e = e->next;
+ }
+ return count;
+}
+
+
/* end of multihashmap.c */
Modified: GNUnet/todo
===================================================================
--- GNUnet/todo 2008-10-30 12:07:52 UTC (rev 7812)
+++ GNUnet/todo 2008-10-31 00:25:05 UTC (rev 7813)
@@ -1,6 +1,14 @@
This is just the current plan, plans change.
0.8.1 [8'08] (aka "growth"):
+- test & document multihashmap
+- finish & document new ECRS URI hash function
+ => test complexity of #search results in new FSUI/gap code!
+- make GUIs handle namespace advertisement events
+ => enable publishing of namespace ads in FSUI
+ => test
+
+
- Publishing:
* clean up indexing with gnunet-insert (#1107)
* power insert (#854)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r7813 - in GNUnet: . src/applications/fs/ecrs src/applications/fs/fsui src/applications/fs/gap src/include src/util/containers,
gnunet <=