gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r35662 - in gnunet/src: datacache include util


From: gnunet
Subject: [GNUnet-SVN] r35662 - in gnunet/src: datacache include util
Date: Tue, 28 Apr 2015 17:05:12 +0200

Author: grothoff
Date: 2015-04-28 17:05:12 +0200 (Tue, 28 Apr 2015)
New Revision: 35662

Modified:
   gnunet/src/datacache/datacache.c
   gnunet/src/datacache/plugin_datacache_heap.c
   gnunet/src/include/gnunet_container_lib.h
   gnunet/src/include/gnunet_datacache_lib.h
   gnunet/src/include/gnunet_datacache_plugin.h
   gnunet/src/util/container_multihashmap.c
Log:
extending datacache API with function to return random element, implemented 
(only) in heap plugin right now

Modified: gnunet/src/datacache/datacache.c
===================================================================
--- gnunet/src/datacache/datacache.c    2015-04-28 13:21:44 UTC (rev 35661)
+++ gnunet/src/datacache/datacache.c    2015-04-28 15:05:12 UTC (rev 35662)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and 
other contributing authors)
+     Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2015 Christian Grothoff 
(and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -17,7 +17,6 @@
      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      Boston, MA 02111-1307, USA.
 */
-
 /**
  * @file datacache/datacache.c
  * @brief datacache API implementation
@@ -103,18 +102,26 @@
  * @param size number of bytes that were made available
  */
 static void
-env_delete_notify (void *cls, const struct GNUNET_HashCode * key, size_t size)
+env_delete_notify (void *cls,
+                   const struct GNUNET_HashCode *key,
+                   size_t size)
 {
   struct GNUNET_DATACACHE_Handle *h = cls;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Content under key `%s' discarded\n",
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Content under key `%s' discarded\n",
        GNUNET_h2s (key));
   GNUNET_assert (h->utilization >= size);
   h->utilization -= size;
-  GNUNET_CONTAINER_bloomfilter_remove (h->filter, key);
-  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), - (long 
long) size,
+  GNUNET_CONTAINER_bloomfilter_remove (h->filter,
+                                       key);
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# bytes stored"),
+                            - (long long) size,
                             GNUNET_NO);
-  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# items stored"), -1,
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# items stored"),
+                            -1,
                             GNUNET_NO);
 }
 
@@ -137,18 +144,25 @@
   char *name;
 
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", &quota))
+      GNUNET_CONFIGURATION_get_value_size (cfg,
+                                           section,
+                                           "QUOTA",
+                                           &quota))
   {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("No `%s' specified for `%s' in configuration!\n"), "QUOTA", 
section);
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               section,
+                               "QUOTA");
     return NULL;
   }
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name))
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             section,
+                                             "DATABASE",
+                                             &name))
   {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("No `%s' specified for `%s' in configuration!\n"), "DATABASE",
-         section);
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               section,
+                               "DATABASE");
     return NULL;
   }
   bf_size = quota / 32;         /* 8 bit per entry, 1 bit per 32 kb in DB */
@@ -165,12 +179,15 @@
     }
     if (NULL != ret->bloom_name)
     {
-      ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, quota 
/ 1024,     /* 8 bit per entry in DB, expect 1k entries */
+      ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name,
+                                                       quota / 1024,     /* 8 
bit per entry in DB, expect 1k entries */
                                                       5);
     }
     if (NULL == ret->filter)
     {
-       ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, bf_size, 5); /* 
approx. 3% false positives at max use */
+       ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL,
+                                                         bf_size,
+                                                         5); /* approx. 3% 
false positives at max use */
     }
   }
   ret->stats = GNUNET_STATISTICS_create ("datacache", cfg);
@@ -181,15 +198,20 @@
   ret->env.cls = ret;
   ret->env.delete_notify = &env_delete_notify;
   ret->env.quota = quota;
-  LOG (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datacache plugin\n"), name);
-  GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name);
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       _("Loading `%s' datacache plugin\n"),
+       name);
+  GNUNET_asprintf (&libname,
+                   "libgnunet_plugin_datacache_%s",
+                   name);
   ret->short_name = name;
   ret->lib_name = libname;
   ret->api = GNUNET_PLUGIN_load (libname, &ret->env);
   if (ret->api == NULL)
   {
     LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("Failed to load datacache plugin for `%s'\n"), name);
+         _("Failed to load datacache plugin for `%s'\n"),
+         name);
     GNUNET_DATACACHE_destroy (ret);
     return NULL;
   }
