stuff
authorChristian Grothoff <christian@grothoff.org>
Wed, 16 Sep 2009 15:44:32 +0000 (15:44 +0000)
committerChristian Grothoff <christian@grothoff.org>
Wed, 16 Sep 2009 15:44:32 +0000 (15:44 +0000)
src/fs/gnunet-service-fs.c
src/util/Makefile.am
src/util/container_heap.c

index 5237cee042d38fd239e2445b50351f4e34e1b5b0..0a9fbcefe789d72c3bdcbc346554c0b10ebad6bb 100644 (file)
@@ -24,7 +24,7 @@
  * @author Christian Grothoff
  *
  * TODO:
- * - tracking of PendingRequests (and defining that struct...)
+ * - tracking of PendingRequests
  * - setup P2P search on CS request
  * - setup P2P search on P2P GET
  * - forward replies based on tracked requests
@@ -341,6 +341,13 @@ struct ProcessGetContext
 };
 
 
+/**
+ * All requests from a client are 
+ * kept in a doubly-linked list.
+ */
+struct ClientRequestList;
+
+
 /**
  * Information we keep for each pending request.  We should try to
  * keep this struct as small as possible since its memory consumption
@@ -355,6 +362,13 @@ struct PendingRequest
    */
   struct GNUNET_SERVER_Client *client;
 
+  /**
+   * If this request was made by a client,
+   * this is our entry in the client request
+   * list; otherwise NULL.
+   */
+  struct ClientRequestList *crl_entry;
+
   /**
    * If this is a namespace query, pointer to the hash of the public
    * key of the namespace; otherwise NULL.
@@ -451,6 +465,60 @@ struct PendingRequest
 };
 
 
+/**
+ * All requests from a client are 
+ * kept in a doubly-linked list.
+ */
+struct ClientRequestList
+{
+  /**
+   * This is a doubly-linked list.
+   */
+  struct ClientRequestList *next;
+
+  /**
+   * This is a doubly-linked list.
+   */ 
+  struct ClientRequestList *prev;
+
+  /**
+   * A request from this client.
+   */
+  struct PendingRequest *req;
+
+};
+
+
+/**
+ * Linked list of all clients that we are 
+ * currently processing requests for.
+ */
+struct ClientList
+{
+
+  /**
+   * This is a linked list.
+   */
+  struct ClientList *next;
+
+  /**
+   * What client is this entry for?
+   */
+  struct GNUNET_SERVER_Client* client;
+
+  /**
+   * Head of the DLL of requests from this client.
+   */
+  struct ClientRequestList *head;
+
+  /**
+   * Tail of the DLL of requests from this client.
+   */
+  struct ClientRequestList *tail;
+
+};
+
+
 /**
  * Closure for "process_reply" function.
  */
@@ -505,8 +573,7 @@ static struct GNUNET_SCHEDULER_Handle *sched;
 const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 /**
- * Handle to the core service (NULL until we've
- * connected to it).
+ * Handle to the core service (NULL until we've connected to it).
  */
 struct GNUNET_CORE_Handle *core;
 
@@ -543,6 +610,27 @@ static struct IndexInfo *indexed_files;
  */
 static struct GNUNET_CONTAINER_MultiHashMap *ifm;
 
+/**
+ * Map of query hash codes to requests.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *requests_by_query;
+
+/**
+ * Map of peer IDs to requests (for those requests coming
+ * from other peers).
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *requests_by_peer;
+
+/**
+ * Linked list of all of our clients and their requests.
+ */
+static struct ClientList *clients;
+
+/**
+ * Heap with the request that will expire next at the top.
+ */
+static struct GNUNET_CONTAINER_Heap *requests_by_expiration;
+
 
 /**
  * Write the current index information list to disk.
@@ -1467,6 +1555,35 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = {
 };
 
 
+/**
+ * Clean up the memory used by the PendingRequest
+ * structure (except for the client or peer list
+ * that the request may be part of).
+ *
+ * @param pr request to clean up
+ */
+static void
+destroy_pending_request (struct PendingRequest *pr)
+{
+  GNUNET_CONTAINER_multihashmap_remove (requests_by_query,
+                                       &pr->query,
+                                       pr);
+  // FIXME: not sure how this can work (efficiently)
+  // also, what does the return value mean?
+  GNUNET_CONTAINER_heap_remove_node (requests_by_expiration,
+                                    pr);
+  if (NULL != pr->bf)
+    GNUNET_CONTAINER_bloomfilter_free (pr->bf);
+  GNUNET_PEER_change_rc (pr->source_pid, -1);
+  GNUNET_PEER_change_rc (pr->target_pid, -1);
+  GNUNET_PEER_decrement_rcs (pr->used_pids, pr->used_pids_off);
+  GNUNET_free_non_null (pr->used_pids);
+  GNUNET_free_non_null (pr->replies_seen);
+  GNUNET_free_non_null (pr->namespace);
+  GNUNET_free (pr);
+}
+
+
 /**
  * A client disconnected.  Remove all of its pending queries.
  *
@@ -1479,14 +1596,38 @@ handle_client_disconnect (void *cls,
                          * client)
 {
   struct LocalGetContext *lgc;
+  struct ClientList *cpos;
+  struct ClientList *cprev;
+  struct ClientRequestList *rl;
 
   lgc = lgc_head;
   while ( (NULL != lgc) &&
          (lgc->client != client) )
     lgc = lgc->next;
-  if (lgc == NULL)
-    return; /* not one of our clients */
-  local_get_context_free (lgc);
+  if (lgc != NULL)
+    local_get_context_free (lgc);
+  cprev = NULL;
+  cpos = clients;
+  while ( (NULL != cpos) &&
+         (clients->client != client) )
+    {
+      cprev = cpos;
+      cpos = cpos->next;
+    }
+  if (cpos != NULL)
+    {
+      if (cprev == NULL)
+       clients = cpos->next;
+      else
+       cprev->next = cpos->next;
+      while (NULL != (rl = cpos->head))
+       {
+         cpos->head = rl->next;
+         destroy_pending_request (rl->req);
+         GNUNET_free (rl);
+       }
+      GNUNET_free (cpos);
+    }
 }
 
 
