gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r5328 - in GNUnet/src: applications applications/datastore


From: gnunet
Subject: [GNUnet-SVN] r5328 - in GNUnet/src: applications applications/datastore applications/fs/module applications/sqstore_mysql applications/sqstore_sqlite include
Date: Sat, 21 Jul 2007 19:56:18 -0600 (MDT)

Author: grothoff
Date: 2007-07-21 19:56:14 -0600 (Sat, 21 Jul 2007)
New Revision: 5328

Removed:
   GNUnet/src/applications/sqstore_mysql_embedded/
Modified:
   GNUnet/src/applications/Makefile.am
   GNUnet/src/applications/datastore/datastore.c
   GNUnet/src/applications/fs/module/dht_push.c
   GNUnet/src/applications/sqstore_mysql/mysql.c
   GNUnet/src/applications/sqstore_mysql/mysqltest.c
   GNUnet/src/applications/sqstore_mysql/mysqltest2.c
   GNUnet/src/applications/sqstore_mysql/mysqltest3.c
   GNUnet/src/applications/sqstore_sqlite/sqlite.c
   GNUnet/src/include/gnunet_datastore_service.h
   GNUnet/src/include/gnunet_sqstore_service.h
Log:
starting new DB approach -- does not yet compile

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2007-07-21 07:21:17 UTC (rev 5327)
+++ GNUnet/src/applications/Makefile.am 2007-07-22 01:56:14 UTC (rev 5328)
@@ -1,7 +1,3 @@
-if HAVE_MYSQLE
- MYSQLE_DIR = sqstore_mysql_embedded
-endif
-
 if HAVE_MYSQL
  MYSQL_DIR = sqstore_mysql
 endif
@@ -33,7 +29,6 @@
  pingpong \
  session \
  $(MYSQL_DIR) \
- $(MYSQLE_DIR) \
  $(SQLITE_DIR) \
  tbench \
  template \

Modified: GNUnet/src/applications/datastore/datastore.c
===================================================================
--- GNUnet/src/applications/datastore/datastore.c       2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/datastore/datastore.c       2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -201,14 +201,16 @@
 
 typedef struct
 {
-  int exists;
+  int exists; 
   const Datastore_Value *value;
-  Datastore_Value *existing;
+  unsigned long long uid;
+  unsigned long long expiration;
 } CE;
 
 static int
 checkExists (const HashCode512 * key,
-             const Datastore_Value * value, void *cls)
+             const Datastore_Value * value, void *cls,
+            unsigned long long uid)
 {
   CE *ce = cls;
 
@@ -217,8 +219,8 @@
                     &ce->value[1],
                     ntohl (value->size) - sizeof (Datastore_Value))))
     return OK;                  /* found another value, but different content! 
*/
-  ce->existing = MALLOC (ntohl (value->size));
-  memcpy (ce->existing, value, ntohl (value->size));
+  ce->uid = uid;
+  ce->expiration = ntohll(value->expirationTime);
   ce->exists = YES;
   return SYSERR;                /* abort iteration! */
 }
@@ -251,16 +253,13 @@
     {
       if ((ntohl (value->prio) == 0) &&
           (ntohll (value->expirationTime) <=
-           ntohll (cls.existing->expirationTime)))
+           cls.expiration)))
         {
-          FREE (cls.existing);
           return OK;
         }
       /* update prio */
-      sq->update (key,
-                  cls.existing,
+      sq->update (cls.uid,
                   ntohl (value->prio), ntohll (value->expirationTime));
-      FREE (cls.existing);
       return OK;
     }
 #if DEBUG_DATASTORE

Modified: GNUnet/src/applications/fs/module/dht_push.c
===================================================================
--- GNUnet/src/applications/fs/module/dht_push.c        2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/fs/module/dht_push.c        2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -109,7 +109,7 @@
     {
       if (total == 0)
         total = 1;
-      total = sqstore->iterateNonAnonymous (0, YES, &push_callback, NULL);
+      total = sqstore->iterateNonAnonymous (0, &push_callback, NULL);
       if ((dht != NULL) && (total == 0))
         PTHREAD_SLEEP (15 * cronMINUTES);
     }

Modified: GNUnet/src/applications/sqstore_mysql/mysql.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysql.c       2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysql.c       2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -103,13 +103,10 @@
  * - If you get odd SEGVs on gnunetd startup, it might be that the mysql
  *   databases have been corrupted.
  * - The tables can be verified/fixed in two ways;
- *   1) by shutting down mysqld (mandatory!) and running
- *   # myisamchk -r *.MYI
- *   in /var/lib/mysql/gnunet/ (or wherever the tables are stored).
- *   Another repair command is "mysqlcheck". The usable command
- *   may depend on your mysql build/version. Or,
- *   2) by executing
- *   mysql> REPAIR TABLE gn070;
+ *   1) by running mysqlcheck -A, or
+ *   2) by executing (inside of mysql using the GNUnet database):
+ *   mysql> REPAIR TABLE gn071;
+ *   mysql> REPAIR TABLE gn071;
  *
  * PROBLEMS?
  *
@@ -129,8 +126,11 @@
 #include <mysql/mysql.h>
 
 #define DEBUG_MYSQL NO
+
 #define DEBUG_TIME_MYSQL NO
 
+#define MAX_DATUM_SIZE 65536
+
 /**
  * Die with an error message that indicates
  * a failure of the command 'cmd' with the message given
@@ -172,375 +172,580 @@
 
   char *cnffile;
 
-  int prepare;
-
   int valid;
 
-  MYSQL_STMT *insert;
+  /* stuff dealing with gn072 table */
+#define SELECT_VALUE "SELECT value FROM gn072 WHERE vkey=?"
+  MYSQL_STMT * select_value;
 
-  MYSQL_BIND bind[7];
+#define DELETE_VALUE "DELETE FROM gn072 WHERE vkey=?"
+  MYSQL_STMT * delete_value;
 
-  MYSQL_STMT *select;
+#define INSERT_VALUE "INSERT INTO gn072 (value) VALUES (?)"
+  MYSQL_STMT * insert_value;
 
-  MYSQL_STMT *selectc;
+  /* stuff dealing with gn071 table */
+#define INSERT_ENTRY "INSERT INTO gn071 
(size,type,prio,anonLevel,expire,hash,vkey) VALUES (?,?,?,?,?,?,?)"
+  MYSQL_STMT * insert_entry;
 
-  MYSQL_STMT *selects;
+#define DELETE_ENTRY_BY_VKEY "DELETE FROM gn071 WHERE vkey=?"
+  MYSQL_STMT * delete_entry_by_vkey;
 
-  MYSQL_STMT *selectsc;
+#define SELECT_ENTRY_BY_HASH "SELECT * FROM gn071 WHERE hash=? ORDER BY expire 
DESC"
+  MYSQL_STMT * select_entry_by_hash;
 
-  MYSQL_BIND sbind[2];
+#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT * FROM gn071 WHERE hash=? AND 
type=?"
+  MYSQL_STMT * select_entry_by_hash_and_type;
 
-  MYSQL_STMT *deleteh;
+#define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn071 WHERE hash=?"
+  MYSQL_STMT * count_entry_by_hash;
 
-  MYSQL_STMT *deleteg;
+#define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn071 WHERE hash=? 
AND type=?"
+  MYSQL_STMT * count_entry_by_hash_and_type;
 
-  MYSQL_BIND dbind[7];
+#define UPDATE_ENTRY "UPDATE gn071 SET 
prio=prio+?,expire=IF(expire>=?,expire,?) WHERE hash=? AND vkey=?"
+  MYSQL_STMT * update_entry;
 
-  MYSQL_STMT *update;
 
-  MYSQL_BIND ubind[5];
 
-} mysqlHandle;
+#define SELECT_IT_LOW_PRIORITY "SELECT * FROM gn071 WHERE ( (prio = ? AND vkey 
> ?) OR (prio > ?) )"\
+                               "ORDER BY prio ASC,vkey ASC LIMIT 1"
+  MYSQL_STMT * ilow;
 
-#define SELECT_SIZE "SELECT sum(size) FROM gn070"
+#define SELECT_IT_NON_ANONYMOUS "SELECT * FROM gn071 WHERE ( (prio = ? AND 
vkey > ?) OR (prio > ?) ) "\
+                                "AND anonLevel=0 AND type != 0xFFFFFFFF "\
+                                "ORDER BY prio DESC,vkey DESC LIMIT 1"
+  MYSQL_STMT * inon;
 
-#define INSERT_SAMPLE "INSERT INTO gn070 
(size,type,prio,anonLevel,expire,hash,value) VALUES (?,?,?,?,?,?,?)"
+#define SELECT_IT_EXPIRATION_TIME "SELECT * FROM gn071 WHERE ( (expire = ? AND 
vkey > ?) OR (expire > ?) ) "\
+                                  "ORDER BY expire ASC,vkey ASC LIMIT 1"
+  MYSQL_STMT * iexp;
 
-#define SELECT_SAMPLE "SELECT * FROM gn070 WHERE hash=? ORDER BY expire DESC"
+#define SELECT_IT_MIGRATION_ORDER "SELECT * FROM gn071 WHERE ( (expire = ? AND 
vkey < ?) OR (expire > ?) ) "\
+                                  "AND expire > ? AND type!=3 "\
+                                  "ORDER BY expire DESC,vkey DESC LIMIT 1"
+  MYSQL_STMT * imig;
 
-#define SELECT_SAMPLE_COUNT "SELECT count(*) FROM gn070 WHERE hash=?"
+#define SELECT_ALL "SELECT * FROM gn071"
+  MYSQL_STMT * iall;
 
-#define SELECT_TYPE_SAMPLE "SELECT * FROM gn070 WHERE hash=? AND type=?"
+} mysqlHandle;
 
-#define SELECT_TYPE_SAMPLE_COUNT "SELECT count(*) FROM gn070 WHERE hash=? AND 
type=?"
 
-/**
- * Select to prepare for key-based deletion.
- */
-#define SELECT_HASH_SAMPLE "SELECT * FROM gn070 WHERE hash=? ORDER BY prio ASC 
LIMIT 1"
+#define SELECT_SIZE "SELECT sum(size) FROM gn070"
 
-#define DELETE_GENERIC_SAMPLE "DELETE FROM gn070 WHERE hash=? AND size=? AND 
type=? AND prio=? AND anonLevel=? AND expire=? AND value=? ORDER BY prio ASC 
LIMIT 1"
+static mysqlHandle * dbh;
 
-#define UPDATE_SAMPLE "UPDATE gn070 SET 
prio=prio+?,expire=IF(expire>=?,expire,?) WHERE hash=? AND value=?"
-
-static mysqlHandle *dbh;
-
-
 /**
- * Given a full (SELECT *) sql_row from gn070 table in database
- * order, assemble it into a Datastore_Datum representation.
- *
+ * Close the database connection.
  */