@@ -207,16 +229,18 @@
 {
   if (NULL != h->filter)
     GNUNET_CONTAINER_bloomfilter_free (h->filter);
-  if (h->api != NULL)
+  if (NULL != h->api)
     GNUNET_break (NULL == GNUNET_PLUGIN_unload (h->lib_name, h->api));
   GNUNET_free (h->lib_name);
   GNUNET_free (h->short_name);
   GNUNET_free (h->section);
-  if (h->bloom_name != NULL)
+  if (NULL != h->bloom_name)
   {
     if (0 != UNLINK (h->bloom_name))
-      GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING, "datacache",
-                                     "unlink", h->bloom_name);
+      GNUNET_log_from_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                     "datacache",
+                                     "unlink",
+                                     h->bloom_name);
     GNUNET_free (h->bloom_name);
   }
   GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO);
@@ -229,7 +253,7 @@
  *
  * @param h handle to the datacache
  * @param key key to store data under
- * @param size number of bytes in data
+ * @param data_size number of bytes in @a data
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
@@ -239,8 +263,10 @@
  */
 int
 GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
-                      const struct GNUNET_HashCode * key, size_t size,
-                      const char *data, enum GNUNET_BLOCK_Type type,
+                      const struct GNUNET_HashCode *key,
+                      size_t data_size,
+                      const char *data,
+                      enum GNUNET_BLOCK_Type type,
                       struct GNUNET_TIME_Absolute discard_time,
                      unsigned int path_info_len,
                      const struct GNUNET_PeerIdentity *path_info)
@@ -248,7 +274,7 @@
   ssize_t used;
 
   used = h->api->put (h->api->cls, key,
-                     size, data,
+                     data_size, data,
                      type, discard_time,
                      path_info_len, path_info);
   if (-1 == used)
@@ -261,11 +287,16 @@
     /* duplicate */
     return GNUNET_NO;
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Stored data under key `%s' in cache\n",
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Stored data under key `%s' in cache\n",
        GNUNET_h2s (key));
-  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# bytes stored"), size,
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# bytes stored"),
+                            data_size,
                             GNUNET_NO);
-  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# items stored"), 1,
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# items stored"),
+                            1,
                             GNUNET_NO);
   if (NULL != h->filter)
     GNUNET_CONTAINER_bloomfilter_add (h->filter, key);
@@ -284,32 +315,64 @@
  * @param key what to look up
  * @param type entries of which type are relevant?
  * @param iter maybe NULL (to just count)
- * @param iter_cls closure for iter
+ * @param iter_cls closure for @a iter
  * @return the number of results found
  */
 unsigned int
 GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
-                      const struct GNUNET_HashCode * key, enum 
GNUNET_BLOCK_Type type,
-                      GNUNET_DATACACHE_Iterator iter, void *iter_cls)
+                      const struct GNUNET_HashCode *key,
+                      enum GNUNET_BLOCK_Type type,
+                      GNUNET_DATACACHE_Iterator iter,
+                      void *iter_cls)
 {
-  GNUNET_STATISTICS_update (h->stats, gettext_noop ("# requests received"), 1,
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# requests received"),
+                            1,
                             GNUNET_NO);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing request for key `%s'\n",
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Processing request for key `%s'\n",
        GNUNET_h2s (key));
   if ( (NULL != h->filter) &&
        (GNUNET_OK != GNUNET_CONTAINER_bloomfilter_test (h->filter, key)) )
   {
     GNUNET_STATISTICS_update (h->stats,
-                              gettext_noop
-                              ("# requests filtered by bloom filter"), 1,
+                              gettext_noop ("# requests filtered by bloom 
filter"),
+                              1,
                               GNUNET_NO);
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Bloomfilter filters request for key `%s'\n",
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Bloomfilter filters request for key `%s'\n",
          GNUNET_h2s (key));
     return 0;                   /* can not be present */
   }
-  return h->api->get (h->api->cls, key, type, iter, iter_cls);
+  return h->api->get (h->api->cls,
+                      key, type,
+                      iter, iter_cls);
 }
 
 
