gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r24938 - in gnunet/src: datacache dht include


From: gnunet
Subject: [GNUnet-SVN] r24938 - in gnunet/src: datacache dht include
Date: Tue, 13 Nov 2012 21:05:40 +0100

Author: grothoff
Date: 2012-11-13 21:05:40 +0100 (Tue, 13 Nov 2012)
New Revision: 24938

Added:
   gnunet/src/datacache/perf_datacache_data_heap.conf
   gnunet/src/datacache/test_datacache_data_heap.conf
Removed:
   gnunet/src/datacache/perf_datacache_data_mysql.conf
   gnunet/src/datacache/plugin_datacache_mysql.c
   gnunet/src/datacache/test_datacache_data_mysql.conf
Modified:
   gnunet/src/datacache/Makefile.am
   gnunet/src/datacache/datacache.c
   gnunet/src/datacache/perf_datacache.c
   gnunet/src/datacache/plugin_datacache_heap.c
   gnunet/src/datacache/plugin_datacache_postgres.c
   gnunet/src/datacache/plugin_datacache_sqlite.c
   gnunet/src/datacache/plugin_datacache_template.c
   gnunet/src/datacache/test_datacache.c
   gnunet/src/datacache/test_datacache_quota.c
   gnunet/src/dht/gnunet-service-dht_datacache.c
   gnunet/src/include/gnunet_datacache_lib.h
   gnunet/src/include/gnunet_datacache_plugin.h
Log:
changing datacache API to separate put-paths from data (so that plugins can 
test for duplicates), removing support for MySQL

Modified: gnunet/src/datacache/Makefile.am
===================================================================
--- gnunet/src/datacache/Makefile.am    2012-11-13 18:54:54 UTC (rev 24937)
+++ gnunet/src/datacache/Makefile.am    2012-11-13 20:05:40 UTC (rev 24938)
@@ -19,9 +19,6 @@
 if HAVE_SQLITE
   SQLITE_PLUGIN = libgnunet_plugin_datacache_sqlite.la
 endif
-if HAVE_MYSQL
-  MYSQL_PLUGIN = libgnunet_plugin_datacache_mysql.la
-endif
 if HAVE_POSTGRES
   POSTGRES_PLUGIN = libgnunet_plugin_datacache_postgres.la
 endif
@@ -42,7 +39,6 @@
 
 plugin_LTLIBRARIES = \
   $(SQLITE_PLUGIN) \
-  $(MYSQL_PLUGIN) \
   $(POSTGRES_PLUGIN) \
   libgnunet_plugin_datacache_heap.la \
   libgnunet_plugin_datacache_template.la 
@@ -66,18 +62,6 @@
 libgnunet_plugin_datacache_heap_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
 
-libgnunet_plugin_datacache_mysql_la_SOURCES = \
-  plugin_datacache_mysql.c
-libgnunet_plugin_datacache_mysql_la_LIBADD = \
-  $(top_builddir)/src/statistics/libgnunetstatistics.la \
-  $(top_builddir)/src/mysql/libgnunetmysql.la \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
-libgnunet_plugin_datacache_mysql_la_CPPFLAGS = \
- $(MYSQL_CPPFLAGS)
-libgnunet_plugin_datacache_mysql_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS) $(MYSQL_LDFLAGS) -lmysqlclient
-
 libgnunet_plugin_datacache_postgres_la_SOURCES = \
   plugin_datacache_postgres.c
 libgnunet_plugin_datacache_postgres_la_LIBADD = \
@@ -110,16 +94,14 @@
  $(SQLITE_BENCHMARKS)
 endif
 
-if HAVE_MYSQL
 if HAVE_BENCHMARKS
- MYSQL_BENCHMARKS = \
-  perf_datacache_mysql
+ HEAP_BENCHMARKS = \
+  perf_datacache_heap
 endif
-MYSQL_TESTS = \
- test_datacache_mysql \
- test_datacache_quota_mysql \
- $(MYSQL_BENCHMARKS)
-endif
+HEAP_TESTS = \
+ test_datacache_heap \
+ test_datacache_quota_heap \
+ $(HEAP_BENCHMARKS)
 
 if HAVE_POSTGRES
 if HAVE_BENCHMARKS
@@ -134,7 +116,7 @@
 
 check_PROGRAMS = \
  $(SQLITE_TESTS) \
- $(MYSQL_TESTS) \
+ $(HEAP_TESTS) \
  $(POSTGRES_TESTS) 
 
 if ENABLE_TEST_RUN
@@ -162,23 +144,23 @@
  $(top_builddir)/src/datacache/libgnunetdatacache.la \
  $(top_builddir)/src/util/libgnunetutil.la  
 
-test_datacache_mysql_SOURCES = \
+test_datacache_heap_SOURCES = \
  test_datacache.c
-test_datacache_mysql_LDADD = \
+test_datacache_heap_LDADD = \
  $(top_builddir)/src/testing/libgnunettesting.la \
  $(top_builddir)/src/datacache/libgnunetdatacache.la \
  $(top_builddir)/src/util/libgnunetutil.la  
 
-test_datacache_quota_mysql_SOURCES = \
+test_datacache_quota_heap_SOURCES = \
  test_datacache_quota.c
-test_datacache_quota_mysql_LDADD = \
+test_datacache_quota_heap_LDADD = \
  $(top_builddir)/src/testing/libgnunettesting.la \
  $(top_builddir)/src/datacache/libgnunetdatacache.la \
  $(top_builddir)/src/util/libgnunetutil.la  
 
-perf_datacache_mysql_SOURCES = \
+perf_datacache_heap_SOURCES = \
  perf_datacache.c
-perf_datacache_mysql_LDADD = \
+perf_datacache_heap_LDADD = \
  $(top_builddir)/src/testing/libgnunettesting.la \
  $(top_builddir)/src/datacache/libgnunetdatacache.la \
  $(top_builddir)/src/util/libgnunetutil.la  
@@ -207,7 +189,7 @@
 EXTRA_DIST = \
  test_datacache_data_sqlite.conf \
  perf_datacache_data_sqlite.conf \
- test_datacache_data_mysql.conf \
- perf_datacache_data_mysql.conf \
+ test_datacache_data_heap.conf \
+ perf_datacache_data_heap.conf \
  test_datacache_data_postgres.conf \
  perf_datacache_data_postgres.conf