-static Datastore_Datum *
-assembleDatum (MYSQL_RES * res, MYSQL_ROW sql_row, mysqlHandle * dbhI)
+static int
+iclose ()
 {
-  Datastore_Datum *datum;
-  int contentSize;
-  unsigned long *lens;
-  unsigned int type;
-  unsigned int prio;
-  unsigned int level;
-  unsigned long long exp;
-
-  contentSize = atol (sql_row[0]) - sizeof (Datastore_Value);
-  if (contentSize < 0)
-    return NULL;                /* error */
-
-  lens = mysql_fetch_lengths (res);
-  if ((lens[5] != sizeof (HashCode512)) ||
-      (lens[6] != contentSize) ||
-      (sscanf (sql_row[1], "%u", &type) != 1) ||
-      (sscanf (sql_row[2], "%u", &prio) != 1) ||
-      (sscanf (sql_row[3], "%u", &level) != 1) ||
-      (SSCANF (sql_row[4], "%llu", &exp) != 1))
-    {
-      mysql_free_result (res);
-      if ((lens[5] != sizeof (HashCode512)) || (lens[6] != contentSize))
-        {
-          char scratch[512];
-
-          GE_LOG (ectx,
-                  GE_WARNING | GE_BULK | GE_USER,
-                  _("Invalid data in %s.  Trying to fix (by deletion).\n"),
-                  _("mysql datastore"));
-          SNPRINTF (scratch,
-                    512,
-                    "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND 
(size=%u + LENGTH(value)))",
-                    sizeof (HashCode512), sizeof (Datastore_Value));
-          if (0 != mysql_query (dbhI->dbf, scratch))
-            LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
-        }
-      else
-        {
-          GE_BREAK (ectx, 0);   /* should really never happen */
-        }
-      return NULL;
-    }
-  datum = MALLOC (sizeof (Datastore_Datum) + contentSize);
-  datum->value.size = htonl (contentSize + sizeof (Datastore_Value));
-  datum->value.type = htonl (type);
-  datum->value.prio = htonl (prio);
-  datum->value.anonymityLevel = htonl (level);
-  datum->value.expirationTime = htonll (exp);
-  memcpy (&datum->key, sql_row[5], sizeof (HashCode512));
-  memcpy (&datum[1], sql_row[6], contentSize);
-  return datum;
+#define PEND(h) if (h != NULL) { mysql_stmt_close(h); h = NULL; } else {}
+  if (dbh->dbf == NULL)
+    return SYSERR;
+  PEND(dbh->select_value);
+  PEND(dbh->delete_value);
+  PEND(dbh->insert_value);
+  PEND(dbh->insert_entry);
+  PEND(dbh->delete_entry_by_vkey);
+  PEND(dbh->select_entry_by_hash);
+  PEND(dbh->select_entry_by_hash_and_type);
+  PEND(dbh->count_entry_by_hash);
+  PEND(dbh->count_entry_by_hash_and_type);
+  PEND(dbh->update_entry);
+  PEND(dbh->ilow);
+  PEND(dbh->inon);
+  PEND(dbh->iexp);
+  PEND(dbh->imig);
+  PEND(dbh->iall);  
+  mysql_close (dbh->dbf);
+  dbh->dbf = NULL;
+  dbh->valid = NO;
+  return OK;
 }
 
 /**
- * Initiate the database connection.
- * Uses dbhI->cnffile for the configuration,
- * so that must be set already.
+ * Initiate the database connection.  Uses dbh->cnffile for the
+ * configuration, so that must be set already.
  *
- * @param prepare is this the main connection
- *        (if YES, we create tables and initialize
- *         prepared statements; if NO, we
- *         use longer timeouts (for iteration)
- *         and do not setup prepared statements)
  * @return OK on success
  */
 static int
