gnunet-svn
[Top][All Lists]
Advanced

[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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]