+/**
+ * Obtain a random element from the datacache.
+ *
+ * @param h handle to the datacache
+ * @param iter maybe NULL (to just count)
+ * @param iter_cls closure for @a iter
+ * @return the number of results found (zero or 1)
+ */
+unsigned int
+GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h,
+                             GNUNET_DATACACHE_Iterator iter,
+                             void *iter_cls)
+{
+  GNUNET_STATISTICS_update (h->stats,
+                            gettext_noop ("# requests for random value 
received"),
+                            1,
+                            GNUNET_NO);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Processing request for random value\n");
+  return h->api->get_random (h->api->cls,
+                             iter,
+                             iter_cls);
+}
 
-/* end of datacache_api.c */
+
+/* end of datacache.c */

Modified: gnunet/src/datacache/plugin_datacache_heap.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_heap.c        2015-04-28 13:21:44 UTC 
(rev 35661)
+++ gnunet/src/datacache/plugin_datacache_heap.c        2015-04-28 15:05:12 UTC 
(rev 35662)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     Copyright (C) 2012 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2012, 2015 Christian Grothoff (and other contributing 
authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -87,7 +87,7 @@
   size_t size;
 
   /**
-   * Number of entries in 'path_info'.
+   * Number of entries in @e path_info.
    */
   unsigned int path_info_len;
 
@@ -103,7 +103,7 @@
 
 
 /**
- * Closure for 'put_cb'.
+ * Closure for #put_cb().
  */
 struct PutContext
 {
@@ -128,7 +128,7 @@
   const struct GNUNET_PeerIdentity *path_info;
 
   /**
-   * Number of bytes in 'data'.
+   * Number of bytes in @e data.
    */
   size_t size;
 
@@ -138,12 +138,12 @@
   enum GNUNET_BLOCK_Type type;
 
   /**
-   * Number of entries in 'path_info'.
+   * Number of entries in @e path_info.
    */
   unsigned int path_info_len;
 
   /**
-   * Value to set to GNUNET_YES if an equivalent block was found.
+   * Value to set to #GNUNET_YES if an equivalent block was found.
    */
   int found;
 };
@@ -153,7 +153,7 @@
  * Function called during PUT to detect if an equivalent block
  * already exists.
  *
- * @param cls the 'struct PutContext'
+ * @param cls the `struct PutContext`
  * @param key the key for the value(s)
  * @param value an existing value
  * @return #GNUNET_YES if not found (to continue to iterate)
@@ -200,17 +200,20 @@
  *
  * @param cls closure (our `struct Plugin`)
  * @param key key to store data under
- * @param size number of bytes in data
+ * @param size number of bytes in @a data
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
  * @param path_info_len number of entries in @a path_info
  * @param path_info a path through the network
-   * @return 0 if duplicate, -1 on error, number of bytes used otherwise
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
  */
 static ssize_t
-heap_plugin_put (void *cls, const struct GNUNET_HashCode * key, size_t size,
-                const char *data, enum GNUNET_BLOCK_Type type,
+heap_plugin_put (void *cls,
+                 const struct GNUNET_HashCode *key,
+                 size_t size,
+                const char *data,
+                 enum GNUNET_BLOCK_Type type,
                 struct GNUNET_TIME_Absolute discard_time,
                 unsigned int path_info_len,
                 const struct GNUNET_PeerIdentity *path_info)
@@ -229,7 +232,7 @@
   put_ctx.type = type;
   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
                                              key,
-                                             put_cb,
+                                             &put_cb,
                                              &put_ctx);
   if (GNUNET_YES == put_ctx.found)
     return 0;
@@ -256,7 +259,7 @@
 
 
 /**
- * Closure for 'get_cb'.
+ * Closure for #get_cb().
  */
 struct GetContext
 {
@@ -266,7 +269,7 @@
   GNUNET_DATACACHE_Iterator iter;
 
   /**
-   * Closure for 'iter'.
+   * Closure for @e iter.
    */
   void *iter_cls;
 
@@ -287,10 +290,10 @@
  * Function called during GET to find matching blocks.
  * Only matches by type.
  *
- * @param cls the 'struct GetContext'
+ * @param cls the `struct GetContext`
  * @param key the key for the value(s)
  * @param value an existing value
- * @return GNUNET_YES to continue to iterate
+ * @return #GNUNET_YES to continue to iterate
  */
 static int
 get_cb (void *cls,
@@ -310,7 +313,7 @@
                         val->size,
                         (const char *) &val[1],
                         val->type,
-                      val->discard_time,
+                         val->discard_time,
                         val->path_info_len,
                         val->path_info);
   else
@@ -324,17 +327,19 @@
  * Iterate over the results for a particular key
  * in the datastore.
  *
- * @param cls closure (our "struct Plugin")
+ * @param cls closure (our `struct Plugin`)
  * @param key
  * @param type entries of which type are relevant?
  * @param iter maybe NULL (to just count)
- * @param iter_cls closure for iter
+ * @param iter_cls closure for @a iter
  * @return the number of results found
  */
 static unsigned int
-heap_plugin_get (void *cls, const struct GNUNET_HashCode * key,
-                   enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter,
-                   void *iter_cls)
+heap_plugin_get (void *cls,
+                 const struct GNUNET_HashCode *key,
+                 enum GNUNET_BLOCK_Type type,
+                 GNUNET_DATACACHE_Iterator iter,
+                 void *iter_cls)
 {
   struct Plugin *plugin = cls;
   struct GetContext get_ctx;
@@ -345,7 +350,7 @@
   get_ctx.cnt = 0;
   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
                                              key,
-                                             get_cb,
+                                             &get_cb,
                                              &get_ctx);
   return get_ctx.cnt;
 }
@@ -355,7 +360,7 @@
  * Delete the entry with the lowest expiration value
  * from the datacache right now.
  *
- * @param cls closure (our "struct Plugin")
+ * @param cls closure (our `struct Plugin`)
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 static int
@@ -381,6 +386,33 @@
 
 
 /**
+ * Return a random value from the datastore.
+ *
+ * @param cls closure (our `struct Plugin`)
+ * @param iter maybe NULL (to just count)
+ * @param iter_cls closure for @a iter
+ * @return the number of results found
+ */
+static unsigned int
+heap_plugin_get_random (void *cls,
+                        GNUNET_DATACACHE_Iterator iter,
+                        void *iter_cls)
+{
+  struct Plugin *plugin = cls;
+  struct GetContext get_ctx;
+
+  get_ctx.type = GNUNET_BLOCK_TYPE_ANY;
+  get_ctx.iter = iter;
+  get_ctx.iter_cls = iter_cls;
+  get_ctx.cnt = 0;
+  GNUNET_CONTAINER_multihashmap_get_random (plugin->map,
+                                            &get_cb,
+                                            &get_ctx);
+  return get_ctx.cnt;
+}
+
+
+/**
  * Entry point for the plugin.
  *
  * @param cls closure (the `struct GNUNET_DATACACHE_PluginEnvironmnet`)
@@ -403,7 +435,9 @@
   api->get = &heap_plugin_get;
   api->put = &heap_plugin_put;
   api->del = &heap_plugin_del;
-  LOG (GNUNET_ERROR_TYPE_INFO, _("Heap datacache running\n"));
+  api->get_random = &heap_plugin_get_random;
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       _("Heap datacache running\n"));
   return api;
 }
 

Modified: gnunet/src/include/gnunet_container_lib.h
===================================================================
--- gnunet/src/include/gnunet_container_lib.h   2015-04-28 13:21:44 UTC (rev 
35661)
+++ gnunet/src/include/gnunet_container_lib.h   2015-04-28 15:05:12 UTC (rev 
35662)
@@ -854,6 +854,22 @@
                                             void *it_cls);
 
 
+/**
+ * @ingroup hashmap
+ * Call @a it on a random value from the map, or not at all
+ * if the map is empty.
+ *
+ * @param map the map
+ * @param it function to call on a random entry
+ * @param it_cls extra argument to @a it
+ * @return the number of key value pairs processed, zero or one.
+ */
+unsigned int
+GNUNET_CONTAINER_multihashmap_get_random (const struct 
GNUNET_CONTAINER_MultiHashMap *map,
+                                          GNUNET_CONTAINER_HashMapIterator it,
+                                          void *it_cls);
+
+
 /* ***************** Version of Multihashmap for peer identities 
****************** */
 
 /**

Modified: gnunet/src/include/gnunet_datacache_lib.h
===================================================================
--- gnunet/src/include/gnunet_datacache_lib.h   2015-04-28 13:21:44 UTC (rev 
35661)
+++ gnunet/src/include/gnunet_datacache_lib.h   2015-04-28 15:05:12 UTC (rev 
35662)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     Copyright (C) 2006, 2009 Christian Grothoff (and other contributing 
authors)
+     Copyright (C) 2006, 2009, 2015 Christian Grothoff (and other contributing 
authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -75,21 +75,23 @@
  *
  * @param cls closure
  * @param key key for the content
- * @param size number of bytes in data
+ * @param data_size number of bytes in @a data
  * @param data content stored
  * @param type type of the content
  * @param exp when will the content expire?
- * @param path_info_len number of entries in 'path_info'
+ * @param path_info_len number of entries in @a path_info
  * @param path_info a path through the network
- * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort
+ * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort
  */
-typedef int (*GNUNET_DATACACHE_Iterator) (void *cls,
-                                          const struct GNUNET_HashCode *key,
-                                          size_t size, const char *data,
-                                          enum GNUNET_BLOCK_Type type,
-                                          struct GNUNET_TIME_Absolute exp,
-                                         unsigned int path_info_len,
-                                         const struct GNUNET_PeerIdentity 
*path_info);
+typedef int
+(*GNUNET_DATACACHE_Iterator) (void *cls,
+                              const struct GNUNET_HashCode *key,
+                              size_t data_size,
+                              const char *data,
+                              enum GNUNET_BLOCK_Type type,
+                              struct GNUNET_TIME_Absolute exp,
+                              unsigned int path_info_len,
+                              const struct GNUNET_PeerIdentity *path_info);
 
 
 /**
@@ -97,18 +99,20 @@
  *
  * @param h handle to the datacache
  * @param key key to store data under
- * @param size number of bytes in data
+ * @param data_size number of bytes in @a data
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @param path_info_len number of entries in 'path_info'
+ * @param path_info_len number of entries in @a path_info
  * @param path_info a path through the network
- * @return GNUNET_OK on success, GNUNET_SYSERR on error, GNUNET_NO if duplicate
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error, #GNUNET_NO if 
duplicate
  */
 int
 GNUNET_DATACACHE_put (struct GNUNET_DATACACHE_Handle *h,
-                      const struct GNUNET_HashCode * key, size_t size,
-                      const char *data, enum GNUNET_BLOCK_Type type,
+                      const struct GNUNET_HashCode *key,
+                      size_t data_size,
+                      const char *data,
+                      enum GNUNET_BLOCK_Type type,
                       struct GNUNET_TIME_Absolute discard_time,
                      unsigned int path_info_len,
                      const struct GNUNET_PeerIdentity *path_info);
@@ -122,15 +126,32 @@
  * @param key what to look up
  * @param type entries of which type are relevant?
  * @param iter maybe NULL (to just count)
- * @param iter_cls closure for iter
+ * @param iter_cls closure for @a iter
  * @return the number of results found
  */
 unsigned int
 GNUNET_DATACACHE_get (struct GNUNET_DATACACHE_Handle *h,
-                      const struct GNUNET_HashCode * key, enum 
GNUNET_BLOCK_Type type,
+                      const struct GNUNET_HashCode *key,
+                      enum GNUNET_BLOCK_Type type,
                       GNUNET_DATACACHE_Iterator iter, void *iter_cls);
 
 
+/**
+ * Obtain a random element from the datacache.
+ *
+ * @param h handle to the datacache
+ * @param iter maybe NULL (to just count)
+ * @param iter_cls closure for @a iter
+ * @return the number of results found (zero or 1)
+ */
+unsigned int
+GNUNET_DATACACHE_get_random (struct GNUNET_DATACACHE_Handle *h,
+                             GNUNET_DATACACHE_Iterator iter,
+                             void *iter_cls);
+
+
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif

Modified: gnunet/src/include/gnunet_datacache_plugin.h
===================================================================
--- gnunet/src/include/gnunet_datacache_plugin.h        2015-04-28 13:21:44 UTC 
(rev 35661)
+++ gnunet/src/include/gnunet_datacache_plugin.h        2015-04-28 15:05:12 UTC 
(rev 35662)
@@ -45,9 +45,10 @@
  * @param key key of the content that was deleted
  * @param size number of bytes that were made available
  */
-typedef void (*GNUNET_DATACACHE_DeleteNotifyCallback) (void *cls,
-                                                       const struct 
GNUNET_HashCode *
-                                                       key, size_t size);
+typedef void
+(*GNUNET_DATACACHE_DeleteNotifyCallback) (void *cls,
+                                          const struct GNUNET_HashCode *key,
+                                          size_t size);
 
 
 /**
@@ -58,7 +59,6 @@
 struct GNUNET_DATACACHE_PluginEnvironment
 {
 
-
   /**
    * Configuration to use.
    */
@@ -103,47 +103,63 @@
    * Store an item in the datastore.
    *
    * @param cls closure (internal context for the plugin)
-   * @param size number of bytes in data
+   * @param key key to store the value under
+   * @param size number of bytes in @a data
    * @param data data to store
    * @param type type of the value
    * @param discard_time when to discard the value in any case
-   * @param path_info_len number of entries in 'path_info'
+   * @param path_info_len number of entries in @a path_info
    * @param path_info a path through the network
    * @return 0 if duplicate, -1 on error, number of bytes used otherwise
    */
-  ssize_t (*put) (void *cls, const struct GNUNET_HashCode * key, size_t size,
-                 const char *data, enum GNUNET_BLOCK_Type type,
+  ssize_t (*put) (void *cls,
+                  const struct GNUNET_HashCode *key,
+                  size_t size,
+                 const char *data,
+                  enum GNUNET_BLOCK_Type type,
                  struct GNUNET_TIME_Absolute discard_time,
                  unsigned int path_info_len,
                  const struct GNUNET_PeerIdentity *path_info);
 
-
   /**
    * Iterate over the results for a particular key
    * in the datastore.
    *
    * @param cls closure (internal context for the plugin)
-   * @param key
+   * @param key key to look for
    * @param type entries of which type are relevant?
    * @param iter maybe NULL (to just count)
-   * @param iter_cls closure for iter
+   * @param iter_cls closure for @a iter
    * @return the number of results found
    */
-  unsigned int (*get) (void *cls, const struct GNUNET_HashCode * key,
+  unsigned int (*get) (void *cls,
+                       const struct GNUNET_HashCode * key,
                        enum GNUNET_BLOCK_Type type,
-                       GNUNET_DATACACHE_Iterator iter, void *iter_cls);
+                       GNUNET_DATACACHE_Iterator iter,
+                       void *iter_cls);
 
-
   /**
    * Delete the entry with the lowest expiration value
    * from the datacache right now.
    *
    * @param cls closure (internal context for the plugin)
-   * @return GNUNET_OK on success, GNUNET_SYSERR on error
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
    */
   int (*del) (void *cls);
 
+  /**
+   * Return a random value from the datastore.
+   *
+   * @param cls closure (internal context for the plugin)
+   * @param iter maybe NULL (to just count)
+   * @param iter_cls closure for @a iter
+   * @return the number of results found (zero or one)
+   */
+  unsigned int (*get_random) (void *cls,
+                              GNUNET_DATACACHE_Iterator iter,
+                              void *iter_cls);
 
+
 };
 
 

Modified: gnunet/src/util/container_multihashmap.c
===================================================================
--- gnunet/src/util/container_multihashmap.c    2015-04-28 13:21:44 UTC (rev 
35661)
+++ gnunet/src/util/container_multihashmap.c    2015-04-28 15:05:12 UTC (rev 
35662)
@@ -839,6 +839,79 @@
 
 
 /**
+ * @ingroup hashmap
+ * Call @a it on a random value from the map, or not at all
+ * if the map is empty.
+ *
+ * @param map the map
+ * @param it function to call on a random entry
+ * @param it_cls extra argument to @a it
+ * @return the number of key value pairs processed, zero or one.
+ */
+unsigned int
+GNUNET_CONTAINER_multihashmap_get_random (const struct 
GNUNET_CONTAINER_MultiHashMap *map,
+                                          GNUNET_CONTAINER_HashMapIterator it,
+                                          void *it_cls)
+{
+  unsigned int off;
+  unsigned int idx;
+  union MapEntry me;
+
+  if (0 == map->size)
+    return 0;
+  if (NULL == it)
+    return 1;
+  off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+                                  map->size);
+  for (idx = 0; idx < map->map_length; idx++)
+  {
+    me = map->map[idx];
+    if (map->use_small_entries)
+    {
+      struct SmallMapEntry *sme;
+      struct SmallMapEntry *nxt;
+
+      nxt = me.sme;
+      while (NULL != (sme = nxt))
+      {
+        nxt = sme->next;
+        if (0 == off)
+        {
+          if (GNUNET_OK != it (it_cls,
+                               sme->key,
+                               sme->value))
+            return GNUNET_SYSERR;
+          return 1;
+        }
+        off--;
+      }
+    }
+    else
+    {
+      struct BigMapEntry *bme;
+      struct BigMapEntry *nxt;
+
+      nxt = me.bme;
+      while (NULL != (bme = nxt))
+      {
+        nxt = bme->next;
+        if (0 == off)
+        {
+          if (GNUNET_OK != it (it_cls,
+                               &bme->key, bme->value))
+            return GNUNET_SYSERR;
+          return 1;
+        }
+        off--;
+      }
+    }
+  }
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+/**
  * Create an iterator for a multihashmap.
  * The iterator can be used to retrieve all the elements in the multihashmap
  * one by one, without having to handle all elements at once (in contrast to




reply via email to

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