-iopen (mysqlHandle * dbhI, int prepare)
+iopen ()
 {
   char *dbname;
   my_bool reconnect = 0;
   unsigned int timeout = 60;    /* in seconds */
-  cron_t start;
 
-  if (dbhI->cnffile == NULL)
+  if (dbh->cnffile == NULL)
     return SYSERR;
-  dbhI->dbf = mysql_init (NULL);
-  if (dbhI->dbf == NULL)
+  dbh->dbf = mysql_init (NULL);
+  if (dbh->dbf == NULL)
     return SYSERR;
-  mysql_options (dbhI->dbf, MYSQL_READ_DEFAULT_FILE, dbh->cnffile);
-  mysql_options (dbhI->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
-  mysql_options (dbhI->dbf, MYSQL_OPT_RECONNECT, &reconnect);
-  mysql_options (dbhI->dbf,
+  mysql_options (dbh->dbf, MYSQL_READ_DEFAULT_FILE, dbh->cnffile);
+  mysql_options (dbh->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
+  mysql_options (dbh->dbf, MYSQL_OPT_RECONNECT, &reconnect);
+  mysql_options (dbh->dbf,
                  MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
-  if (!prepare)
-    timeout = 28800;
-  mysql_options (dbhI->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
-  mysql_options (dbhI->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
+  mysql_options (dbh->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
+  mysql_options (dbh->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
 
   dbname = NULL;
   GC_get_configuration_value_string (coreAPI->cfg,
                                      "MYSQL", "DATABASE", "gnunet", &dbname);
   GE_ASSERT (ectx, dbname != NULL);
-  mysql_real_connect (dbhI->dbf, NULL, NULL, NULL, dbname, 0, NULL, 0);
+  mysql_real_connect (dbh->dbf, NULL, NULL, NULL, dbname, 0, NULL, 0);
   FREE (dbname);
-  if (mysql_error (dbhI->dbf)[0])
+  if (mysql_error (dbh->dbf)[0])
     {
-      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_real_connect", dbhI);
-      dbhI->dbf = NULL;
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_real_connect", dbh);
+      iclose();
       return SYSERR;
     }
-  if (prepare)
+  mysql_query (dbh->dbf,
+              "SET SESSION net_read_timeout=60, SESSION net_write_timeout=60");
+  if (mysql_error (dbh->dbf)[0])
     {
-      dbhI->prepare = YES;
-      mysql_query (dbhI->dbf,
-                   "SET SESSION net_read_timeout=60, SESSION 
net_write_timeout=60");
-      if (mysql_error (dbhI->dbf)[0])
-        {
-          LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
-      mysql_query (dbhI->dbf,
-                   "CREATE TABLE IF NOT EXISTS gn070 ("
-                   " size INT(11) UNSIGNED NOT NULL DEFAULT 0,"
-                   " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
-                   " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
-                   " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
-                   " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
-                   " hash TINYBLOB NOT NULL DEFAULT '',"
-                   " value BLOB NOT NULL DEFAULT '',"
-                   " INDEX (hash(64)),"
-                   " INDEX (prio),"
-                   " INDEX (expire),"
-                   " INDEX (expire,anonLevel,type)" ") TYPE=InnoDB");
-      if (mysql_error (dbhI->dbf)[0])
-        {
-          LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
-      mysql_query (dbhI->dbf, "SET AUTOCOMMIT = 1");
-      if (mysql_error (dbhI->dbf)[0])
-        {
-          LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
-      dbhI->insert = mysql_stmt_init (dbhI->dbf);
-      dbhI->select = mysql_stmt_init (dbhI->dbf);
-      dbhI->selectc = mysql_stmt_init (dbhI->dbf);
-      dbhI->selects = mysql_stmt_init (dbhI->dbf);
-      dbhI->selectsc = mysql_stmt_init (dbhI->dbf);
-      dbhI->update = mysql_stmt_init (dbhI->dbf);
-      dbhI->deleteh = mysql_stmt_init (dbhI->dbf);
-      dbhI->deleteg = mysql_stmt_init (dbhI->dbf);
-      if ((dbhI->insert == NULL) ||
-          (dbhI->update == NULL) ||
-          (dbhI->select == NULL) ||
-          (dbhI->selectc == NULL) ||
-          (dbhI->selects == NULL) ||
-          (dbhI->selectsc == NULL) ||
-          (dbhI->deleteh == NULL) || (dbhI->deleteg == NULL))
-        {
-          GE_BREAK (ectx, 0);
-          if (dbhI->insert != NULL)
-            mysql_stmt_close (dbhI->insert);
-          if (dbhI->update != NULL)
-            mysql_stmt_close (dbhI->update);
-          if (dbhI->select != NULL)
-            mysql_stmt_close (dbhI->select);
-          if (dbhI->selectc != NULL)
-            mysql_stmt_close (dbhI->selectc);
-          if (dbhI->selects != NULL)
-            mysql_stmt_close (dbhI->selects);
-          if (dbhI->selectsc != NULL)
-            mysql_stmt_close (dbhI->selectsc);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
-      start = get_time ();
-      if (mysql_stmt_prepare (dbhI->insert,
-                              INSERT_SAMPLE,
-                              strlen (INSERT_SAMPLE)) ||
-          mysql_stmt_prepare (dbhI->select,
-                              SELECT_SAMPLE,
-                              strlen (SELECT_SAMPLE)) ||
-          mysql_stmt_prepare (dbhI->selectc,
-                              SELECT_SAMPLE_COUNT,
-                              strlen (SELECT_SAMPLE_COUNT)) ||
-          mysql_stmt_prepare (dbhI->selects,
-                              SELECT_TYPE_SAMPLE,
-                              strlen (SELECT_TYPE_SAMPLE)) ||
-          mysql_stmt_prepare (dbhI->selectsc,
-                              SELECT_TYPE_SAMPLE_COUNT,
-                              strlen (SELECT_TYPE_SAMPLE_COUNT)) ||
-          mysql_stmt_prepare (dbhI->update,
-                              UPDATE_SAMPLE,
-                              strlen (UPDATE_SAMPLE)) ||
-          mysql_stmt_prepare (dbhI->deleteh,
-                              SELECT_HASH_SAMPLE,
-                              strlen (SELECT_HASH_SAMPLE)) ||
-          mysql_stmt_prepare (dbhI->deleteg,
-                              DELETE_GENERIC_SAMPLE,
-                              strlen (DELETE_GENERIC_SAMPLE)))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _
-                  ("`%s' failed at %s:%d with error: I/%s S/%s SC/%s SS/%s 
SSC/%s U/%s D/%s DG/%s after %llums\n"),
-                  "mysql_stmt_prepare", __FILE__, __LINE__,
-                  mysql_stmt_error (dbhI->insert),
-                  mysql_stmt_error (dbhI->select),
-                  mysql_stmt_error (dbhI->selectc),
-                  mysql_stmt_error (dbhI->selects),
-                  mysql_stmt_error (dbhI->selectsc),
-                  mysql_stmt_error (dbhI->update),
-                  mysql_stmt_error (dbhI->deleteh),
-                  mysql_stmt_error (dbhI->deleteg), get_time () - start);
-          mysql_stmt_close (dbhI->insert);
-          mysql_stmt_close (dbhI->select);
-          mysql_stmt_close (dbhI->selectc);
-          mysql_stmt_close (dbhI->selects);
-          mysql_stmt_close (dbhI->selectsc);
-          mysql_stmt_close (dbhI->update);
-          mysql_stmt_close (dbhI->deleteh);
-          mysql_stmt_close (dbhI->deleteg);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
-      memset (dbhI->bind, 0, sizeof (dbhI->bind));
-      dbhI->bind[0].buffer_type = MYSQL_TYPE_LONG;      /* size */
-      dbhI->bind[1].buffer_type = MYSQL_TYPE_LONG;      /* type */
-      dbhI->bind[2].buffer_type = MYSQL_TYPE_LONG;      /* prio */
-      dbhI->bind[3].buffer_type = MYSQL_TYPE_LONG;      /* anon level */
-      dbhI->bind[4].buffer_type = MYSQL_TYPE_LONGLONG;  /* expiration */
-      dbhI->bind[5].buffer_type = MYSQL_TYPE_TINY_BLOB; /* hash */
-      dbhI->bind[6].buffer_type = MYSQL_TYPE_BLOB;      /* value */
-      memset (dbhI->sbind, 0, sizeof (dbhI->sbind));
-      dbhI->sbind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;        /* hash */
-      dbhI->sbind[1].buffer_type = MYSQL_TYPE_LONG;     /* type */
-      memset (dbhI->dbind, 0, sizeof (dbhI->dbind));
-      dbhI->dbind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;        /* hash */
-      dbhI->dbind[1].buffer_type = MYSQL_TYPE_LONG;     /* size */
-      dbhI->dbind[2].buffer_type = MYSQL_TYPE_LONG;     /* type */
-      dbhI->dbind[3].buffer_type = MYSQL_TYPE_LONG;     /* prio */
-      dbhI->dbind[4].buffer_type = MYSQL_TYPE_LONG;     /* anon level */
-      dbhI->dbind[5].buffer_type = MYSQL_TYPE_LONGLONG; /* expiration */
-      dbhI->dbind[6].buffer_type = MYSQL_TYPE_BLOB;     /* value */
-      memset (dbhI->ubind, 0, sizeof (dbhI->ubind));
-      dbhI->ubind[0].buffer_type = MYSQL_TYPE_LONG;
-      dbhI->ubind[1].buffer_type = MYSQL_TYPE_LONG;
-      dbhI->ubind[2].buffer_type = MYSQL_TYPE_LONG;
-      dbhI->ubind[3].buffer_type = MYSQL_TYPE_BLOB;
-      dbhI->ubind[4].buffer_type = MYSQL_TYPE_BLOB;
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+      iclose();
+      return SYSERR;
     }
+  mysql_query (dbh->dbf,
+              "CREATE TABLE IF NOT EXISTS gn071 ("
+              " size INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+              " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+              " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+              " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+              " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
+              " hash BINARY(64) NOT NULL DEFAULT '',"
+              " vkey BIGINT UNSIGNED NOT NULL DEFAULT 0,"
+              " INDEX (hash(64)),"
+              " INDEX (prio),"
+              " INDEX (expire,anonLevel,type)" ") ENGINE=MyISAM");
+  if (mysql_error (dbh->dbf)[0])
+    {
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+      iclose();
+      return SYSERR;
+    }
+  mysql_query (dbh->dbf,
+              "CREATE TABLE IF NOT EXISTS gn072 ("
+              " vkey BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
+              " value BLOB NOT NULL DEFAULT '') ENGINE=MyISAM");
+  if (mysql_error (dbh->dbf)[0])
+    {
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+      iclose();
+      return SYSERR;
+    }
+  mysql_query (dbh->dbf, "SET AUTOCOMMIT = 1");
+  if (mysql_error (dbh->dbf)[0])
+    {
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+      iclose();
+      return SYSERR;
+    }
+#define PINIT(a,b) a = mysql_stmt_init(dbh->dbf); if (a == NULL) { iclose(); 
return SYSERR; } else { \
+    if (mysql_stmt_prepare (a, b, strlen(b))) { \
+      GE_LOG (ectx, GE_ERROR | GE_BULK | GE_USER, \
+             _("`%s' failed at %s:%d with error: %s"), "mysql_stmt_prepare", 
__FILE__, __LINE__, \
+             mysql_stmt_error (a));  iclose(); return SYSERR; } }
+  PINIT(dbh->select_value, SELECT_VALUE);
+  PINIT(dbh->delete_value, DELETE_VALUE);
+  PINIT(dbh->insert_value, INSERT_VALUE);
+  PINIT(dbh->insert_entry, INSERT_ENTRY);
+  PINIT(dbh->delete_entry_by_vkey, DELETE_ENTRY_BY_VKEY);
+  PINIT(dbh->select_entry_by_hash, SELECT_ENTRY_BY_HASH);
+  PINIT(dbh->select_entry_by_hash_and_type, SELECT_ENTRY_BY_HASH_AND_TYPE);
+  PINIT(dbh->count_entry_by_hash, COUNT_ENTRY_BY_HASH);
+  PINIT(dbh->count_entry_by_hash_and_type, COUNT_ENTRY_BY_HASH_AND_TYPE);
+  PINIT(dbh->update_entry, UPDATE_ENTRY);
+  PINIT(dbh->ilow, SELECT_IT_LOW_PRIORITY);
+  PINIT(dbh->inon, SELECT_IT_NON_ANONYMOUS);
+  PINIT(dbh->iexp, SELECT_IT_EXPIRATION_TIME);
+  PINIT(dbh->imig, SELECT_IT_MIGRATION_ORDER);
+  PINIT(dbh->iall, SELECT_ALL);
+  dbh->valid = YES;
+  return OK;
+}
+
+/**
+ * Check if DBH handle is valid, return OK if it is.
+ * Also tries to re-connect to the DB if the connection
+ * is down.
+ */
+#define CHECK_DBH ((dbh->valid == NO) ? iopen(dbh, YES) : OK)
+
+
+/**
+ * Delete an value from the gn072 table.
+ *
+ * @param vkey vkey identifying the value to delete
+ * @return OK on success, NO if no such value exists, SYSERR on error
+ */
+static int delete_value(unsigned long long vkey) {
+  MYSQL_BIND qbind[1];
+  int ret;
+
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].is_unsigned = YES;
+  qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[0].buffer = &vkey;
+  GE_ASSERT (ectx,
+            mysql_stmt_param_count (dbh->delete_value) == 1);
+  if (mysql_stmt_bind_param(dbh->delete_value,
+                           qbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_param",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->delete_value));
+    iclose ();
+    return SYSERR;
+  }
+  if (mysql_stmt_execute (dbh->delete_value))
+    {
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_execute",
+              __FILE__, __LINE__, mysql_stmt_error (dbh->delete_value));
+      iclose ();
+      return SYSERR;
+    }
+  if (mysql_stmt_affected_rows(dbh->delete_value) == 0)
+    ret = NO;
   else
+    ret = OK;
+  mysql_stmt_reset(dbh->delete_value);
+  return ret;
+}
+
+/**
+ * Insert a value into the gn072 table.
+ *
+ * @param value the value to insert
+ * @param size size of the value
+ * @param vkey vkey identifying the value henceforth (set)
+ * @return OK on success, SYSERR on error
+ */
+static int insert_value(const void * value,
+                       unsigned int size,
+                       unsigned long long * vkey) {
+  MYSQL_BIND qbind[1];
+  unsigned long length = size;
+
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].buffer_type = MYSQL_TYPE_BLOB;
+  qbind[0].buffer = (void*) value; 
+  qbind[0].buffer_length = size;
+  qbind[0].length = &length;
+  GE_ASSERT (ectx,
+            mysql_stmt_param_count (dbh->insert_value) == 1);
+  if (mysql_stmt_bind_param(dbh->insert_value,
+                           qbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_param",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->insert_value));
+    iclose ();
+    return SYSERR;
+  }
+  if (mysql_stmt_execute (dbh->insert_value))
     {
-      dbhI->prepare = NO;
-      mysql_query (dbhI->dbf,
-                   "SET SESSION net_read_timeout=28800, SESSION 
net_write_timeout=28800");
-      if (mysql_error (dbhI->dbf)[0])
-        {
-          LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
-          mysql_close (dbhI->dbf);
-          dbhI->dbf = NULL;
-          return SYSERR;
-        }
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_execute",
+              __FILE__, __LINE__, mysql_stmt_error (dbh->insert_value));
+      iclose ();
+      return SYSERR;
     }
-  dbhI->valid = YES;
+  *vkey = (unsigned long long) mysql_stmt_insert_id(dbh->insert_value);
+  mysql_stmt_reset(dbh->insert_value);
   return OK;
 }
 
 /**
- * Close the database connection.
+ * Delete an entry from the gn071 table.
+ *
+ * @param vkey vkey identifying the entry to delete
+ * @return OK on success, NO if no such value exists, SYSERR on error
  */
+static int delete_entry_by_vkey(unsigned long long vkey) {
+  MYSQL_BIND qbind[1];
+  int ret;
+
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].is_unsigned = YES;
+  qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[0].buffer = &vkey;
+  GE_ASSERT (ectx,
+            mysql_stmt_param_count (dbh->delete_entry_by_vkey) == 1);
+  if (mysql_stmt_bind_param(dbh->delete_entry_by_vkey,
+                           qbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_param",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->delete_entry_by_vkey));
+    iclose ();
+    return SYSERR;
+  }
+  if (mysql_stmt_execute (dbh->delete_entry_by_vkey))
+    {
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_execute",
+              __FILE__, __LINE__, mysql_stmt_error 
(dbh->delete_entry_by_vkey));
+      iclose ();
+      return SYSERR;
+    }
+  if (mysql_stmt_affected_rows(dbh->delete_entry_by_vkey) == 0)
+    ret = NO;
+  else
+    ret = OK;
+  mysql_stmt_reset(dbh->delete_entry_by_vkey);
+  return ret;
+}
+
+/**
+ * Given a full (SELECT *) result set from gn071 table,
+ * assemble it into a Datastore_Value representation.
+ *
+ * @param result location where mysql_stmt_fetch stored the results
+ * @return NULL on error
+ */
+static Datastore_Value *
+assembleDatum (MYSQL_BIND * result)
+{
+  Datastore_Value *datum;
+  unsigned int contentSize;
+  unsigned int type;
+  unsigned int prio;
+  unsigned int level;
+  unsigned long long exp;
+  unsigned long long vkey;
+  unsigned long length;
+  MYSQL_BIND qbind[1];
+  MYSQL_BIND rbind[1];
+
+  if ( (result[0].buffer_type != MYSQL_TYPE_LONG) ||
+       (! result[0].is_unsigned) ||
+       (result[1].buffer_type != MYSQL_TYPE_LONG) ||
+       (! result[1].is_unsigned) ||
+       (result[2].buffer_type != MYSQL_TYPE_LONG) ||
+       (! result[2].is_unsigned) ||
+       (result[3].buffer_type != MYSQL_TYPE_LONG) ||
+       (! result[3].is_unsigned) ||
+       (result[4].buffer_type != MYSQL_TYPE_LONGLONG) ||
+       (! result[4].is_unsigned) ||
+       (result[5].buffer_type != MYSQL_TYPE_STRING) ||
+       (result[5].buffer_length != sizeof(HashCode512)) ||
+       (*result[5].length != sizeof(HashCode512)) ||
+       (result[6].buffer_type != MYSQL_TYPE_LONGLONG) ||
+       (! result[6].is_unsigned) ) 
+    return NULL; /* error */  
+  
+  contentSize = * (unsigned int*) result[0].buffer;
+  if (contentSize < sizeof(Datastore_Value))
+    return NULL;                /* error */
+  contentSize -= sizeof(Datastore_Value);
+  type = *(unsigned int*) result[1].buffer;
+  prio = *(unsigned int*) result[2].buffer;
+  level = *(unsigned int*) result[3].buffer;
+  exp = *(unsigned long long*) result[4].buffer;
+  vkey = *(unsigned long long*) result[6].buffer;
+  datum = MALLOC (sizeof (Datastore_Value) + contentSize);
+  datum->size = htonl (contentSize + sizeof (Datastore_Value));
+  datum->type = htonl (type);
+  datum->prio = htonl (prio);
+  datum->anonymityLevel = htonl (level);
+  datum->expirationTime = htonll (exp);
+
+  /* now do query on gn072 */
+  length = contentSize;
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].is_unsigned = YES;
+  qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[0].buffer = &vkey;
+  memset(rbind, 0, sizeof(rbind));
+  rbind[0].buffer_type = MYSQL_TYPE_BLOB;
+  rbind[0].buffer_length = contentSize;
+  rbind[0].length = &length;
+  rbind[0].buffer = &datum[1];
+  GE_ASSERT (ectx,
+            mysql_stmt_param_count (dbh->select_value) == 1);
+  if (mysql_stmt_bind_param(dbh->select_value,
+                           qbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_param",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+    iclose ();
+    return NULL;
+  }
+  if (mysql_stmt_execute (dbh->select_value))
+    {
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_execute",
+              __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+      iclose ();
+      return NULL;
+    }
+  GE_ASSERT (ectx,
+            mysql_stmt_field_count (dbh->select_value) == 1);
+  if (mysql_stmt_bind_result(dbh->select_value,
+                            rbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_result",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+    iclose ();
+    return NULL;
+  }
+  if ( (mysql_stmt_fetch(dbh->select_value)) ||
+       (rbind[0].buffer_length != contentSize) ||
+       (length != contentSize) ) {
+    mysql_stmt_reset(dbh->select_value);
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_result",
+           __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+    delete_entry_by_vkey(vkey);
+    content_size -= ntohl(datum->size);
+    return NULL;
+  }
+  mysql_stmt_reset(dbh->select_value);
+  return datum;
+}
+
+/**
+ * Store an item in the datastore.
+ *
+ * @return OK on success, SYSERR on error
+ */
 static int
-iclose (mysqlHandle * dbhI)
+put (const HashCode512 * key, const Datastore_Value * value)
 {
-  if (dbhI->dbf == NULL)
+  unsigned long contentSize;
+  unsigned long hashSize;
+  unsigned int size;
+  unsigned int type;
+  unsigned int prio;
+  unsigned int level;
+  unsigned long long expiration;
+  unsigned long long vkey;
+  MYSQL_BIND qbind[7];
+#if DEBUG_MYSQL
+  EncName enc;
+#endif
+
+  if ( ((ntohl (value->size) < sizeof (Datastore_Value))) ||
+       ((ntohl (value->size) - sizeof (Datastore_Value)) > MAX_DATUM_SIZE) )   
 
+    {
+      GE_BREAK (ectx, 0);
+      return SYSERR;
+    }
+  MUTEX_LOCK (lock);
+  mysql_thread_init ();
+  if (OK != CHECK_DBH)
+    {
+      mysql_thread_end ();
+      MUTEX_UNLOCK (lock);
+      return SYSERR;
+    }
+  contentSize = ntohl (value->size) - sizeof (Datastore_Value);
+  if (OK != insert_value(&value[1],
+                        contentSize,
+                        &vkey)) {
+    mysql_thread_end ();
+    MUTEX_UNLOCK (lock);
     return SYSERR;
-  if (dbhI->prepare == YES)
+  }
+  hashSize = sizeof (HashCode512);
+  size = ntohl (value->size);
+  type = ntohl (value->type);
+  prio = ntohl (value->prio);
+  level = ntohl (value->anonymityLevel);
+  expiration = ntohll (value->expirationTime);
+#if DEBUG_MYSQL
+  IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
+  GE_LOG (ectx,
+          GE_DEBUG | GE_REQUEST | GE_USER,
+          "Storing in database block with type %u and key %s.\n", type, &enc);
+#endif
+  GE_ASSERT (ectx,
+            mysql_stmt_param_count (dbh->insert_entry) == 7);
+  memset(qbind, 0, sizeof (qbind));
+  qbind[0].buffer_type = MYSQL_TYPE_LONG;      /* size */
+  qbind[0].buffer = &size;
+  qbind[0].is_unsigned = YES;
+  qbind[1].buffer_type = MYSQL_TYPE_LONG;      /* type */
+  qbind[1].is_unsigned = YES;
+  qbind[1].buffer = &type;
+  qbind[2].buffer_type = MYSQL_TYPE_LONG;      /* prio */
+  qbind[2].is_unsigned = YES;
+  qbind[2].buffer = &prio;
+  qbind[3].buffer_type = MYSQL_TYPE_LONG;      /* anon level */
+  qbind[3].is_unsigned = YES;
+  qbind[3].buffer = &level;
+  qbind[4].buffer_type = MYSQL_TYPE_LONGLONG;  /* expiration */
+  qbind[4].is_unsigned = YES;
+  qbind[4].buffer = &expiration;
+  qbind[5].buffer_type = MYSQL_TYPE_STRING; /* hash */
+  qbind[5].buffer = (void*) key;
+  qbind[5].length = &hashSize;
+  qbind[5].buffer_length = hashSize;
+  qbind[6].buffer_type = MYSQL_TYPE_LONGLONG;   /* vkey */
+  qbind[6].is_unsigned = YES; 
+  qbind[6].buffer = &vkey;
+
+  if (mysql_stmt_bind_param (dbh->insert_entry, qbind))
     {
-      mysql_stmt_free_result (dbhI->update);
-      mysql_stmt_free_result (dbhI->insert);
-      mysql_stmt_free_result (dbhI->select);
-      mysql_stmt_free_result (dbhI->selectc);
-      mysql_stmt_free_result (dbhI->selects);
-      mysql_stmt_free_result (dbhI->selectsc);
-      mysql_stmt_free_result (dbhI->deleteh);
-      mysql_stmt_free_result (dbhI->deleteg);
-      mysql_stmt_close (dbhI->update);
-      mysql_stmt_close (dbhI->insert);
-      mysql_stmt_close (dbhI->select);
-      mysql_stmt_close (dbhI->selectc);
-      mysql_stmt_close (dbhI->selects);
-      mysql_stmt_close (dbhI->selectsc);
-      mysql_stmt_close (dbhI->deleteh);
-      mysql_stmt_close (dbhI->deleteg);
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_bind_param",
+              __FILE__, __LINE__, mysql_stmt_error (dbh->insert_entry));
+      delete_value(vkey);
+      iclose ();
+      mysql_thread_end ();
+      MUTEX_UNLOCK (lock);
+      return SYSERR;
     }
-  mysql_close (dbhI->dbf);
-  dbhI->dbf = NULL;
-  dbhI->valid = NO;
+
+  if (mysql_stmt_execute (dbh->insert_entry))
+    {
+      GE_LOG (ectx,
+              GE_ERROR | GE_BULK | GE_USER,
+              _("`%s' failed at %s:%d with error: %s\n"),
+              "mysql_stmt_execute",
+              __FILE__, __LINE__, mysql_stmt_error (dbh->insert_entry));
+      delete_value(vkey);      
+      iclose ();
+      mysql_thread_end ();
+      MUTEX_UNLOCK (lock);
+      return SYSERR;
+    }
+  mysql_thread_end ();
+  content_size += ntohl (value->size);
+  MUTEX_UNLOCK (lock);
   return OK;
 }
 
-/**
- * Check if DBH handle is valid, return OK if it is.
- * Also tries to re-connect to the DB if the connection
- * is down.
- */
-#define CHECK_DBH ((dbh->valid == NO) ? iopen(dbh, YES) : OK)
 
+
+
 /**
  * Iterate over the items in the datastore
  * using the given query to select and order
@@ -549,85 +754,194 @@
  * @param type entries of which type should be considered?
  *        Use 0 for any type.
  * @param iter never NULL
+ * @param is_asc are we using ascending order?
+ * @param is_int is the extra ordering (other than vkey) an int?
  * @return the number of results, SYSERR if the
  *   iter is non-NULL and aborted the iteration
  */
 static int
 iterateHelper (unsigned int type,
-               const char *query, Datum_Iterator iter, void *closure)
+              int is_asc,
+              int is_int,
+               MYSQL_STMT * stmt, Datum_Iterator iter, void *closure)
 {
-  MYSQL_RES *sql_res;
-  MYSQL_ROW sql_row;
-  Datastore_Datum *datum;
-  char *scratch;
-  char typestr[32];
-  int count = 0;
-  mysqlHandle dbhI;
+  Datastore_Value * datum;
+  int count;
+  int ret;
+  int found;
+  unsigned int last_prio;
+  unsigned long long last_expire;
+  unsigned long long last_vkey;
+  unsigned int size;
+  unsigned int rtype;
+  unsigned int prio;
+  unsigned int level;
+  unsigned long long expiration;
+  unsigned long long vkey;
+  unsigned long hashSize;
+  HashCode512 key;
   cron_t now;
+  MYSQL_BIND qbind[4];
+  MYSQL_BIND rbind[7];
 
-  dbhI.cnffile = dbh->cnffile;  /* shared */
-  if (OK != iopen (&dbhI, NO))
-    return SYSERR;
+  if (is_asc) {
+    last_prio = 0;
+    last_vkey = 0;
+    last_expire = 0;
+  } else {
+    last_prio = -1;
+    last_vkey = -1;
+    last_expire = -1;
+  }
+  if (is_int) {
+    qbind[0].buffer_type = MYSQL_TYPE_LONG;
+    qbind[0].buffer = &last_prio;
+    qbind[0].is_unsigned = YES;
+    qbind[2].buffer_type = MYSQL_TYPE_LONG;
+    qbind[2].buffer = &last_prio;  
+    qbind[2].is_unsigned = YES;
+  } else {
+    qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+    qbind[0].buffer = &last_expire;
+    qbind[0].is_unsigned = YES;
+    qbind[2].buffer_type = MYSQL_TYPE_LONGLONG;
+    qbind[2].buffer = &last_expire;  
+    qbind[2].is_unsigned = YES;
+  }
+  qbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[1].buffer = &last_vkey;
+  qbind[1].is_unsigned = YES;
+  qbind[3].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[3].buffer = &now;
+  qbind[3].is_unsigned = YES;
+  
+  hashSize = sizeof(HashCode512);
+  memset(rbind, 0, sizeof(rbind));
+  rbind[0].buffer_type = MYSQL_TYPE_LONG;
+  rbind[0].buffer = &size;
+  rbind[0].is_unsigned = YES;
+  rbind[1].buffer_type = MYSQL_TYPE_LONG;
+  rbind[1].buffer = &rtype;
+  rbind[1].is_unsigned = YES;
+  rbind[2].buffer_type = MYSQL_TYPE_LONG;
+  rbind[2].buffer = &prio;
+  rbind[2].is_unsigned = YES;
+  rbind[3].buffer_type = MYSQL_TYPE_LONG;
+  rbind[3].buffer = &level;
+  rbind[3].is_unsigned = YES;
+  rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
+  rbind[4].buffer = &expiration;
+  rbind[4].is_unsigned = YES;
+  rbind[5].buffer_type = MYSQL_TYPE_STRING;
+  rbind[5].buffer = &key;
+  rbind[5].buffer_length = hashSize;
+  rbind[5].length = &hashSize;
+  rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
+  rbind[6].buffer = &vkey;
+  rbind[6].is_unsigned = YES;
 
   mysql_thread_init ();
-  mysql_query (dbhI.dbf, "SET AUTOCOMMIT = 0");
-  mysql_query (dbhI.dbf,
-               "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
-  if (type == 0)
-    {
-      typestr[0] = '\0';
+  count = 0;
+  while (1) {
+    MUTEX_LOCK (lock);
+    if (OK != CHECK_DBH) {
+      MUTEX_UNLOCK (lock);
+      mysql_thread_end ();
+      return SYSERR; 
     }
-  else
-    {
-      SNPRINTF (typestr, 32, "WHERE type=%u ", type);
-    }
-  now = get_time ();
-  scratch = MALLOC (256);
-  SNPRINTF (scratch, 256, query, typestr, now);
-  mysql_query (dbhI.dbf, scratch);
-  FREE (scratch);
-  if (mysql_error (dbhI.dbf)[0])
-    {
-      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", &dbhI);
+    now = get_time ();
+    GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 4);
+    if (mysql_stmt_bind_param (stmt, qbind))
+      {
+       GE_LOG (ectx,
+               GE_ERROR | GE_BULK | GE_USER,
+               _("`%s' failed at %s:%d with error: %s\n"),
+               "mysql_stmt_bind_param",
+               __FILE__, __LINE__, mysql_stmt_error (stmt));
+       iclose ();
+       mysql_thread_end ();
+       MUTEX_UNLOCK (lock);
+       return SYSERR;
+      }
+    if (mysql_stmt_execute (stmt))
+      {
+       GE_LOG (ectx,
+               GE_ERROR | GE_BULK | GE_USER,
+               _("`%s' failed at %s:%d with error: %s\n"),
+               "mysql_stmt_execute",
+               __FILE__, __LINE__, mysql_stmt_error (stmt));
+       iclose ();
+       mysql_thread_end ();
+       MUTEX_UNLOCK (lock);
+       return SYSERR;
+      }    
+    GE_ASSERT (ectx,
+              mysql_stmt_field_count (stmt) == 7);
+    if (mysql_stmt_bind_result(stmt,
+                              rbind)) {
+      GE_LOG (ectx,
+             GE_ERROR | GE_BULK | GE_USER,
+             _("`%s' failed at %s:%d with error: %s\n"),
+             "mysql_stmt_bind_result",
+             __FILE__, __LINE__, mysql_stmt_error (stmt));
+      iclose ();
       mysql_thread_end ();
-      iclose (&dbhI);
+      MUTEX_UNLOCK (lock);
       return SYSERR;
     }
-  if (!(sql_res = mysql_use_result (dbhI.dbf)))
-    {
-      iclose (&dbhI);
-      return SYSERR;
-    }
-  while ((sql_row = mysql_fetch_row (sql_res)))
-    {
-      datum = assembleDatum (sql_res, sql_row, &dbhI);
-      if (datum == NULL)
-        {
-          mysql_thread_end ();
-          iclose (&dbhI);
-          return count;
-        }
-      if ((iter != NULL) &&
-          (SYSERR == iter (&datum->key, &datum->value, closure)))
-        {
-          count = SYSERR;
-          FREE (datum);
-          break;
-        }
-      FREE (datum);
+    found = NO;
+    datum = NULL;
+    while (mysql_stmt_fetch(stmt)) {
+      if (datum != NULL) {
+       if (iter == NULL)
+         ret = OK;
+       else 
+         ret = iter(&key,
+                    datum,
+                    closure,
+                    vkey);
+       FREE(datum);
+       datum = NULL;
+       if (ret == SYSERR) 
+         break;        
+       if (ret == NO) {
+         delete_value(vkey);
+         delete_entry_by_vkey(vkey);
+         content_size -= ntohl(datum->size);
+       }
+      }
+      found = YES;
       count++;
+      datum = assembleDatum(rbind);
+      mysql_stmt_reset(stmt);
     }
-  if (mysql_error (dbhI.dbf)[0])
-    {
-      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", &dbhI);
-      mysql_free_result (sql_res);
-      mysql_thread_end ();
-      iclose (&dbhI);
-      return SYSERR;
+    if (found == NO) {
+      mysql_stmt_reset(stmt);
+      MUTEX_UNLOCK (lock);
+      break;
     }
-  mysql_free_result (sql_res);
+    MUTEX_UNLOCK (lock);
+    if (datum == NULL)
+      continue;
+    ret = iter(&key,
+              datum,
+              closure,
+              vkey);
+    FREE(datum);
+    if (ret == SYSERR) 
+      break;        
+    if (ret == NO) {
+      MUTEX_LOCK (lock);
+      delete_value(vkey);
+      delete_entry_by_vkey(vkey);
+      content_size -= ntohl(datum->size);
+      MUTEX_UNLOCK (lock);
+    }
+    last_prio = prio;
+    last_vkey = vkey;
+    last_expire = expiration;
+  }
   mysql_thread_end ();
-  iclose (&dbhI);
   return count;
 }
 
@@ -645,8 +959,10 @@
 iterateLowPriority (unsigned int type, Datum_Iterator iter, void *closure)
 {
   return iterateHelper (type,
-                        "SELECT SQL_NO_CACHE * FROM gn070"
-                        " %s" "ORDER BY prio ASC", iter, closure);
+                       YES, YES,
+                        dbh->ilow,
+                        iter, 
+                       closure);
 }
 
 /**
@@ -661,21 +977,13 @@
  */
 static int
 iterateNonAnonymous (unsigned int type,
-                     int on_demand, Datum_Iterator iter, void *closure)
+                     Datum_Iterator iter, void *closure)
 {
-  char limit[512];
-
-  if (on_demand == YES)
-    SNPRINTF (limit,
-              512,
-              "SELECT SQL_NO_CACHE * FROM gn070"
-              " %%s WHERE expire > %%llu AND anonLevel = 0 AND type != %d",
-              ONDEMAND_BLOCK);
-  else
-    strcpy (limit,
-            "SELECT SQL_NO_CACHE * FROM gn070"
-            " %s WHERE expire > %llu AND anonLevel = 0");
-  return iterateHelper (type, limit, iter, closure);
+  return iterateHelper (type,
+                       NO, YES,
+                       dbh->inon,
+                       iter,
+                       closure);
 }
 
 /**
@@ -692,8 +1000,10 @@
 iterateExpirationTime (unsigned int type, Datum_Iterator iter, void *closure)
 {
   return iterateHelper (type,
-                        "SELECT SQL_NO_CACHE * FROM gn070"
-                        " %s" " ORDER BY expire ASC", iter, closure);
+                       YES, NO,
+                        dbh->iexp,
+                       iter,
+                       closure);
 }
 
 /**
@@ -708,9 +1018,11 @@
 iterateMigrationOrder (Datum_Iterator iter, void *closure)
 {
   return iterateHelper (0,
-                        "SELECT SQL_NO_CACHE * FROM gn070"
-                        " %s WHERE expire > %llu AND type!=3"
-                        " ORDER BY expire DESC", iter, closure);
+                       NO,
+                       NO,
+                        dbh->imig,
+                       iter,
+                       closure);
 }
 
 /**
@@ -724,11 +1036,13 @@
 static int
 iterateAllNow (Datum_Iterator iter, void *closure)
 {
-  return iterateHelper (0, "SELECT SQL_NO_CACHE * FROM gn070", iter, closure);
+  return iterateHelper (0, 
+                       NO,
+                       NO,
+                       dbh->iall,
+                       iter, closure);
 }
 
-#define MAX_DATUM_SIZE 65536
-
 /**
  * Iterate over the results for a particular key
  * in the datastore.
@@ -744,19 +1058,20 @@
 get (const HashCode512 * query,
      unsigned int type, Datum_Iterator iter, void *closure)
 {
-  MYSQL_RES *sql_res;
   int count;
-  MYSQL_STMT *stmt;
+  int ret;
+  MYSQL_STMT * stmt;
   unsigned int size;
   unsigned int rtype;
   unsigned int prio;
   unsigned int level;
   unsigned long long expiration;
-  unsigned long datasize;
-  unsigned long twenty;
-  Datastore_Value *datum;
+  unsigned long long vkey;
+  Datastore_Value * datum;
   HashCode512 key;
   unsigned long hashSize;
+  MYSQL_BIND qbind[2];  
+  MYSQL_BIND rbind[7];
 #if DEBUG_MYSQL
   EncName enc;
 #endif
@@ -781,55 +1096,41 @@
   if (type != 0)
     {
       if (iter == NULL)
-        stmt = dbh->selectsc;
+        stmt = dbh->count_entry_by_hash_and_type;
       else
-        stmt = dbh->selects;
+        stmt = dbh->select_entry_by_hash_and_type;
     }
   else
     {
       if (iter == NULL)
-        stmt = dbh->selectc;
+        stmt = dbh->count_entry_by_hash;
       else
-        stmt = dbh->select;
+        stmt = dbh->select_entry_by_hash;
     }
+
   hashSize = sizeof (HashCode512);
-  dbh->sbind[0].buffer = (char *) query;
-  dbh->sbind[1].buffer = (char *) &type;
-  dbh->sbind[0].length = &hashSize;
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].buffer_type = MYSQL_TYPE_STRING;
+  qbind[0].buffer = (void*) query;
+  qbind[0].length = &hashSize;
+  qbind[0].buffer_length = hashSize;
+  qbind[1].buffer_type = MYSQL_TYPE_LONG;
+  qbind[1].buffer = &type;
   GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 2);
-  sql_res = mysql_stmt_result_metadata (stmt);
-  if (!sql_res)
+
+  if (mysql_stmt_bind_param (stmt, qbind))
     {
       GE_LOG (ectx,
               GE_ERROR | GE_BULK | GE_USER,
               _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_result_metadata",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  if ((iter != NULL) && (7 != mysql_num_fields (sql_res)))
-    {
-      GE_BREAK (ectx, 0);
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  if (mysql_stmt_bind_param (stmt, dbh->sbind))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
               "mysql_stmt_bind_param",
               __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
+      iclose ();
       mysql_thread_end ();
       MUTEX_UNLOCK (lock);
       return SYSERR;
     }
+
   if (mysql_stmt_execute (stmt))
     {
       GE_LOG (ectx,
@@ -837,11 +1138,12 @@
               _("`%s' failed at %s:%d with error: %s\n"),
               "mysql_stmt_execute",
               __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
+      iclose ();
       mysql_thread_end ();
       MUTEX_UNLOCK (lock);
       return SYSERR;
     }
+
   if (iter == NULL)
     {
       count = mysql_stmt_affected_rows (stmt);
@@ -849,473 +1151,80 @@
       mysql_thread_end ();
       MUTEX_UNLOCK (lock);
       return count;
-    }
-  datum = MALLOC (sizeof (Datastore_Value) + MAX_DATUM_SIZE);
-  twenty = sizeof (HashCode512);
-  dbh->bind[0].buffer = (char *) &size;
-  dbh->bind[1].buffer = (char *) &rtype;
-  dbh->bind[2].buffer = (char *) &prio;
-  dbh->bind[3].buffer = (char *) &level;
-  dbh->bind[4].buffer = (char *) &expiration;
-  dbh->bind[5].buffer = (char *) &key;
-  dbh->bind[6].buffer = (char *) &datum[1];
-  dbh->bind[5].length = &twenty;
-  dbh->bind[6].length = &datasize;
-  dbh->bind[5].buffer_length = sizeof (HashCode512);
-  dbh->bind[6].buffer_length = MAX_DATUM_SIZE;
-  if (mysql_stmt_bind_result (stmt, dbh->bind))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_bind_result",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      FREE (datum);
-      return SYSERR;
-    }
-  if (mysql_stmt_store_result (stmt))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_store_result",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      FREE (datum);
-      return SYSERR;
-    }
-  datasize = MAX_DATUM_SIZE;
+    } 
+  GE_ASSERT (ectx,
+            mysql_stmt_field_count (stmt) == 7);
+  memset(rbind, 0, sizeof(rbind));
+  rbind[0].buffer_type = MYSQL_TYPE_LONG;
+  rbind[0].buffer = &size;
+  rbind[0].is_unsigned = YES;
+  rbind[1].buffer_type = MYSQL_TYPE_LONG;
+  rbind[1].buffer = &rtype;
+  rbind[1].is_unsigned = YES;
+  rbind[2].buffer_type = MYSQL_TYPE_LONG;
+  rbind[2].buffer = &prio;
+  rbind[2].is_unsigned = YES;
+  rbind[3].buffer_type = MYSQL_TYPE_LONG;
+  rbind[3].buffer = &level;
+  rbind[3].is_unsigned = YES;
+  rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
+  rbind[4].buffer = &expiration;
+  rbind[4].is_unsigned = YES;
+  rbind[5].buffer_type = MYSQL_TYPE_STRING;
+  rbind[5].buffer = &key;
+  rbind[5].buffer_length = hashSize;
+  rbind[5].length = &hashSize;
+  rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
+  rbind[6].buffer = &vkey;
+  rbind[6].is_unsigned = YES;
+  if (mysql_stmt_bind_result(dbh->select_value,
+                            rbind)) {
+    GE_LOG (ectx,
+           GE_ERROR | GE_BULK | GE_USER,
+           _("`%s' failed at %s:%d with error: %s\n"),
+           "mysql_stmt_bind_result",
+           __FILE__, __LINE__, mysql_stmt_error (stmt));
+    iclose ();
+    mysql_thread_end ();
+    MUTEX_UNLOCK (lock);
+    return SYSERR;
+  }
   count = 0;
-  while (0 == mysql_stmt_fetch (stmt))
-    {
-      if ((twenty != sizeof (HashCode512)) ||
-          (datasize != size - sizeof (Datastore_Value)))
-        {
-          char scratch[512];
-
-          mysql_free_result (sql_res);
-          GE_LOG (ectx,
-                  GE_WARNING | GE_BULK | GE_USER,
-                  _("Invalid data in %s.  Trying to fix (by deletion).\n"),
-                  _("mysql datastore"));
-          SNPRINTF (scratch,
-                    512,
-                    "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND 
(size=%u + LENGTH(value)))",
-                    sizeof (HashCode512), sizeof (Datastore_Value));
-          if (0 != mysql_query (dbh->dbf, scratch))
-            LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
-
-          FREE (datum);
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return count;
-        }
-      count++;
-      datum->size = htonl (size);
-      datum->type = htonl (rtype);
-      datum->prio = htonl (prio);
-      datum->anonymityLevel = htonl (level);
-      datum->expirationTime = htonll (expiration);
-#if DEBUG_MYSQL
-      GE_LOG (ectx,
-              GE_DEBUG | GE_REQUEST | GE_USER,
-              "Found in database block with type %u.\n",
-              ntohl (*(int *) &datum[1]));
-#endif
-      if (SYSERR == iter (&key, datum, closure))
-        {
-          count = SYSERR;
-          break;
-        }
-      datasize = MAX_DATUM_SIZE;
+  while (mysql_stmt_fetch(stmt)) {
+    datum = assembleDatum(rbind);
+    if (datum == NULL)
+      continue;
+    count++;
+    ret = iter(&key,
+              datum,
+              closure,
+              vkey);
+    FREE(datum);
+    if (ret == SYSERR) 
+      break;    
+    if (ret == NO) {
+      delete_value(vkey);
+      delete_entry_by_vkey(vkey);
+      content_size -= ntohl(datum->size);
     }
-  if (mysql_stmt_errno (stmt))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_fetch",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      mysql_free_result (sql_res);
-      FREE (datum);
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  mysql_free_result (sql_res);
-  FREE (datum);
+  }
+  mysql_stmt_reset(stmt);
   mysql_thread_end ();
   MUTEX_UNLOCK (lock);
-
-#if DEBUG_MYSQL
-  IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (query, &enc));
-  if (count > 0)
-    {
-      GE_LOG (ectx,
-              GE_DEBUG | GE_REQUEST | GE_USER,
-              "MySQL found %d results for `%s' of type %u.\n",
-              count, &enc, type);
-    }
-  else
-    {
-      GE_LOG (ectx,
-              GE_DEBUG | GE_REQUEST | GE_USER,
-              "MySQL iteration aborted looking for `%s' of type %u.\n",
-              &enc, type);
-    }
-#endif
   return count;
 }
 
 /**
- * Store an item in the datastore.
- *
- * @return OK on success, SYSERR on error
- */
-static int
-put (const HashCode512 * key, const Datastore_Value * value)
-{
-  unsigned long contentSize;
-  unsigned long hashSize;
-  unsigned int size;
-  unsigned int type;
-  unsigned int prio;
-  unsigned int level;
-  unsigned long long expiration;
-#if DEBUG_MYSQL
-  EncName enc;
-#endif
-
-  if ((ntohl (value->size) < sizeof (Datastore_Value)))
-    {
-      GE_BREAK (ectx, 0);
-      return SYSERR;
-    }
-  MUTEX_LOCK (lock);
-  mysql_thread_init ();
-  if (OK != CHECK_DBH)
-    {
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  contentSize = ntohl (value->size) - sizeof (Datastore_Value);
-  hashSize = sizeof (HashCode512);
-  size = ntohl (value->size);
-  type = ntohl (value->type);
-  prio = ntohl (value->prio);
-  level = ntohl (value->anonymityLevel);
-  expiration = ntohll (value->expirationTime);
-#if DEBUG_MYSQL
-  IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
-  GE_LOG (ectx,
-          GE_DEBUG | GE_REQUEST | GE_USER,
-          "Storing in database block with type %u and key %s.\n", type, &enc);
-#endif
-  dbh->bind[0].buffer = (char *) &size;
-  dbh->bind[1].buffer = (char *) &type;
-  dbh->bind[2].buffer = (char *) &prio;
-  dbh->bind[3].buffer = (char *) &level;
-  dbh->bind[4].buffer = (char *) &expiration;
-  dbh->bind[5].buffer = (char *) key;
-  dbh->bind[6].buffer = (char *) &value[1];
-  dbh->bind[5].length = &hashSize;
-  dbh->bind[6].length = &contentSize;
-
-  if (mysql_stmt_bind_param (dbh->insert, dbh->bind))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_bind_param",
-              __FILE__, __LINE__, mysql_stmt_error (dbh->insert));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-
-  if (mysql_stmt_execute (dbh->insert))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_execute",
-              __FILE__, __LINE__, mysql_stmt_error (dbh->insert));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  mysql_thread_end ();
-  content_size += ntohl (value->size);
-  MUTEX_UNLOCK (lock);
-  return OK;
-}
-
-/**
- * Delete an item from the datastore.
- *
- * @param value maybe NULL, then all items under the
- *        given key are deleted
- * @return the number of items deleted, 0 if
- *        none were found, SYSERR on errors
- */
-static int
-del (const HashCode512 * key, const Datastore_Value * value)
-{
-  int count;
-  unsigned long twenty;
-  MYSQL_STMT *stmt;
-  unsigned int size;
-  unsigned int type;
-  unsigned int prio;
-  unsigned int anon;
-  unsigned long long expiration;
-  unsigned long datasize;
-  Datastore_Value *svalue;
-  MYSQL_RES *sql_res;
-  unsigned int rtype;
-  unsigned int level;
-  HashCode512 skey;
-#if DEBUG_MYSQL
-  EncName enc;
-
-  IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
-  GE_LOG (ectx,
-          GE_DEBUG | GE_REQUEST | GE_USER,
-          "MySQL is executing deletion request for content of query `%s' and 
type %u\n",
-          &enc, value == NULL ? 0 : ntohl (value->type));
-#endif
-  twenty = sizeof (HashCode512);
-  svalue = NULL;
-  MUTEX_LOCK (lock);
-  mysql_thread_init ();
-  if (OK != CHECK_DBH)
-    {
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      return SYSERR;
-    }
-  if (value == NULL)
-    {
-      stmt = dbh->deleteh;
-      dbh->dbind[0].buffer = (char *) key;
-      dbh->dbind[0].length = &twenty;
-      GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 1);
-
-      sql_res = mysql_stmt_result_metadata (stmt);
-      if (!sql_res)
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_result_metadata",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return SYSERR;
-        }
-      if (7 != mysql_num_fields (sql_res))
-        {
-          GE_BREAK (ectx, 0);
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return SYSERR;
-        }
-      if (mysql_stmt_bind_param (stmt, dbh->dbind))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_bind_param",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return SYSERR;
-        }
-      if (mysql_stmt_execute (stmt))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_execute",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return SYSERR;
-        }
-      svalue = MALLOC (sizeof (Datastore_Value) + MAX_DATUM_SIZE);
-      twenty = sizeof (HashCode512);
-      dbh->bind[0].buffer = (char *) &size;
-      dbh->bind[1].buffer = (char *) &rtype;
-      dbh->bind[2].buffer = (char *) &prio;
-      dbh->bind[3].buffer = (char *) &level;
-      dbh->bind[4].buffer = (char *) &expiration;
-      dbh->bind[5].buffer = (char *) &skey;
-      dbh->bind[6].buffer = (char *) &svalue[1];
-      dbh->bind[5].length = &twenty;
-      dbh->bind[6].length = &datasize;
-      dbh->bind[5].buffer_length = sizeof (HashCode512);
-      dbh->bind[6].buffer_length = MAX_DATUM_SIZE;
-      if (mysql_stmt_bind_result (stmt, dbh->bind))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_bind_result",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          FREE (svalue);
-          return SYSERR;
-        }
-      if (mysql_stmt_store_result (stmt))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_store_result",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          FREE (svalue);
-          return SYSERR;
-        }
-      datasize = MAX_DATUM_SIZE;
-      if (0 != mysql_stmt_fetch (stmt))
-        {
-          GE_LOG (ectx,
-                  GE_ERROR | GE_BULK | GE_USER,
-                  _("`%s' failed at %s:%d with error: %s\n"),
-                  "mysql_stmt_fetch",
-                  __FILE__, __LINE__, mysql_stmt_error (stmt));
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          FREE (svalue);
-          return SYSERR;
-        }
-      if ((twenty != sizeof (HashCode512)) ||
-          (datasize != size - sizeof (Datastore_Value)))
-        {
-          char scratch[512];
-
-          mysql_free_result (sql_res);
-          GE_LOG (ectx,
-                  GE_WARNING | GE_BULK | GE_USER,
-                  _("Invalid data in %s.  Trying to fix (by deletion).\n"),
-                  _("mysql datastore"));
-          SNPRINTF (scratch,
-                    512,
-                    "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND 
(size=%u + LENGTH(value)))",
-                    sizeof (HashCode512), sizeof (Datastore_Value));
-          if (0 != mysql_query (dbh->dbf, scratch))
-            LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
-          FREE (svalue);
-          iclose (dbh);
-          mysql_thread_end ();
-          MUTEX_UNLOCK (lock);
-          return 1;
-        }
-      mysql_free_result (sql_res);
-      svalue->size = htonl (size);
-      svalue->type = htonl (rtype);
-      svalue->prio = htonl (prio);
-      svalue->anonymityLevel = htonl (level);
-      svalue->expirationTime = htonll (expiration);
-      value = svalue;
-    }
-
-  stmt = dbh->deleteg;
-  type = ntohl (value->type);
-  size = ntohl (value->size);
-  prio = ntohl (value->prio);
-  anon = ntohl (value->anonymityLevel);
-  expiration = ntohll (value->expirationTime);
-  datasize = ntohl (value->size) - sizeof (Datastore_Value);
-  dbh->dbind[0].buffer = (char *) key;
-  dbh->dbind[0].length = &twenty;
-  dbh->dbind[1].buffer = (char *) &size;
-  dbh->dbind[2].buffer = (char *) &type;
-  dbh->dbind[3].buffer = (char *) &prio;
-  dbh->dbind[4].buffer = (char *) &anon;
-  dbh->dbind[5].buffer = (char *) &expiration;
-  dbh->dbind[6].buffer = (char *) &value[1];
-  dbh->dbind[6].length = &datasize;
-#if 0
-  dbh->dbind[0].buffer_length = sizeof (HashCode512);
-  dbh->dbind[6].buffer_length = size - sizeof (Datastore_Value);
-#endif
-  GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 7);
-  if (mysql_stmt_bind_param (stmt, dbh->dbind))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_bind_param",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      if (svalue != NULL)
-        FREE (svalue);
-      return SYSERR;
-    }
-  if (mysql_stmt_execute (stmt))
-    {
-      GE_LOG (ectx,
-              GE_ERROR | GE_BULK | GE_USER,
-              _("`%s' failed at %s:%d with error: %s\n"),
-              "mysql_stmt_execute",
-              __FILE__, __LINE__, mysql_stmt_error (stmt));
-      iclose (dbh);
-      mysql_thread_end ();
-      MUTEX_UNLOCK (lock);
-      if (svalue != NULL)
-        FREE (svalue);
-      return SYSERR;
-    }
-  count = mysql_stmt_affected_rows (stmt);
-  mysql_thread_end ();
-#if DEBUG_MYSQL
-  GE_LOG (ectx,
-          GE_DEBUG | GE_REQUEST | GE_USER,
-          "MySQL DELETE operation affected %d rows.\n", count);
-#endif
-  content_size -= ntohl (value->size);
-  MUTEX_UNLOCK (lock);
-  if (svalue != NULL)
-    FREE (svalue);
-  return count;
-}
-
-/**
  * Update the priority for a particular key
  * in the datastore.
  */
 static int
-update (const HashCode512 * key,
-        const Datastore_Value * value, int delta, cron_t expire)
+update (unsigned long long vkey,
+        int delta, cron_t expire)
 {
-  unsigned long contentSize;
-  unsigned long twenty;
   cron_t start;
+  MYSQL_BIND qbind[4];
 
-  twenty = sizeof (HashCode512);
   MUTEX_LOCK (lock);
   mysql_thread_init ();
   if (OK != CHECK_DBH)
@@ -1324,23 +1233,27 @@
       MUTEX_UNLOCK (lock);
       return SYSERR;
     }
-  contentSize = ntohl (value->size) - sizeof (Datastore_Value);
-  dbh->ubind[0].buffer = (char *) &delta;
-  dbh->ubind[1].buffer = (char *) &expire;
-  dbh->ubind[2].buffer = (char *) &expire;
-  dbh->ubind[3].buffer = (char *) key;
-  dbh->ubind[3].length = &twenty;
-  dbh->ubind[4].buffer = (char *) &value[1];
-  dbh->ubind[4].length = &contentSize;
-  GE_ASSERT (ectx, mysql_stmt_param_count (dbh->update) <= 5);
-  if (mysql_stmt_bind_param (dbh->update, dbh->ubind))
+  memset(qbind, 0, sizeof(qbind));
+  qbind[0].buffer_type = MYSQL_TYPE_LONG;
+  qbind[0].buffer = &delta;
+  qbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[1].buffer = &expire;
+  qbind[1].is_unsigned = YES;
+  qbind[2].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[2].is_unsigned = YES;
+  qbind[2].buffer = &expire; 
+  qbind[3].buffer_type = MYSQL_TYPE_LONGLONG;
+  qbind[3].is_unsigned = YES;
+  qbind[3].buffer = &vkey;
+  GE_ASSERT (ectx, mysql_stmt_param_count (dbh->update_entry) == 4);
+  if (mysql_stmt_bind_param (dbh->update_entry, qbind))
     {
       GE_LOG (ectx,
               GE_ERROR | GE_BULK | GE_USER,
               _("`%s' failed at %s:%d with error: %s\n"),
               "mysql_stmt_bind_param",
-              __FILE__, __LINE__, mysql_stmt_error (dbh->update));
-      iclose (dbh);
+              __FILE__, __LINE__, mysql_stmt_error (dbh->update_entry));
+      iclose ();
       mysql_thread_end ();
       MUTEX_UNLOCK (lock);
       return SYSERR;
@@ -1351,24 +1264,26 @@
    * at all in this context.)
    */
   start = get_time ();