Modified: gnunet/src/datacache/datacache.c
===================================================================
--- gnunet/src/datacache/datacache.c    2012-11-13 18:54:54 UTC (rev 24937)
+++ gnunet/src/datacache/datacache.c    2012-11-13 20:05:40 UTC (rev 24938)
@@ -233,22 +233,34 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return GNUNET_OK on success, GNUNET_SYSERR on error (full, etc.)
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @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,
-                      struct GNUNET_TIME_Absolute discard_time)
+                      struct GNUNET_TIME_Absolute discard_time,
+                     unsigned int path_info_len,
+                     const struct GNUNET_PeerIdentity *path_info)
 {
-  uint32_t used;
+  ssize_t used;
 
-  used = h->api->put (h->api->cls, key, size, data, type, discard_time);
-  if (0 == used)
+  used = h->api->put (h->api->cls, key, 
+                     size, data, 
+                     type, discard_time,
+                     path_info_len, path_info);
+  if (-1 == used)
   {
-    /* error or duplicate */
+    GNUNET_break (0);
     return GNUNET_SYSERR;
   }
+  if (0 == used)
+  {
+    /* duplicate */
+    return GNUNET_NO;
+  }
   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,

Modified: gnunet/src/datacache/perf_datacache.c
===================================================================
--- gnunet/src/datacache/perf_datacache.c       2012-11-13 18:54:54 UTC (rev 
24937)
+++ gnunet/src/datacache/perf_datacache.c       2012-11-13 20:05:40 UTC (rev 
24938)
@@ -44,9 +44,12 @@
 
 
 static int
-checkIt (void *cls, struct GNUNET_TIME_Absolute exp,
+checkIt (void *cls, 
          const struct GNUNET_HashCode * key, size_t size, const char *data,
-         enum GNUNET_BLOCK_Type type)
+         enum GNUNET_BLOCK_Type type,
+        struct GNUNET_TIME_Absolute exp,
+        unsigned int path_len,
+        const struct GNUNET_PeerIdentity *path)
 {
   if ((size == sizeof (struct GNUNET_HashCode)) && (0 == memcmp (data, cls, 
size)))
     found++;
@@ -84,7 +87,8 @@
     GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
     ASSERT (GNUNET_OK ==
             GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
-                                  (const char *) &n, 1 + i % 16, exp));
+                                  (const char *) &n, 1 + i % 16, exp,
+                                 0, NULL));
     k = n;
   }
   FPRINTF (stderr, "%s",  "\n");

Copied: gnunet/src/datacache/perf_datacache_data_heap.conf (from rev 24933, 
gnunet/src/datacache/perf_datacache_data_mysql.conf)
===================================================================
--- gnunet/src/datacache/perf_datacache_data_heap.conf                          
(rev 0)
+++ gnunet/src/datacache/perf_datacache_data_heap.conf  2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -0,0 +1,5 @@
+[perfcache]
+QUOTA = 500 KB
+DATABASE = heap
+
+

Deleted: gnunet/src/datacache/perf_datacache_data_mysql.conf
===================================================================
--- gnunet/src/datacache/perf_datacache_data_mysql.conf 2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/perf_datacache_data_mysql.conf 2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -1,13 +0,0 @@
-[perfcache]
-QUOTA = 500 KB
-DATABASE = mysql
-
-[datacache-mysql]
-DATABASE = gnunetcheck
-# CONFIG = ~/.my.cnf
-# USER =
-# PASSWORD =
-# HOST = 
-# PORT = 
-
-

Modified: gnunet/src/datacache/plugin_datacache_heap.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_heap.c        2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/plugin_datacache_heap.c        2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -32,6 +32,7 @@
 #define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, 
"datacache-heap", op, fn)
 
 
+
 /**
  * Context for all functions in this plugin.
  */
@@ -76,11 +77,21 @@
   struct GNUNET_CONTAINER_HeapNode *hn;
 
   /**
+   * Path information.
+   */
+  struct GNUNET_PeerIdentity *path_info;
+
+  /**
    * Payload (actual payload follows this struct)
    */
   size_t size;
 
   /**
+   * Number of entries in 'path_info'.
+   */
+  unsigned int path_info_len;
+
+  /**
    * Type of the block.
    */
   enum GNUNET_BLOCK_Type type;
@@ -88,6 +99,9 @@
 };
 
 
+#define OVERHEAD (sizeof (struct Value) + 64)
+
+
 /**
  * Closure for 'put_cb'.
  */
@@ -109,6 +123,11 @@
   struct GNUNET_CONTAINER_Heap *heap;
 
   /**
+   * Path information.
+   */
+  const struct GNUNET_PeerIdentity *path_info;
+
+  /**
    * Number of bytes in 'data'.
    */
   size_t size;
@@ -119,6 +138,11 @@
   enum GNUNET_BLOCK_Type type;
 
   /**
+   * Number of entries in 'path_info'.
+   */
+  unsigned int path_info_len;
+
+  /**
    * Value to set to GNUNET_YES if an equivalent block was found.
    */
   int found;
@@ -149,13 +173,20 @@
     put_ctx->found = GNUNET_YES;    
     val->discard_time = GNUNET_TIME_absolute_max (val->discard_time,
                                                  put_ctx->discard_time);
+    /* replace old path with new path */
+    GNUNET_array_grow (val->path_info,
+                      val->path_info_len,
+                      put_ctx->path_info_len);
+    memcpy (val->path_info, 
+           put_ctx->path_info,
+           put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity));   
     GNUNET_CONTAINER_heap_update_cost (put_ctx->heap,
                                       val->hn,
                                       val->discard_time.abs_value);
     return GNUNET_NO;
   }
   if (val->type == put_ctx->type)
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Got another value for key %s and type %d (size %u vs %u)\n",
                GNUNET_h2s (key),
                val->type,
@@ -174,12 +205,16 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+   * @return 0 if duplicate, -1 on error, number of bytes used otherwise
  */
-static size_t
+static ssize_t
 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)
+                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)
 {
   struct Plugin *plugin = cls;
   struct Value *val;
@@ -189,6 +224,8 @@
   put_ctx.heap = plugin->heap;
   put_ctx.data = data;
   put_ctx.size = size;
+  put_ctx.path_info = path_info;
+  put_ctx.path_info_len = path_info_len;
   put_ctx.discard_time = discard_time;
   put_ctx.type = type;
   GNUNET_CONTAINER_multihashmap_get_multiple (plugin->map,
@@ -203,6 +240,11 @@
   val->type = type;
   val->discard_time = discard_time;
   val->size = size;
+  GNUNET_array_grow (val->path_info,
+                    val->path_info_len,
+                    path_info_len);
+  memcpy (val->path_info, path_info,
+         path_info_len * sizeof (struct GNUNET_PeerIdentity));
   (void) GNUNET_CONTAINER_multihashmap_put (plugin->map,
                                            &val->key,
                                            val,
@@ -210,7 +252,7 @@
   val->hn = GNUNET_CONTAINER_heap_insert (plugin->heap,
                                          val,
                                          val->discard_time.abs_value);
-  return size;
+  return size + OVERHEAD;
 }
 
 
@@ -263,13 +305,17 @@
   if ( (get_ctx->type != val->type) &&
        (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
     return GNUNET_OK;
-  ret = get_ctx->iter (get_ctx->iter_cls,
+  if (NULL != get_ctx->iter)
+    ret = get_ctx->iter (get_ctx->iter_cls,
+                        key,
+                        val->size,
+                        (const char *) &val[1],
+                        val->type,
                       val->discard_time,
-                      key,
-                      val->size,
-                      (const char *) &val[1],
-                      val->type);
-                
+                        val->path_info_len,
+                        val->path_info);
+  else
+    ret = GNUNET_YES;
   get_ctx->cnt++;
   return ret;
 }
@@ -328,7 +374,8 @@
                                                       val));
   plugin->env->delete_notify (plugin->env->cls,
                              &val->key,
-                             val->size);
+                             val->size + OVERHEAD);
+  GNUNET_free_non_null (val->path_info);
   GNUNET_free (val);
   return GNUNET_OK;
 }