@@ -1520,6 +1661,30 @@ shutdown_task (void *cls,
 }
 
 
+/**
+ * Free (each) request made by the peer.
+ *
+ * @param cls closure, points to peer that the request belongs to
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES (we should continue to iterate)
+ */
+static int
+destroy_request (void *cls,
+                const GNUNET_HashCode * key,
+                void *value)
+{
+  const struct GNUNET_PeerIdentity * peer = cls;
+  struct PendingRequest *pr = value;
+  
+  GNUNET_CONTAINER_multihashmap_remove (requests_by_peer,
+                                       &peer->hashPubKey,
+                                       pr);
+  destroy_pending_request (pr);
+  return GNUNET_YES;
+}
+
+
 /**
  * Method called whenever a peer disconnects.
  *
@@ -1531,9 +1696,10 @@ peer_disconnect_handler (void *cls,
                         const struct
                         GNUNET_PeerIdentity * peer)
 {
-  // FIXME: remove all pending requests from this
-  // peer from our memory
-  // (iterate over request_map)
+  GNUNET_CONTAINER_multihashmap_get_multiple (requests_by_peer,
+                                             &peer->hashPubKey,
+                                             &destroy_request,
+                                             (void*) peer);
 }
 
 
@@ -1565,6 +1731,7 @@ forward_get_request (void *cls,
  * the target buffer "buf".  "buf" will be
  * NULL and "size" zero if the socket was closed for
  * writing in the meantime.  In that case, only
+
  * free the message
  *
  * @param cls closure, pointer to the message
index d7e5ada548b4dd0858d43ba06494937454594c35..c0e64b3f4cade158a28c97466bf33b8c0508f42f 100644 (file)
@@ -24,6 +24,7 @@ libgnunetutil_la_SOURCES = \
   configuration.c \
   connection.c \
   container_bloomfilter.c \
+  container_heap.c \
   container_meta_data.c \
   container_multihashmap.c \
   crypto_aes.c \
index b5ccd795051c3f8bb80fa06f414eb149ca7200d0..7e41c40f251ab3bc4f07cb24043800af385140cd 100644 (file)
@@ -26,8 +26,7 @@
 
 #include "platform.h"
 #include "gnunet_protocols.h"
-#include "gnunet_util.h"
-#include "gnunet_util_containers.h"
+#include "gnunet_util_lib.h"
 
 /*
  * Struct that is stored in hashmap, pointers to
@@ -65,7 +64,7 @@ struct GNUNET_CONTAINER_Heap
 
   unsigned int max_size;
 
-  enum type;
+  enum GNUNET_CONTAINER_HeapOrder type;
 
   struct GNUNET_CONTAINER_heap_node *root;
 
@@ -96,7 +95,7 @@ printTree (struct GNUNET_CONTAINER_Heap *root)
 }
 
 struct GNUNET_CONTAINER_Heap *
-GNUNET_CONTAINER_heap_create (enum type)
+GNUNET_CONTAINER_heap_create (enum GNUNET_CONTAINER_HeapOrder type)
 {
   struct GNUNET_CONTAINER_Heap *heap;
   heap = malloc (sizeof (struct GNUNET_CONTAINER_Heap));
@@ -491,7 +490,7 @@ internal_iterator (struct GNUNET_CONTAINER_Heap *root,
     return;
   internal_iterator (root, node->left_child, iterator, cls);
   internal_iterator (root, node->right_child, iterator, cls);
-  iterator (node->element, node->cost, root, cls);
+  iterator (cls, node->element, node->cost);
 }
 
 int
@@ -519,7 +518,7 @@ GNUNET_CONTAINER_heap_walk_get_next (struct GNUNET_CONTAINER_Heap *root)
 
   element = root->traversal_pos->element;
 
-  choice = GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, 2);
+  choice = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2);
 
   switch (choice)
     {