-  if (mysql_stmt_execute (dbh->update))
+  if (mysql_stmt_execute (dbh->update_entry))
     {
       GE_LOG (ectx,
               GE_ERROR | GE_BULK | GE_USER,
               _("`%s' failed at %s:%d with error `%s' after %llums\n"),
               "mysql_stmt_execute",
               __FILE__, __LINE__,
-              mysql_stmt_error (dbh->update), get_time () - start);
-      iclose (dbh);
+              mysql_stmt_error (dbh->update_entry), get_time () - start);
+      iclose ();
       mysql_thread_end ();
       MUTEX_UNLOCK (lock);
       return SYSERR;
     }
+  mysql_stmt_reset(dbh->update_entry);
   mysql_thread_end ();
   MUTEX_UNLOCK (lock);
   return OK;
 }
 
+
 /**
  * Get the current on-disk size of the SQ store.
  * Estimates are fine, if that's the only thing
@@ -1385,7 +1300,7 @@
   if (stats)
     stats->set (stat_size, ret);
   MUTEX_UNLOCK (lock);
-  return ret * 2;               /* common overhead seems to be 100%! */
+  return ret * 2; /* FIXME: measure again! */
 }
 
 /**
@@ -1395,6 +1310,9 @@
 static void
 drop ()
 {
+  int ok;
+
+  ok = YES;
   MUTEX_LOCK (lock);
   mysql_thread_init ();
   if (OK != CHECK_DBH)
@@ -1403,16 +1321,21 @@
       MUTEX_UNLOCK (lock);
       return;
     }
-  mysql_query (dbh->dbf, "DROP TABLE gn070");
+  mysql_query (dbh->dbf, "DROP TABLE gn071");
   if (mysql_error (dbh->dbf)[0])
     {
       LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
-      iclose (dbh);
+      ok = NO;
     }
-  else
+  mysql_query (dbh->dbf, "DROP TABLE gn072");
+  if (mysql_error (dbh->dbf)[0])
     {
-      content_size = 0;
+      LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+      ok = NO;
     }
+  if (ok == YES)    
+      content_size = 0;    
+  iclose();
   mysql_thread_end ();
   MUTEX_UNLOCK (lock);
 }
@@ -1473,8 +1396,9 @@
       fclose (fp);
     }
   dbh = MALLOC (sizeof (mysqlHandle));
+  memset(dbh, 0, sizeof(mysqlHandle));
   dbh->cnffile = cnffile;
-  if (OK != iopen (dbh, YES))
+  if (OK != iopen ())
     {
       FREE (cnffile);
       FREE (dbh);
@@ -1541,7 +1465,6 @@
   api.iterateExpirationTime = &iterateExpirationTime;
   api.iterateMigrationOrder = &iterateMigrationOrder;
   api.iterateAllNow = &iterateAllNow;
-  api.del = &del;
   api.drop = &drop;
   api.update = &update;
   return &api;
@@ -1554,11 +1477,11 @@
 release_module_sqstore_mysql ()
 {
   State_ServiceAPI *state;
+
   iclose (dbh);
   FREE (dbh->cnffile);
   FREE (dbh);
   dbh = NULL;
-
   if (stats != NULL)
     coreAPI->releaseService (stats);
   MUTEX_DESTROY (lock);

Modified: GNUnet/src/applications/sqstore_mysql/mysqltest.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest.c   2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest.c   2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2004, 2005, 2006, 2007 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
@@ -52,7 +52,8 @@
 
 static int
 checkValue (const HashCode512 * key,
-            const Datastore_Value * val, void *closure)
+            const Datastore_Value * val, void *closure,
+           unsigned long long uid)
 {
   int i;
   int ret;
@@ -77,39 +78,49 @@
 }
 
 static int
-iterateUp (const HashCode512 * key, const Datastore_Value * val, int *closure)
+iterateUp (const HashCode512 * key, const Datastore_Value * val, int *closure,
+          unsigned long long uid)
 {
   int ret;
 
-  ret = checkValue (key, val, closure);
+  ret = checkValue (key, val, closure, uid);
   (*closure) += 2;
   return ret;
 }
 
 static int
 iterateDown (const HashCode512 * key,
-             const Datastore_Value * val, int *closure)
+             const Datastore_Value * val, int *closure,
+            unsigned long long uid)
 {
   int ret;
 
   (*closure) -= 2;
-  ret = checkValue (key, val, closure);
+  ret = checkValue (key, val, closure, uid);
   return ret;
 }
 
 static int
 iterateDelete (const HashCode512 * key,
-               const Datastore_Value * val, SQstore_ServiceAPI * api)
+               const Datastore_Value * val, void * closure,
+              unsigned long long uid)
 {
-  if (1 == api->del (key, val))
-    return OK;
-  else
-    return SYSERR;
+  return NO;
 }
 
 static int
+iteratePriority (const HashCode512 * key,
+                const Datastore_Value * val, SQstore_ServiceAPI * api,
+                unsigned long long uid)
+{
+  api->update(uid, 4, 0);
+  return OK;
+}
+
+static int
 priorityCheck (const HashCode512 * key,
-               const Datastore_Value * val, int *closure)
+               const Datastore_Value * val, int *closure,
+              unsigned long long uid)
 {
   int id;
 
@@ -122,7 +133,8 @@
 
 static int
 multipleCheck (const HashCode512 * key,
-               const Datastore_Value * val, Datastore_Value ** last)
+               const Datastore_Value * val, Datastore_Value ** last,
+              unsigned long long uid)
 {
   if (*last != NULL)
     {
@@ -171,7 +183,7 @@
     {
       memset (&key, 256 - i, sizeof (HashCode512));
       value = initValue (i);
-      ASSERT (1 == api->del (&key, value));
+      ASSERT (1 == api->get (&key, 0, &iterateDelete, NULL));
       FREE (value);
     }
   ASSERT (oldSize > api->getSize ());
@@ -197,7 +209,8 @@
   ASSERT (1 == api->iterateExpirationTime (ANY_BLOCK,
                                            (Datum_Iterator) & priorityCheck,
                                            &i));
-  api->update (&key, value, 4, 0);
+  ASSERT (1 == api->iterateAllNow((Datum_Iterator) & iteratePriority,
+                                 api));
   i += 4;
   ASSERT (1 == api->iterateExpirationTime (ANY_BLOCK,
                                            (Datum_Iterator) & priorityCheck,
@@ -214,8 +227,8 @@
                                            (Datum_Iterator) & multipleCheck,
                                            &value));
   FREE (value);
-  api->del (&key, NULL);
-  api->del (&key, NULL);
+  ASSERT (2 == api->iterateAllNow ((Datum_Iterator) & iterateDelete,
+                                  api));
   ASSERT (0 == api->iterateExpirationTime (ANY_BLOCK, NULL, NULL));
   api->drop ();
 

Modified: GNUnet/src/applications/sqstore_mysql/mysqltest2.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest2.c  2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest2.c  2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2004, 2005, 2006, 2007 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
@@ -166,7 +166,8 @@
 
 static int
 iterateDelete (const HashCode512 * key,
-               const Datastore_Value * val, void *cls)
+               const Datastore_Value * val, void *cls,
+              unsigned long long uid)
 {
   SQstore_ServiceAPI *api = cls;
   static int dc;
@@ -180,10 +181,9 @@
   if (dc % REP_FREQ == 0)
     fprintf (stderr, "D");
 #endif
-  GE_ASSERT (NULL, 1 == api->del (key, val));
   stored_bytes -= ntohl (val->size);
   stored_entries--;
-  return OK;
+  return NO;
 }
 
 /**

Modified: GNUnet/src/applications/sqstore_mysql/mysqltest3.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest3.c  2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest3.c  2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -70,6 +70,7 @@
   size = size - (size & 7);     /* always multiple of 8 */
 
   /* generate random key */