Deleted: gnunet/src/datacache/plugin_datacache_mysql.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_mysql.c       2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/plugin_datacache_mysql.c       2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -1,474 +0,0 @@
-/*
-     This file is part of GNUnet
-     (C) 2006, 2009, 2010 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
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file datacache/plugin_datacache_mysql.c
- * @brief mysql for an implementation of a database backend for the datacache
- * @author Christian Grothoff
- *
- * SETUP INSTRUCTIONS:
- *
- * 1) Access mysql as root,
- *    <pre>
- *
- *    $ mysql -u root -p
- *
- *    </pre>
- *    and do the following. [You should replace $USER with the username
- *    that will be running the gnunetd process].
- * @verbatim
-      CREATE DATABASE gnunet;
-      GRANT select,insert,update,delete,create,alter,drop,create temporary 
tables
-         ON gnunet.* TO address@hidden;
-      SET PASSWORD FOR address@hidden('$the_password_you_like');
-      FLUSH PRIVILEGES;
-   @endverbatim
- * 2) In the $HOME directory of $USER, create a ".my.cnf" file
- *    with the following lines
- * @verbatim
-      [client]
-      user=$USER
-      password=$the_password_you_like
-   @endverbatim
- *
- * Thats it -- now you can configure your datastores in GNUnet to
- * use MySQL. Note that .my.cnf file is a security risk unless its on
- * a safe partition etc. The $HOME/.my.cnf can of course be a symbolic
- * link. Even greater security risk can be achieved by setting no
- * password for $USER.  Luckily $USER has only priviledges to mess
- * up GNUnet's tables, nothing else (unless you give him more,
- * of course).<p>
- *
- * 3) Still, perhaps you should briefly try if the DB connection
- *    works. First, login as $USER. Then use,
- * @verbatim
-      $ mysql -u $USER -p $the_password_you_like
-      mysql> use gnunet;
-   @endverbatim
- *
- *    If you get the message &quot;Database changed&quot; it probably works.
- *
- *    [If you get &quot;ERROR 2002: Can't connect to local MySQL server
- *     through socket '/tmp/mysql.sock' (2)&quot; it may be resolvable by
- *     &quot;ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock&quot;
- *     so there may be some additional trouble depending on your mysql setup.]
- *
- * PROBLEMS?
- *
- * If you have problems related to the mysql module, your best
- * friend is probably the mysql manual. The first thing to check
- * is that mysql is basically operational, that you can connect
- * to it, create tables, issue queries etc.
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_datacache_plugin.h"
-#include "gnunet_mysql_lib.h"
-#include <mysql/mysql.h>
-
-
-/**
- * Estimate of the per-entry overhead (including indices).
- */
-#define OVERHEAD ((4*2+4*2+8*2+8*2+sizeof(struct GNUNET_HashCode)*5+8))
-
-/**
- * Die with an error message that indicates
- * a failure of the command 'cmd' with the message given
- * by strerror(errno).
- */
-#define DIE_MYSQL(cmd, dbh) do { GNUNET_log(GNUNET_ERROR_TYPE__ERROR, _("`%s' 
failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, 
mysql_error((dbh)->dbf)); GNUNET_abort(); } while(0);
-
-/**
- * Log an error message at log-level 'level' that indicates
- * a failure of the command 'cmd' on file 'filename'
- * with the message given by strerror(errno).
- */
-#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_log(level, _("`%s' failed at 
%s:%d with error: %s\n"), cmd, __FILE__, __LINE__, mysql_error((dbh)->dbf)); } 
while(0);
-
-
-/**
- * Context for all functions in this plugin.
- */
-struct Plugin
-{
-  /**
-   * Our execution environment.
-   */
-  struct GNUNET_DATACACHE_PluginEnvironment *env;
-
-  /**
-   * Handle to the mysql database.
-   */
-  struct GNUNET_MYSQL_Context *mc;
-
-#define SELECT_VALUE_STMT "SELECT value,expire FROM gn080dstore FORCE INDEX 
(hashidx) WHERE hash=? AND type=? AND expire >= ? LIMIT 1 OFFSET ?"
-  struct GNUNET_MYSQL_StatementHandle *select_value;
-
-#define COUNT_VALUE_STMT "SELECT count(*) FROM gn080dstore FORCE INDEX 
(hashidx) WHERE hash=? AND type=? AND expire >= ?"
-  struct GNUNET_MYSQL_StatementHandle *count_value;
-
-#define SELECT_OLD_VALUE_STMT "SELECT hash, vhash, type, value FROM 
gn080dstore FORCE INDEX (expireidx) ORDER BY puttime ASC LIMIT 1"
-  struct GNUNET_MYSQL_StatementHandle *select_old_value;
-
-#define DELETE_VALUE_STMT "DELETE FROM gn080dstore WHERE hash = ? AND vhash = 
? AND type = ? AND value = ?"
-  struct GNUNET_MYSQL_StatementHandle *delete_value;
-
-#define INSERT_VALUE_STMT "INSERT INTO gn080dstore (type, puttime, expire, 
hash, vhash, value) "\
-                          "VALUES (?, ?, ?, ?, ?, ?)"
-  struct GNUNET_MYSQL_StatementHandle *insert_value;
-
-#define UPDATE_VALUE_STMT "UPDATE gn080dstore FORCE INDEX (allidx) SET 
puttime=?, expire=? "\
-                          "WHERE hash=? AND vhash=? AND type=?"
-  struct GNUNET_MYSQL_StatementHandle *update_value;
-
-};
-
-
-/**
- * Create temporary table and prepare statements.
- *
- * @param plugin plugin context
- * @return GNUNET_OK on success
- */
-static int
-itable (struct Plugin *plugin)
-{
-#define MRUNS(a) (GNUNET_OK != GNUNET_MYSQL_statement_run (plugin->mc, a) )
-  if (MRUNS
-      ("CREATE TEMPORARY TABLE gn080dstore ("
-       "  type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
-       "  puttime BIGINT UNSIGNED NOT NULL DEFAULT 0,"
-       "  expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
-       "  hash BINARY(64) NOT NULL DEFAULT '',"
-       "  vhash BINARY(64) NOT NULL DEFAULT '',"
-       "  value BLOB NOT NULL DEFAULT '',"
-       "  INDEX hashidx (hash(64),type,expire),"
-       "  INDEX allidx (hash(64),vhash(64),type)," "  INDEX expireidx 
(puttime)"
-       ") ENGINE=InnoDB") || MRUNS ("SET AUTOCOMMIT = 1"))
-    return GNUNET_SYSERR;
-#undef MRUNS
-#define PINIT(a,b) (NULL == (a = GNUNET_MYSQL_statement_prepare (plugin->mc, 
b)))
-  if (PINIT (plugin->select_value, SELECT_VALUE_STMT) ||
-      PINIT (plugin->count_value, COUNT_VALUE_STMT) ||
-      PINIT (plugin->select_old_value, SELECT_OLD_VALUE_STMT) ||
-      PINIT (plugin->delete_value, DELETE_VALUE_STMT) ||
-      PINIT (plugin->insert_value, INSERT_VALUE_STMT) ||
-      PINIT (plugin->update_value, UPDATE_VALUE_STMT))
-    return GNUNET_SYSERR;
-#undef PINIT
-  return GNUNET_OK;
-}
-
-
-/**
- * Store an item in the datastore.
- *
- * @param cls closure (our "struct Plugin")
- * @param key key to store data under
- * @param size number of bytes in data
- * @param data data to store
- * @param type type of the value
- * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
- */
-static size_t
-mysql_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)
-{
-  struct Plugin *plugin = cls;
-  struct GNUNET_TIME_Absolute now;
-  unsigned long k_length;
-  unsigned long h_length;
-  unsigned long v_length;
-  unsigned long long v_now;
-  unsigned long long v_discard_time;
-  unsigned int v_type;
-  struct GNUNET_HashCode vhash;
-  int ret;
-
-  if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
-    return GNUNET_SYSERR;
-  GNUNET_CRYPTO_hash (data, size, &vhash);
-  now = GNUNET_TIME_absolute_get ();
-
-  /* first try UPDATE */
-  h_length = sizeof (struct GNUNET_HashCode);
-  k_length = sizeof (struct GNUNET_HashCode);
-  v_length = size;
-  v_type = type;
-  v_now = (unsigned long long) now.abs_value;
-  v_discard_time = (unsigned long long) discard_time.abs_value;
-  if (GNUNET_OK ==
-      GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->update_value, 
NULL,
-                              MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
-                              MYSQL_TYPE_LONGLONG, &v_discard_time, GNUNET_YES,
-                              MYSQL_TYPE_BLOB, key, sizeof (struct 
GNUNET_HashCode),
-                              &k_length, MYSQL_TYPE_BLOB, &vhash,
-                              sizeof (struct GNUNET_HashCode), &h_length,
-                              MYSQL_TYPE_LONG, &v_type, GNUNET_YES, -1))
-    return GNUNET_OK;
-
-  /* now try INSERT */
-  h_length = sizeof (struct GNUNET_HashCode);
-  k_length = sizeof (struct GNUNET_HashCode);
-  v_length = size;
-  if (GNUNET_OK !=
-      (ret =
-       GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->insert_value, 
NULL,
-                               MYSQL_TYPE_LONG, &type, GNUNET_YES,
-                               MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
-                               MYSQL_TYPE_LONGLONG, &v_discard_time, 
GNUNET_YES,
-                               MYSQL_TYPE_BLOB, key, sizeof (struct 
GNUNET_HashCode),
-                               &k_length, MYSQL_TYPE_BLOB, &vhash,
-                               sizeof (struct GNUNET_HashCode), &h_length,
-                               MYSQL_TYPE_BLOB, data, (unsigned long) size,
-                               &v_length, -1)))
-  {
-    if (ret == GNUNET_SYSERR)
-      itable (plugin);
-    return GNUNET_SYSERR;
-  }
-  return size + OVERHEAD;
-}
-
-
-static int
-return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
-{
-  return GNUNET_OK;
-}
-
-
-/**
- * Iterate over the results for a particular key
- * in the datastore.
- *
- * @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
- * @return the number of results found
- */
-static unsigned int
-mysql_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;
-  MYSQL_BIND rbind[3];
-  unsigned long h_length;
-  unsigned long v_length;
-  unsigned long long v_expire;
-  struct GNUNET_TIME_Absolute now;
-  struct GNUNET_TIME_Absolute expire;
-  unsigned int cnt;
-  unsigned long long total;
-  unsigned long long v_now;
-  unsigned int off;
-  unsigned int v_type;
-  int ret;
-  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
-
-  now = GNUNET_TIME_absolute_get ();
-  h_length = sizeof (struct GNUNET_HashCode);
-  v_length = sizeof (buffer);
-  total = -1;
-  memset (rbind, 0, sizeof (rbind));
-  rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
-  rbind[0].buffer = &total;
-  rbind[0].is_unsigned = GNUNET_YES;
-  v_type = type;
-  v_now = (unsigned long long) now.abs_value;
-  if ((GNUNET_OK !=
-       (ret =
-        GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, 
plugin->count_value, 1, rbind,
-                                       return_ok, NULL, MYSQL_TYPE_BLOB, key,
-                                       sizeof (struct GNUNET_HashCode), 
&h_length,
-                                       MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
-                                       MYSQL_TYPE_LONGLONG, &v_now, GNUNET_YES,
-                                       -1))) || (-1 == total))
-  {
-    if (ret == GNUNET_SYSERR)
-      itable (plugin);
-    return GNUNET_SYSERR;
-  }
-  if ((iter == NULL) || (total == 0))
-    return (int) total;
-
-  off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
-  cnt = 0;
-  while (cnt < total)
-  {
-    memset (rbind, 0, sizeof (rbind));
-    rbind[0].buffer_type = MYSQL_TYPE_BLOB;
-    rbind[0].buffer_length = sizeof (buffer);
-    rbind[0].length = &v_length;
-    rbind[0].buffer = buffer;
-    rbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
-    rbind[1].is_unsigned = 1;
-    rbind[1].buffer = &v_expire;
-    off = (off + 1) % total;
-    if (GNUNET_OK !=
-        (ret =
-         GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, 
plugin->select_value, 2, rbind,
-                                        return_ok, NULL, MYSQL_TYPE_BLOB, key,
-                                        sizeof (struct GNUNET_HashCode), 
&h_length,
-                                        MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
-                                        MYSQL_TYPE_LONGLONG, &v_now, 
GNUNET_YES,
-                                        MYSQL_TYPE_LONG, &off, GNUNET_YES, 
-1)))
-    {
-      if (ret == GNUNET_SYSERR)
-        itable (plugin);
-      return GNUNET_SYSERR;
-    }
-    cnt++;
-    expire.abs_value = v_expire;
-    if (GNUNET_OK != iter (iter_cls, expire, key, v_length, buffer, type))
-      break;
-  }
-  return cnt;
-}
-
-
-/**
- * Delete the entry with the lowest expiration value
- * from the datacache right now.
- *
- * @param cls closure (our "struct Plugin")
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-static int
-mysql_plugin_del (void *cls)
-{
-  struct Plugin *plugin = cls;
-
-  MYSQL_BIND rbind[5];
-  unsigned int v_type;
-  struct GNUNET_HashCode v_key;
-  struct GNUNET_HashCode vhash;
-  unsigned long k_length;
-  unsigned long h_length;
-  unsigned long v_length;
-  int ret;
-  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
-
-  k_length = sizeof (struct GNUNET_HashCode);
-  h_length = sizeof (struct GNUNET_HashCode);
-  v_length = sizeof (buffer);
-  memset (rbind, 0, sizeof (rbind));
-  rbind[0].buffer_type = MYSQL_TYPE_BLOB;
-  rbind[0].buffer_length = sizeof (struct GNUNET_HashCode);
-  rbind[0].length = &k_length;
-  rbind[0].buffer = &v_key;
-  rbind[1].buffer_type = MYSQL_TYPE_BLOB;
-  rbind[1].buffer_length = sizeof (struct GNUNET_HashCode);
-  rbind[1].length = &h_length;
-  rbind[1].buffer = &vhash;
-  rbind[2].buffer_type = MYSQL_TYPE_LONG;
-  rbind[2].is_unsigned = 1;
-  rbind[2].buffer = &v_type;
-  rbind[3].buffer_type = MYSQL_TYPE_BLOB;
-  rbind[3].buffer_length = sizeof (buffer);
-  rbind[3].length = &v_length;
-  rbind[3].buffer = buffer;
-  if ((GNUNET_OK !=
-       (ret =
-        GNUNET_MYSQL_statement_run_prepared_select (plugin->mc, 
plugin->select_old_value, 4,
-                                       rbind, return_ok, NULL, -1))) ||
-      (GNUNET_OK !=
-       (ret =
-        GNUNET_MYSQL_statement_run_prepared (plugin->mc, plugin->delete_value, 
NULL,
-                                MYSQL_TYPE_BLOB, &v_key,
-                                sizeof (struct GNUNET_HashCode), &k_length,
-                                MYSQL_TYPE_BLOB, &vhash,
-                                sizeof (struct GNUNET_HashCode), &h_length,
-                                MYSQL_TYPE_LONG, &v_type, GNUNET_YES,
-                                MYSQL_TYPE_BLOB, buffer,
-                                (unsigned long) sizeof (buffer), &v_length,
-                                -1))))
-  {
-    if (ret == GNUNET_SYSERR)
-      itable (plugin);
-    return GNUNET_SYSERR;
-  }
-  plugin->env->delete_notify (plugin->env->cls, &v_key, v_length + OVERHEAD);
-
-  return GNUNET_OK;
-}
-
-
-/**
- * Entry point for the plugin.
- *
- * @param cls closure (the "struct GNUNET_DATACACHE_PluginEnvironmnet")
- * @return the plugin's closure (our "struct Plugin")
- */
-void *
-libgnunet_plugin_datacache_mysql_init (void *cls)
-{
-  struct GNUNET_DATACACHE_PluginEnvironment *env = cls;
-  struct GNUNET_DATACACHE_PluginFunctions *api;
-  struct Plugin *plugin;
-
-  plugin = GNUNET_malloc (sizeof (struct Plugin));
-  plugin->env = env;
-  plugin->mc = GNUNET_MYSQL_context_create (env->cfg, "datacache-mysql");
-  if ( (NULL == plugin->mc) ||
-       (GNUNET_OK != itable (plugin)) )
-  {
-    if (NULL != plugin->mc)
-      GNUNET_MYSQL_context_destroy (plugin->mc);
-    GNUNET_free (plugin);
-    return NULL;
-  }
-  api = GNUNET_malloc (sizeof (struct GNUNET_DATACACHE_PluginFunctions));
-  api->cls = plugin;
-  api->get = &mysql_plugin_get;
-  api->put = &mysql_plugin_put;
-  api->del = &mysql_plugin_del;
-  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql",
-                   _("MySQL datacache running\n"));
-  return api;
-}
-
-
-/**
- * Exit point from the plugin.
- *
- * @param cls closure (our "struct Plugin")
- * @return NULL
- */
-void *
-libgnunet_plugin_datacache_mysql_done (void *cls)
-{
-  struct GNUNET_DATACACHE_PluginFunctions *api = cls;
-  struct Plugin *plugin = api->cls;
-
-  GNUNET_MYSQL_context_destroy (plugin->mc);
-  GNUNET_free (plugin);
-  GNUNET_free (api);
-  return NULL;
-}
-
-
-/* end of plugin_datacache_mysql.c */

Modified: gnunet/src/datacache/plugin_datacache_postgres.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_postgres.c    2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/plugin_datacache_postgres.c    2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -75,13 +75,18 @@
               "  type INTEGER NOT NULL DEFAULT 0,"
               "  discard_time BIGINT NOT NULL DEFAULT 0,"
               "  key BYTEA NOT NULL DEFAULT '',"
-              "  value BYTEA NOT NULL DEFAULT '')" "WITH OIDS");
-  if ((ret == NULL) || ((PQresultStatus (ret) != PGRES_COMMAND_OK) && (0 != 
strcmp ("42P07",    /* duplicate table */
-                                                                               
     PQresultErrorField
-                                                                               
     (ret,
-                                                                               
      PG_DIAG_SQLSTATE)))))
+              "  value BYTEA NOT NULL DEFAULT '',"
+              "  path BYTEA DEFAULT '')"
+             "WITH OIDS");
+  if ( (ret == NULL) || 
+       ((PQresultStatus (ret) != PGRES_COMMAND_OK) && 
+       (0 != strcmp ("42P07",    /* duplicate table */
+                     PQresultErrorField
+                     (ret,
+                      PG_DIAG_SQLSTATE)))))
   {
-    (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, 
"CREATE TABLE",
+    (void) GNUNET_POSTGRES_check_result (plugin->dbh, ret, 
+                                        PGRES_COMMAND_OK, "CREATE TABLE",
                                         "gn090dc");
     PQfinish (plugin->dbh);
     plugin->dbh = NULL;
@@ -123,11 +128,11 @@
   PQclear (ret);
   if ((GNUNET_OK !=
        GNUNET_POSTGRES_prepare (plugin->dbh, "getkt",
-                   "SELECT discard_time,type,value FROM gn090dc "
+                   "SELECT discard_time,type,value,path FROM gn090dc "
                    "WHERE key=$1 AND type=$2 ", 2)) ||
       (GNUNET_OK !=
        GNUNET_POSTGRES_prepare (plugin->dbh, "getk",
-                   "SELECT discard_time,type,value FROM gn090dc "
+                   "SELECT discard_time,type,value,path FROM gn090dc "
                    "WHERE key=$1", 1)) ||
       (GNUNET_OK !=
        GNUNET_POSTGRES_prepare (plugin->dbh, "getm",
@@ -137,8 +142,8 @@
        GNUNET_POSTGRES_prepare (plugin->dbh, "delrow", "DELETE FROM gn090dc 
WHERE oid=$1", 1)) ||
       (GNUNET_OK !=
        GNUNET_POSTGRES_prepare (plugin->dbh, "put",
-                   "INSERT INTO gn090dc (type, discard_time, key, value) "
-                   "VALUES ($1, $2, $3, $4)", 4)))
+                   "INSERT INTO gn090dc (type, discard_time, key, value, path) 
"
+                   "VALUES ($1, $2, $3, $4, $5)", 5)))
   {
     PQfinish (plugin->dbh);
     plugin->dbh = NULL;
@@ -157,12 +162,16 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
  */
-static size_t
+static ssize_t
 postgres_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)
+                     struct GNUNET_TIME_Absolute discard_time,
+                    unsigned int path_info_len,
+                    const struct GNUNET_PeerIdentity *path_info)
 {
   struct Plugin *plugin = cls;
   PGresult *ret;
@@ -173,22 +182,25 @@
     (const char *) &btype,
     (const char *) &bexpi,
     (const char *) key,
-    (const char *) data
+    (const char *) data,
+    (const char *) path_info
   };
   int paramLengths[] = {
     sizeof (btype),
     sizeof (bexpi),
     sizeof (struct GNUNET_HashCode),
-    size
+    size,
+    path_info_len * sizeof (struct GNUNET_PeerIdentity)
   };
-  const int paramFormats[] = { 1, 1, 1, 1 };
+  const int paramFormats[] = { 1, 1, 1, 1, 1 };
 
   ret =
-      PQexecPrepared (plugin->dbh, "put", 4, paramValues, paramLengths,
+      PQexecPrepared (plugin->dbh, "put", 5, paramValues, paramLengths,
                       paramFormats, 1);
   if (GNUNET_OK !=
-      GNUNET_POSTGRES_check_result (plugin->dbh, ret, PGRES_COMMAND_OK, 
"PQexecPrepared", "put"))
-    return GNUNET_SYSERR;
+      GNUNET_POSTGRES_check_result (plugin->dbh, ret, 
+                                   PGRES_COMMAND_OK, "PQexecPrepared", "put"))
+    return -1;
   PQclear (ret);
   return size + OVERHEAD;
 }