+  key.bits[0] = (unsigned int) get_time();
   hash (&key, sizeof (HashCode512), &key);
   value = MALLOC (size);
   value->size = htonl (size);
@@ -94,7 +95,8 @@
 }
 
 static int
-iterateDummy (const HashCode512 * key, const Datastore_Value * val, void *cls)
+iterateDummy (const HashCode512 * key, const Datastore_Value * val, void *cls,
+             unsigned long long uid)
 {
   if (GNUNET_SHUTDOWN_TEST () == YES)
     return SYSERR;
@@ -137,17 +139,19 @@
       if (GNUNET_SHUTDOWN_TEST () == YES)
         break;
       start = get_time ();
-      api->iterateNonAnonymous (0, NO, &iterateDummy, api);
+      api->iterateNonAnonymous (0, &iterateDummy, api);
       end = get_time ();
       printf ("%3u non anonymou iteration took %20llums\n", i, end - start);
       if (GNUNET_SHUTDOWN_TEST () == YES)
         break;
+#if 1
       start = get_time ();
-      api->iterateNonAnonymous (0, YES, &iterateDummy, api);
+      api->iterateNonAnonymous (0, &iterateDummy, api);
       end = get_time ();
       printf ("%3u non anon YES iteration took %20llums\n", i, end - start);
       if (GNUNET_SHUTDOWN_TEST () == YES)
         break;
+#endif
       start = get_time ();
       api->iterateMigrationOrder (&iterateDummy, api);
       end = get_time ();
@@ -161,7 +165,6 @@
       if (GNUNET_SHUTDOWN_TEST () == YES)
         break;
     }
-  api->drop ();
   return OK;
 }
 

Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c     2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c     2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -690,7 +690,7 @@
               count++;
               if (iter != NULL)
                 {
-                  if (SYSERR == iter (&datum->key, &datum->value, closure))
+                  if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
                     {
                       FREE (datum);
                       count = SYSERR;
@@ -743,18 +743,16 @@
  *
  * @param type limit the iteration to entries of this
  *   type. 0 for all entries.
- * @param on_demand limit the iteration to entries
- *        that not on-demand?
- * @param iter the callback method
+  * @param iter the callback method
  * @param closure argument to all callback calls
  * @return the number of results, SYSERR if the
  *   iter is non-NULL and aborted the iteration
  */
 static int
 iterateNonAnonymous (unsigned int type,
-                     int on_demand, Datum_Iterator iter, void *closure)
+                     Datum_Iterator iter, void *closure)
 {
-  return sqlite_iterate (0, iter, closure, NO, NO, NO, YES, on_demand);
+  return sqlite_iterate (0, iter, closure, NO, NO, NO, YES, YES);
 }
 
 /**
@@ -828,7 +826,7 @@
       payload += getContentDatastoreSize (&datum->value);
       if (iter != NULL)
         {
-          if (SYSERR == iter (&datum->key, &datum->value, closure))
+          if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
             {
               FREE (datum);
               count = SYSERR;
@@ -1009,7 +1007,7 @@
                       "Found in database block with type %u.\n",
                       ntohl (*(int *) &((&datum->value)[1])));
 #endif
-              if (SYSERR == iter (&datum->key, &datum->value, closure))
+              if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
                 {
 
                   count = SYSERR;
@@ -1123,137 +1121,12 @@
 }
 
 /**
- * Delete an item from the datastore.
- *
- * @param value maybe NULL, then all items under the
- *        given key are deleted
- * @return the number of items deleted, 0 if
- *        none were found, SYSERR on errors
- */
-static int
-del (const HashCode512 * key, const Datastore_Value * value)
-{
-  size_t n;
-  sqlite3_stmt *stmt;
-  int deleted;
-  sqliteHandle *dbh;
-  Datastore_Datum *dvalue;
-  unsigned int size;
-  unsigned int type;
-  unsigned int prio;
-  unsigned int anon;
-  unsigned long long expir;
-  unsigned long contentSize;
-#if DEBUG_SQLITE
-  EncName enc;
-
-  IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
-  GE_LOG (ectx,
-          GE_DEBUG | GE_REQUEST | GE_USER,
-          "SQLite: deleting block with key `%s'\n", &enc);
-#endif
-
-  dbh = getDBHandle ();
-  if (db->lastSync > 1000)
-    syncStats (dbh);
-
-  if (NULL == value)
-    {
-      if (sq_prepare (dbh->dbh,
-                      "SELECT size, type, prio, anonLevel, expire, hash, value 
"
-                      "FROM gn070 WHERE hash = ? ORDER BY prio ASC",
-                      &stmt) != SQLITE_OK)
-        {
-          LOG_SQLITE (dbh,
-                      GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
-                      "sqlite_query");
-          return SYSERR;
-        }
-      sqlite3_bind_blob (stmt,
-                         1, key, sizeof (HashCode512), SQLITE_TRANSIENT);
-      if (sqlite3_step (stmt) != SQLITE_ROW)
-        {
-          sqlite3_finalize (stmt);
-          return NO;
-        }
-      dvalue = assembleDatum (dbh, stmt);
-      if (dvalue == NULL)
-        {
-          sqlite3_finalize (stmt);
-          return SYSERR;
-        }
-      sqlite3_finalize (stmt);
-      value = &dvalue->value;
-    }
-  else
-    {
-      dvalue = NULL;
-    }
-  contentSize = ntohl (value->size) - sizeof (Datastore_Value);
-  n = sq_prepare (dbh->dbh, "DELETE FROM gn070 WHERE hash = ? and " "value = ? 
AND size = ? AND type = ? AND prio = ? AND anonLevel = ? " "AND expire = ?",    
 /* ORDER BY prio ASC LIMIT 1" -- not available in sqlite */
-                  &stmt);
-  if (n == SQLITE_OK)
-    {
-      size = ntohl (value->size);
-      type = ntohl (value->type);
-      prio = ntohl (value->prio);
-      anon = ntohl (value->anonymityLevel);
-      expir = ntohll (value->expirationTime);
-
-      sqlite3_bind_blob (stmt, 1, key, sizeof (HashCode512),
-                         SQLITE_TRANSIENT);
-      sqlite3_bind_blob (stmt, 2, &value[1], contentSize, SQLITE_TRANSIENT);
-      sqlite3_bind_int (stmt, 3, size);
-      sqlite3_bind_int (stmt, 4, type);
-      sqlite3_bind_int (stmt, 5, prio);
-      sqlite3_bind_int (stmt, 6, anon);
-      sqlite3_bind_int64 (stmt, 7, expir);
-      n = sqlite3_step (stmt);
-      if ((n == SQLITE_DONE) || (n == SQLITE_ROW))
-        db->payload -= getContentDatastoreSize (value);
-    }
-  else
-    {
-      LOG_SQLITE (dbh,
-                  GE_ERROR | GE_ADMIN | GE_USER | GE_BULK, "sqlite3_prepare");
-    }
-  FREENONNULL (dvalue);
-  deleted = ((n == SQLITE_DONE)
-             || (n == SQLITE_ROW)) ? sqlite3_changes (dbh->dbh) : SYSERR;
-  sqlite3_finalize (stmt);
-
-  if (n != SQLITE_DONE)
-    {
-      if (n != SQLITE_BUSY)
-        {
-          LOG_SQLITE (dbh,
-                      GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
-                      "sqlite_query");
-          return SYSERR;
-        }
-      else
-        {
-          return NO;
-        }
-    }
-  db->lastSync++;
-
-#if DEBUG_SQLITE
-  GE_LOG (ectx,
-          GE_DEBUG | GE_REQUEST | GE_USER,
-          "SQLite: %d block(s) deleted\n", deleted);
-#endif
-
-  return deleted;
-}
-
-/**
  * Update the priority for a particular key
  * in the datastore.
  */
 static int
-update (const HashCode512 * key,
-        const Datastore_Value * value, int delta, cron_t expire)
+update (unsigned long long uid,
+        int delta, cron_t expire)
 {
   int n;
   unsigned long contentSize;

Modified: GNUnet/src/include/gnunet_datastore_service.h
===================================================================
--- GNUnet/src/include/gnunet_datastore_service.h       2007-07-21 07:21:17 UTC 
(rev 5327)
+++ GNUnet/src/include/gnunet_datastore_service.h       2007-07-22 01:56:14 UTC 
(rev 5328)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2004, 2005, 2006, 2007 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
@@ -84,33 +84,18 @@
 } Datastore_Value;
 
 /**
- * An entry (key-value pair) in the datastore.
- */
-typedef struct
-{
-
-  /**
-   * A key (not unique) that can be used to lookup this Datum in the
-   * datastore.
-   */
-  HashCode512 key;
-
-  /**
-   * The value associated with the key.
-   */
-  Datastore_Value value;
-
-} Datastore_Datum;
-
-/**
  * An iterator over a set of Datastore items.
  *
  * @param datum called with the next item
  * @param closure user-defined extra argument
- * @return SYSERR to abort the iteration, OK to continue.
+ * @param uid unique identifier for the datum
+ *
+ * @return SYSERR to abort the iteration, OK to continue,
+ *         NO to delete the item and continue (if supported)
  */
 typedef int (*Datum_Iterator) (const HashCode512 * key,
-                               const Datastore_Value * value, void *closure);
+                               const Datastore_Value * value, void *closure,
+                              unsigned long long uid);
 
 
 /**
@@ -200,16 +185,6 @@
                     HashCode512 * key,
                     Datastore_Value ** value, unsigned int type);
 
-  /**
-   * Delete an item from the datastore.
-   *
-   * @param value maybe NULL, then all items under the
-   *         given key are deleted
-   * @return the number of items deleted, 0 if
-   *         none were found, SYSERR on errors
-   */
-  int (*del) (const HashCode512 * key, const Datastore_Value * value);
-
 } Datastore_ServiceAPI;
 
 #if 0                           /* keep Emacsens' auto-indent happy */