@@ -226,6 +238,8 @@
   uint32_t size;
   unsigned int cnt;
   unsigned int i;
+  unsigned int path_len;
+  const struct GNUNET_PeerIdentity *path;
   PGresult *res;
 
   res =
@@ -254,7 +268,7 @@
     PQclear (res);
     return cnt;
   }
-  if ((3 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) ||
+  if ((4 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) ||
       (sizeof (uint32_t) != PQfsize (res, 1)))
   {
     GNUNET_break (0);
@@ -267,12 +281,23 @@
         GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
     type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1));
     size = PQgetlength (res, i, 2);
+    path_len = PQgetlength (res, i, 3);
+    if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity)))
+    {
+      GNUNET_break (0);
+      path_len = 0;
+    }
+    path_len %= sizeof (struct GNUNET_PeerIdentity);
+    path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3);
     LOG (GNUNET_ERROR_TYPE_DEBUG, 
         "Found result of size %u bytes and type %u in database\n",
         (unsigned int) size, (unsigned int) type);
     if (GNUNET_SYSERR ==
-        iter (iter_cls, expiration_time, key, size, PQgetvalue (res, i, 2),
-              (enum GNUNET_BLOCK_Type) type))
+        iter (iter_cls, key, size, PQgetvalue (res, i, 2),
+              (enum GNUNET_BLOCK_Type) type,
+             expiration_time,
+             path_len,
+             path))
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG, 
           "Ending iteration (client error)\n");