Modified: GNUnet/src/include/gnunet_sqstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_sqstore_service.h 2007-07-21 07:21:17 UTC (rev 
5327)
+++ GNUnet/src/include/gnunet_sqstore_service.h 2007-07-22 01:56:14 UTC (rev 
5328)
@@ -91,10 +91,7 @@
    * Note that it is possible for multiple values to match this put.
    * In that case, all of the respective values are updated.
    *
-   * @param key never NULL
-   * @param value the value to update (priority
-   *     maybe different than in DB, only match
-   *     on content and use other data as in DB!)
+   * @param uid unique identifier of the datum
    * @param delta by how much should the priority
    *     change?  If priority + delta < 0 the
    *     priority should be set to 0 (never go
@@ -105,8 +102,7 @@
    * @return OK if a match was found and the update
    *     was successful, SYSERR on error
    */
-  int (*update) (const HashCode512 * key,
-                 const Datastore_Value * value, int delta, cron_t expire);
+  int (*update) (unsigned long long uid, int delta, cron_t expire);
 
   /**
    * Iterate over the items in the datastore in ascending
@@ -126,14 +122,11 @@
    *
    * @param type entries of which type should be considered?
    *        Use 0 for any type.
-   * @param on_demand limit the iteration to entries
-   *        that not on-demand?
    * @param iter never NULL
    * @return the number of results, SYSERR if the
    *   iter is non-NULL and aborted the iteration
    */
   int (*iterateNonAnonymous) (unsigned int type,
-                              int on_demand,
                               Datum_Iterator iter, void *closure);
 
   /**
@@ -173,32 +166,6 @@
   int (*iterateAllNow) (Datum_Iterator iter, void *closure);
 
   /**
-   * Delete an item from the datastore.
-   *
-   * Note that it is possible for multiple values to match this del
-   * (even if a value is given).  In that case, only ONE of the
-   * respective values is deleted, and it should be the one with an
-   * expired expiration time or, if such an entry does not exist, the
-   * lowest priority.  (This is done such that if multiple files
-   * contain the same data, the data has multiple replicas and all are
-   * kept, avoiding unavaialbility if just one of the files is
-   * removed).
-   *
-   * @param value maybe NULL, then all items under the
-   *        given key are deleted
-   * @return the number of items deleted (if possible, the
-   *        database should delete only ONE matching item and
-   *        pick the one with the lowest priority [and then
-   *        lowest expiration time]; if the DB cannot do that,
-   *        deleting multiple entries will be 'tolerated' for now,
-   *        but the result is a slightly worse performance of the
-   *        peer; however, that there are multiple matches should
-   *        also be rare).
-   *        0 if no matching items were found, SYSERR on errors
-   */
-  int (*del) (const HashCode512 * key, const Datastore_Value * value);
-
-  /**
    * Delete the database.  The next operation is
    * guaranteed to be unloading of the module.
    */





reply via email to

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