Modified: gnunet/src/datacache/plugin_datacache_sqlite.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_sqlite.c      2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/plugin_datacache_sqlite.c      2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -95,12 +95,16 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+   * @return 0 if duplicate, -1 on error, number of bytes used otherwise
  */
-static size_t
-sqlite_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)
+static ssize_t
+sqlite_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)
 {
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt;
@@ -115,31 +119,38 @@
     dval = INT64_MAX;
   if (sq_prepare
       (plugin->dbh,
-       "INSERT INTO ds090 (type, expire, key, value) VALUES (?, ?, ?, ?)",
+       "INSERT INTO ds090 (type, expire, key, value, path) VALUES (?, ?, ?, ?, 
?)",
        &stmt) != SQLITE_OK)
   {
     LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sq_prepare");
-    return 0;
+    return -1;
   }
   if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
       (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, dval)) ||
       (SQLITE_OK !=
-       sqlite3_bind_blob (stmt, 3, key, sizeof (struct GNUNET_HashCode),
+       sqlite3_bind_blob (stmt, 3,
+                         key, sizeof (struct GNUNET_HashCode),
                           SQLITE_TRANSIENT)) ||
-      (SQLITE_OK != sqlite3_bind_blob (stmt, 4, data, size, SQLITE_TRANSIENT)))
+      (SQLITE_OK != sqlite3_bind_blob (stmt, 4,
+                                      data, size, 
+                                      SQLITE_TRANSIENT)) ||
+      (SQLITE_OK != sqlite3_bind_blob (stmt, 5, 
+                                      path_info, 
+                                      path_info_len * sizeof (struct 
GNUNET_PeerIdentity), 
+                                      SQLITE_TRANSIENT)))
   {
     LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_bind_xxx");
     sqlite3_finalize (stmt);
-    return 0;
+    return -1;
   }
   if (SQLITE_DONE != sqlite3_step (stmt))
   {
     LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_step");
     sqlite3_finalize (stmt);
-    return 0;
+    return -1;
   }
   if (SQLITE_OK != sqlite3_finalize (stmt))
     LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -173,8 +184,10 @@
   unsigned int cnt;
   unsigned int off;
   unsigned int total;
+  unsigned int psize;
   char scratch[256];
   int64_t ntime;
+  const struct GNUNET_PeerIdentity *path;
 
   now = GNUNET_TIME_absolute_get ();
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' for key `%4s'\n", "GET",
@@ -229,7 +242,7 @@
   {
     off = (off + 1) % total;
     GNUNET_snprintf (scratch, sizeof (scratch),
-                     "SELECT value,expire FROM ds090 WHERE key=? AND type=? 
AND expire >= ? LIMIT 1 OFFSET %u",
+                     "SELECT value,expire,path FROM ds090 WHERE key=? AND 
type=? AND expire >= ? LIMIT 1 OFFSET %u",
                      off);
     if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
     {
@@ -253,6 +266,17 @@
     size = sqlite3_column_bytes (stmt, 0);
     dat = sqlite3_column_blob (stmt, 0);
     exp.abs_value = sqlite3_column_int64 (stmt, 1);
+    psize = sqlite3_column_bytes (stmt, 2);
+    if (0 != psize % sizeof (struct GNUNET_PeerIdentity))
+    {
+      GNUNET_break (0);
+      psize = 0;
+    }
+    psize /= sizeof (struct GNUNET_PeerIdentity);
+    if (0 != psize)
+      path = sqlite3_column_blob (stmt, 2);
+    else
+      path = NULL;
     ntime = (int64_t) exp.abs_value;
     if (ntime == INT64_MAX)
       exp = GNUNET_TIME_UNIT_FOREVER_ABS;
@@ -260,7 +284,7 @@
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Found %u-byte result when processing `%s' for key `%4s'\n",
          (unsigned int) size, "GET", GNUNET_h2s (key));
-    if (GNUNET_OK != iter (iter_cls, exp, key, size, dat, type))
+    if (GNUNET_OK != iter (iter_cls, key, size, dat, type, exp, psize, path))
     {
       sqlite3_finalize (stmt);
       break;
@@ -408,7 +432,8 @@
                 "CREATE TABLE ds090 (" "  type INTEGER NOT NULL DEFAULT 0,"
                 "  expire INTEGER NOT NULL DEFAULT 0,"
                 "  key BLOB NOT NULL DEFAULT '',"
-                "  value BLOB NOT NULL DEFAULT '')");
+                "  value BLOB NOT NULL DEFAULT '',"
+               "  path BLOB DEFAULT '')");
   SQLITE3_EXEC (dbh, "CREATE INDEX idx_hashidx ON ds090 (key,type,expire)");
   SQLITE3_EXEC (dbh, "CREATE INDEX idx_expire ON ds090 (expire)");
   plugin = GNUNET_malloc (sizeof (struct Plugin));

Modified: gnunet/src/datacache/plugin_datacache_template.c
===================================================================
--- gnunet/src/datacache/plugin_datacache_template.c    2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/plugin_datacache_template.c    2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -49,15 +49,19 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return 0 on error, number of bytes used otherwise
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @return 0 if duplicate, -1 on error, number of bytes used otherwise
  */
-static size_t
+static ssize_t
 template_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)
+                     struct GNUNET_TIME_Absolute discard_time,
+                    unsigned int path_info_len,
+                    const struct GNUNET_PeerIdentity *path_info)
 {
   GNUNET_break (0);
-  return 0;
+  return -1;
 }
 
 

Modified: gnunet/src/datacache/test_datacache.c
===================================================================
--- gnunet/src/datacache/test_datacache.c       2012-11-13 18:54:54 UTC (rev 
24937)
+++ gnunet/src/datacache/test_datacache.c       2012-11-13 20:05:40 UTC (rev 
24938)
@@ -38,9 +38,13 @@
 
 
 static int
-checkIt (void *cls, struct GNUNET_TIME_Absolute exp,
-         const struct GNUNET_HashCode * key, size_t size, const char *data,
-         enum GNUNET_BLOCK_Type type)
+checkIt (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_len,
+        const struct GNUNET_PeerIdentity *path)
 {
   if (size != sizeof (struct GNUNET_HashCode))
   {
@@ -83,7 +87,8 @@
     GNUNET_CRYPTO_hash (&k, sizeof (struct GNUNET_HashCode), &n);
     ASSERT (GNUNET_OK ==
             GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
-                                  (const char *) &n, 1 + i % 16, exp));
+                                  (const char *) &n, 1 + i % 16, exp, 
+                                 0, NULL));
     k = n;
   }
   memset (&k, 0, sizeof (struct GNUNET_HashCode));
@@ -99,7 +104,8 @@
   ASSERT (GNUNET_OK ==
           GNUNET_DATACACHE_put (h, &k, sizeof (struct GNUNET_HashCode),
                                 (const char *) &n, 792,
-                                GNUNET_TIME_UNIT_FOREVER_ABS));
+                                GNUNET_TIME_UNIT_FOREVER_ABS,
+                               0, NULL));
   ASSERT (0 != GNUNET_DATACACHE_get (h, &k, 792, &checkIt, &n));
 
   GNUNET_DATACACHE_destroy (h);

Copied: gnunet/src/datacache/test_datacache_data_heap.conf (from rev 24933, 
gnunet/src/datacache/test_datacache_data_mysql.conf)
===================================================================
--- gnunet/src/datacache/test_datacache_data_heap.conf                          
(rev 0)
+++ gnunet/src/datacache/test_datacache_data_heap.conf  2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -0,0 +1,4 @@
+[testcache]
+QUOTA = 1 MB
+DATABASE = heap
+

Deleted: gnunet/src/datacache/test_datacache_data_mysql.conf
===================================================================
--- gnunet/src/datacache/test_datacache_data_mysql.conf 2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/datacache/test_datacache_data_mysql.conf 2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -1,13 +0,0 @@
-[testcache]
-QUOTA = 1 MB
-DATABASE = mysql
-
-[datacache-mysql]
-DATABASE = gnunetcheck
-# CONFIG = ~/.my.cnf
-# USER =
-# PASSWORD =
-# HOST = 
-# PORT = 
-
-

Modified: gnunet/src/datacache/test_datacache_quota.c
===================================================================
--- gnunet/src/datacache/test_datacache_quota.c 2012-11-13 18:54:54 UTC (rev 
24937)
+++ gnunet/src/datacache/test_datacache_quota.c 2012-11-13 20:05:40 UTC (rev 
24938)
@@ -73,7 +73,7 @@
     {
       exp.abs_value++;
       buf[j] = i;
-      ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, j, buf, 1 + i, exp));
+      ASSERT (GNUNET_OK == GNUNET_DATACACHE_put (h, &k, j, buf, 1 + i, exp, 0, 
NULL));
       ASSERT (0 < GNUNET_DATACACHE_get (h, &k, 1 + i, NULL, NULL));
     }
     k = n;

Modified: gnunet/src/dht/gnunet-service-dht_datacache.c
===================================================================
--- gnunet/src/dht/gnunet-service-dht_datacache.c       2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/dht/gnunet-service-dht_datacache.c       2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -39,28 +39,6 @@
 
 
 /**
- * Entry for inserting data into datacache from the DHT.
- */
-struct DHTPutEntry
-{
-  /**
-   * Size of data.
-   */
-  uint16_t data_size;
-
-  /**
-   * Length of recorded path.
-   */
-  uint16_t path_length;
-
-  /* PATH ENTRIES */
-
-  /* PUT DATA */
-
-};
-
-
-/**
  * Handle a datum we've received from another peer.  Cache if
  * possible.
  *
@@ -80,14 +58,7 @@
                           enum GNUNET_BLOCK_Type type, size_t data_size,
                           const void *data)
 {
-  size_t plen =
-      data_size + put_path_length * sizeof (struct GNUNET_PeerIdentity) +
-      sizeof (struct DHTPutEntry);
-  char buf[plen];
-  struct DHTPutEntry *pe;
-  struct GNUNET_PeerIdentity *pp;
-
-  if (datacache == NULL)
+  if (NULL == datacache)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 _("%s request received, but have no datacache!\n"), "PUT");
@@ -102,14 +73,9 @@
   GNUNET_STATISTICS_update (GDS_stats,
                             gettext_noop ("# ITEMS stored in datacache"), 1,
                             GNUNET_NO);
-  pe = (struct DHTPutEntry *) buf;
-  pe->data_size = htons (data_size);
-  pe->path_length = htons ((uint16_t) put_path_length);
-  pp = (struct GNUNET_PeerIdentity *) &pe[1];
-  memcpy (pp, put_path, put_path_length * sizeof (struct GNUNET_PeerIdentity));
-  memcpy (&pp[put_path_length], data, data_size);
-  (void) GNUNET_DATACACHE_put (datacache, key, plen, (const char *) pe, type,
-                               expiration);
+  (void) GNUNET_DATACACHE_put (datacache, key, 
+                              data_size, data, type,
+                               expiration, put_path_length, put_path);
 }
 
 
@@ -159,40 +125,26 @@
  * @param size the size of the data identified by key
  * @param data the actual data
  * @param type the type of the data
- *
+ * @param put_path_length number of peers in 'put_path'
+ * @param put_path path the reply took on put
  * @return GNUNET_OK to continue iteration, anything else
  * to stop iteration.
  */
 static int
-datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
+datacache_get_iterator (void *cls, 
                         const struct GNUNET_HashCode * key, size_t size,
-                        const char *data, enum GNUNET_BLOCK_Type type)
+                        const char *data, enum GNUNET_BLOCK_Type type,
+                       struct GNUNET_TIME_Absolute exp,
+                       unsigned int put_path_length,
+                       const struct GNUNET_PeerIdentity *put_path)
 {
   struct GetRequestContext *ctx = cls;
-  const struct DHTPutEntry *pe;
-  const struct GNUNET_PeerIdentity *pp;
-  const char *rdata;
-  size_t rdata_size;
-  uint16_t put_path_length;
   enum GNUNET_BLOCK_EvaluationResult eval;
 
-  pe = (const struct DHTPutEntry *) data;
-  put_path_length = ntohs (pe->path_length);
-  rdata_size = ntohs (pe->data_size);
-
-  if (size !=
-      sizeof (struct DHTPutEntry) + rdata_size +
-      (put_path_length * sizeof (struct GNUNET_PeerIdentity)))
-  {
-    GNUNET_break (0);
-    return GNUNET_OK;
-  }
-  pp = (const struct GNUNET_PeerIdentity *) &pe[1];
-  rdata = (const char *) &pp[put_path_length];
   eval =
       GNUNET_BLOCK_evaluate (GDS_block_context, type, key, ctx->reply_bf,
                              ctx->reply_bf_mutator, ctx->xquery,
-                             ctx->xquery_size, rdata, rdata_size);
+                             ctx->xquery_size, data, size);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Found reply for query %s in datacache, evaluation result is 
%d\n",
               GNUNET_h2s (key), (int) eval);
@@ -206,11 +158,11 @@
                               gettext_noop
                               ("# Good RESULTS found in datacache"), 1,
                               GNUNET_NO);
-    GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, pp, type,
-                              rdata_size, rdata);
+    GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, put_path, 
type,
+                              size, data);
     /* forward to other peers */
-    GDS_ROUTING_process (type, exp, key, put_path_length, pp, 0, NULL, rdata,
-                         rdata_size);
+    GDS_ROUTING_process (type, exp, key, put_path_length, put_path, 0, NULL, 
data,
+                         size);
     break;
   case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
     GNUNET_STATISTICS_update (GDS_stats,

Modified: gnunet/src/include/gnunet_datacache_lib.h
===================================================================
--- gnunet/src/include/gnunet_datacache_lib.h   2012-11-13 18:54:54 UTC (rev 
24937)
+++ gnunet/src/include/gnunet_datacache_lib.h   2012-11-13 20:05:40 UTC (rev 
24938)
@@ -74,18 +74,22 @@
  * An iterator over a set of items stored in the datacache.
  *
  * @param cls closure
- * @param exp when will the content expire?
  * @param key key for the content
  * @param size number of bytes in 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 a path through the network
  * @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,
-                                          const struct GNUNET_HashCode * key,
-                                          size_t size, const char *data,
-                                          enum GNUNET_BLOCK_Type type);
+                                         unsigned int path_info_len,
+                                         const struct GNUNET_PeerIdentity 
*path_info);
 
 
 /**
@@ -97,13 +101,17 @@
  * @param data data to store
  * @param type type of the value
  * @param discard_time when to discard the value in any case
- * @return GNUNET_OK on success, GNUNET_SYSERR on error (full, etc.)
+ * @param path_info_len number of entries in 'path_info'
+ * @param path_info a path through the network
+ * @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,
-                      struct GNUNET_TIME_Absolute discard_time);
+                      struct GNUNET_TIME_Absolute discard_time,
+                     unsigned int path_info_len,
+                     const struct GNUNET_PeerIdentity *path_info);
 
 
 /**

Modified: gnunet/src/include/gnunet_datacache_plugin.h
===================================================================
--- gnunet/src/include/gnunet_datacache_plugin.h        2012-11-13 18:54:54 UTC 
(rev 24937)
+++ gnunet/src/include/gnunet_datacache_plugin.h        2012-11-13 20:05:40 UTC 
(rev 24938)
@@ -107,11 +107,15 @@
    * @param data data to store
    * @param type type of the value
    * @param discard_time when to discard the value in any case
-   * @return 0 on error, number of bytes used otherwise
+   * @param path_info_len number of entries in 'path_info'
+   * @param path_info a path through the network
+   * @return 0 if duplicate, -1 on error, number of bytes used otherwise
    */
-       size_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);
+  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);
 
 
   /**




reply via email to

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