gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r5718 - GNUnet/src/applications/sqstore_sqlite


From: gnunet
Subject: [GNUnet-SVN] r5718 - GNUnet/src/applications/sqstore_sqlite
Date: Sat, 20 Oct 2007 08:41:09 -0600 (MDT)

Author: durner
Date: 2007-10-20 08:41:09 -0600 (Sat, 20 Oct 2007)
New Revision: 5718

Modified:
   GNUnet/src/applications/sqstore_sqlite/sqlite.c
Log:
make better use of indexes (same as in r5716 without win32 line endings)

Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c     2007-10-20 14:39:28 UTC 
(rev 5717)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c     2007-10-20 14:41:09 UTC 
(rev 5718)
@@ -53,6 +53,41 @@
  */
 #define LOG_SQLITE(db, level, cmd) do { GE_LOG(ectx, level, _("`%s' failed at 
%s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } 
while(0)
 
+/* These selects basically work in the same way as the old MySQL selects do. 
But because the
+   reverse ordering kills performance, we are using subselects with MAX() for 
SQLite instead.
+
+#define SELECT_IT_NON_ANONYMOUS "SELECT size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 WHERE ( (prio = ? AND hash < ?) OR (prio < ? 
AND hash != ?) ) "\
+                                "AND anonLevel=0 AND type not in (4294967294, 
4294967295) "\
+                                "ORDER BY prio DESC,hash DESC LIMIT 1"
+
+#define SELECT_IT_MIGRATION_ORDER "SELECT size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 WHERE ( (expire = ? AND hash < ?) OR (expire < 
? AND hash != ?) ) "\
+                                  "AND expire > ? AND type!=3 "\
+                                  "ORDER BY expire DESC,hash DESC LIMIT 1" 
+*/
+
+#define SELECT_IT_LOW_PRIORITY "SELECT size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 WHERE " \
+  "((prio = ? AND hash > ?) OR (prio > ? AND hash != ?)) AND type not in 
(4294967294, 4294967295, 3) ORDER BY " \
+  "prio ASC,hash ASC LIMIT 1"
+
+#define SELECT_IT_NON_ANONYMOUS  "SELECT size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 " \
+  "WHERE hash = " \
+    "(SELECT MAX(hash) FROM gn070 WHERE prio = " \
+      "(SELECT MAX(prio) FROM gn070 WHERE ((prio = ? AND hash < ?) OR (prio < 
? AND hash != ?)) AND anonLevel=0 AND " \
+        "type NOT IN (4294967294, 4294967295, 3)) " \
+      "AND ((prio = ? AND hash < ?) OR (prio < ? AND hash != ?)) AND 
anonLevel=0 AND type NOT IN (4294967294, " \
+      "4294967295, 3))"
+
+#define SELECT_IT_EXPIRATION_TIME "SELECT size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 WHERE " \
+  "((expire = ? AND hash > ?) OR (expire > ? AND hash != ?)) AND type NOT IN 
(4294967294, 4294967295, 3) ORDER BY " \
+  "expire ASC,hash ASC LIMIT 1"
+
+#define SELECT_IT_MIGRATION_ORDER "Select size, type, prio, anonLevel, expire, 
hash, value, _ROWID_ FROM gn070 WHERE " \
+  "hash =" \
+    "(Select MAX(hash) FROM gn070 WHERE expire =" \
+        "(Select MAX(expire) FROM gn070 WHERE ((expire = ? AND hash < ?) OR 
(expire < ? AND hash != ?)) AND " \
+        "type NOT IN (4294967294, 4294967295, 3)) " \
+    "and type not in (4294967294, 4294967295, 3) and ((expire = ? and hash < 
?) or (expire < ? and hash != ?)))"
+
 /**
  * After how many ms "busy" should a DB operation fail for good?
  * A low value makes sure that we are more responsive to requests
@@ -151,14 +186,24 @@
          sqlite3_exec (dbh,
                        "CREATE INDEX idx_expire ON gn070 (expire)",
                        NULL, NULL, ENULL));
+  sqlite3_exec (dbh, "DROP INDEX idx_comb1", NULL, NULL, ENULL);
+  sqlite3_exec (dbh, "DROP INDEX idx_comb2", NULL, NULL, ENULL);
   CHECK (SQLITE_OK ==
          sqlite3_exec (dbh,
-                       "CREATE INDEX idx_comb1 ON gn070 (prio,expire,hash)",
+                       "CREATE INDEX idx_comb3 ON gn070 (expire,type,hash)",
                        NULL, NULL, ENULL));
   CHECK (SQLITE_OK ==
          sqlite3_exec (dbh,
-                       "CREATE INDEX idx_comb2 ON gn070 (expire,prio,hash)",
+                       "CREATE INDEX idx_comb4 ON gn070 
(anonLevel,type,prio,hash)",
                        NULL, NULL, ENULL));
+  CHECK (SQLITE_OK ==
+         sqlite3_exec (dbh,
+                       "CREATE INDEX idx_comb5 ON gn070 (expire,type,hash)",
+                       NULL, NULL, ENULL));
+  CHECK (SQLITE_OK ==
+         sqlite3_exec (dbh,
+                       "CREATE INDEX idx_comb6 ON gn070 (prio,type,hash)",
+                       NULL, NULL, ENULL));
 }
 
 /**
@@ -588,16 +633,15 @@
  */
 static int
 sqlite_iterate (unsigned int type,
-                Datum_Iterator iter,
-                void *closure,
-                int sortByPriority,
-                int inverseOrder,
-                int include_expired,
-                int limit_nonanonymous, int limit_ondemand)
+                int is_asc,
+                int is_prio,
+                int is_migr,
+                int limit_nonanonymous,
+                unsigned int iter_select, Datum_Iterator iter, void *closure)
 {
   sqlite3_stmt *stmt;
   int count;
-  char scratch[512];
+  char *stmt_str;
   Datastore_Value *datum;
   unsigned int lastPrio;
   unsigned long long lastExp;
@@ -611,121 +655,98 @@
   MUTEX_LOCK (lock);
   handle = getDBHandle ();
   dbh = handle->dbh;
-  /* For the rowid trick see
-     http://permalink.gmane.org/gmane.network.gnunet.devel/1363 */
-  strcpy (scratch,
-          "SELECT size, type, prio, anonLevel, expire, hash, value, _ROWID_ 
FROM gn070"
-          " WHERE rowid IN (SELECT rowid FROM gn070"
-          " WHERE ((hash > :1 AND expire == :2 AND prio == :3) OR ");
-  if (sortByPriority)
+
+  switch (iter_select)
     {
-      if (inverseOrder)
-        strcat (scratch, "(expire < :4 AND prio == :5) OR prio < :6)");
-      else
-        strcat (scratch, "(expire > :4 AND prio == :5) OR prio > :6)");
+    case 0:
+      stmt_str = SELECT_IT_LOW_PRIORITY;
+      break;
+    case 1:
+      stmt_str = SELECT_IT_NON_ANONYMOUS;
+      break;
+    case 2:
+      stmt_str = SELECT_IT_EXPIRATION_TIME;
+      break;
+    case 3:
+      stmt_str = SELECT_IT_MIGRATION_ORDER;
+      break;
+    default:
+      GE_BREAK (NULL, 0);
+      return SYSERR;
     }
-  else
+
+  if (sq_prepare (dbh, stmt_str, &stmt) != SQLITE_OK)
     {
-      if (inverseOrder)
-        strcat (scratch, "(prio < :4 AND expire == :5) OR expire < :6)");
-      else
-        strcat (scratch, "(prio > :4 AND expire == :5) OR expire > :6)");
-    }
-  if (type != 0)
-    {
-      strcat (scratch, " AND type = :7");
-    }
-  else if (limit_ondemand == YES)
-    {
-      SNPRINTF (&scratch[strlen (scratch)],
-                512 - strlen (scratch),
-                " AND type != %d AND type != %d",
-                RESERVED_BLOCK, ONDEMAND_BLOCK);
-    }
-  else
-    {
-      SNPRINTF (&scratch[strlen (scratch)], 512 - strlen (scratch), " AND type 
!= %d", RESERVED_BLOCK); /* otherwise we iterate over
-                                                                               
                            the stats entry, which would
-                                                                               
                            be bad */
-    }
-  if (NO == include_expired)
-    {
-      if (type != 0)
-        strcat (scratch, " AND expire > :8");
-      else
-        strcat (scratch, " AND expire > :7");
-    }
-  if (sortByPriority)
-    {
-      if (inverseOrder)
-        strcat (scratch, " ORDER BY prio DESC, expire DESC, hash ASC");
-      else
-        strcat (scratch, " ORDER BY prio ASC, expire ASC, hash ASC");
-    }
-  else
-    {
-      if (inverseOrder)
-        strcat (scratch, " ORDER BY expire DESC, prio DESC, hash ASC");
-      else
-        strcat (scratch, " ORDER BY expire ASC, prio ASC, hash ASC");
-    }
-  strcat (scratch, " LIMIT 1)");
-  if (sq_prepare (dbh, scratch, &stmt) != SQLITE_OK)
-    {
       LOG_SQLITE (handle,
                   GE_ERROR | GE_ADMIN | GE_USER | GE_BULK, "sqlite3_prepare");
       MUTEX_UNLOCK (lock);
       return SYSERR;
     }
   count = 0;
-  if (inverseOrder)
+  if (is_asc)
     {
-      lastPrio = 0x7FFFFFFF;
-      lastExp = 0x7FFFFFFFFFFFFFFFLL;
+      lastPrio = 0;
+      lastExp = 0;
+      memset (&key, 0, sizeof (HashCode512));
     }
   else
     {
-      lastPrio = 0;
-      lastExp = 0;
+      lastPrio = 0x7FFFFFFF;
+      lastExp = 0x7FFFFFFFFFFFFFFFLL;
+      memset (&key, 255, sizeof (HashCode512));
     }
-  memset (&key, 0, sizeof (HashCode512));
   while (1)
     {
-      sqlite3_bind_blob (stmt,
-                         1, &key, sizeof (HashCode512), SQLITE_TRANSIENT);
-      sqlite3_bind_int64 (stmt, 2, lastExp);
-      sqlite3_bind_int (stmt, 3, lastPrio);
-      if (sortByPriority)
+      if (is_prio)
         {
-          sqlite3_bind_int64 (stmt, 4, lastExp);
-          sqlite3_bind_int (stmt, 5, lastPrio);
-          sqlite3_bind_int (stmt, 6, lastPrio);
+          sqlite3_bind_int (stmt, 1, lastPrio);
+          sqlite3_bind_int (stmt, 3, lastPrio);
         }
       else
         {
-          sqlite3_bind_int64 (stmt, 4, lastExp);
-          sqlite3_bind_int (stmt, 5, lastPrio);
-          sqlite3_bind_int64 (stmt, 6, lastExp);
+          sqlite3_bind_int64 (stmt, 1, lastExp);
+          sqlite3_bind_int64 (stmt, 3, lastExp);
         }
-      if (type)
-        sqlite3_bind_int (stmt, 7, type);
-      if (NO == include_expired)
+
+      sqlite3_bind_blob (stmt, 2, &key, sizeof (HashCode512),
+                         SQLITE_TRANSIENT);
+      sqlite3_bind_blob (stmt, 4, &key, sizeof (HashCode512),
+                         SQLITE_TRANSIENT);
+      now = get_time ();
+
+      if (is_migr)
         {
-          now = get_time ();
-          if (type)
-            sqlite3_bind_int64 (stmt, 8, now);
-          else
-            sqlite3_bind_int64 (stmt, 7, now);
+          sqlite3_bind_int64 (stmt, 5, lastExp);
+          sqlite3_bind_blob (stmt, 6, &key, sizeof (HashCode512),
+                             SQLITE_TRANSIENT);
+
+          sqlite3_bind_int64 (stmt, 7, lastExp);
+          sqlite3_bind_blob (stmt, 8, &key, sizeof (HashCode512),
+                             SQLITE_TRANSIENT);
         }
+      else if (limit_nonanonymous)
+        {
+          sqlite3_bind_int (stmt, 5, lastPrio);
+          sqlite3_bind_blob (stmt, 6, &key, sizeof (HashCode512),
+                             SQLITE_TRANSIENT);
+
+          sqlite3_bind_int (stmt, 7, lastPrio);
+          sqlite3_bind_blob (stmt, 8, &key, sizeof (HashCode512),
+                             SQLITE_TRANSIENT);
+        }
+
       if ((ret = sqlite3_step (stmt)) == SQLITE_ROW)
         {
-          datum = assembleDatum (handle, stmt, &key, &rowid);
+          if (sqlite3_column_int64 (stmt, 4) < now)
+            datum = NULL;
+          else
+            datum = assembleDatum (handle, stmt, &key, &rowid);
           if (SQLITE_OK != sqlite3_reset (stmt))
             LOG_SQLITE (handle,
                         GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
                         "sqlite3_reset");
           if (datum == NULL)
-            continue;
+            break;
 #if 0
           printf ("FOUND %4u prio %4u exp %20llu old: %4u, %20llu\n",
                   (ntohl (datum->size) - sizeof (Datastore_Value)),
@@ -792,7 +813,7 @@
 static int
 iterateLowPriority (unsigned int type, Datum_Iterator iter, void *closure)
 {
-  return sqlite_iterate (type, iter, closure, YES, NO, YES, NO, NO);
+  return sqlite_iterate (type, YES, YES, NO, NO, 0, iter, closure);
 }
 
 /**
@@ -808,7 +829,7 @@
 static int
 iterateNonAnonymous (unsigned int type, Datum_Iterator iter, void *closure)
 {
-  return sqlite_iterate (0, iter, closure, NO, NO, NO, YES, YES);
+  return sqlite_iterate (type, NO, YES, NO, YES, 1, iter, closure);
 }
 
 /**
@@ -823,7 +844,7 @@
 static int
 iterateExpirationTime (unsigned int type, Datum_Iterator iter, void *closure)
 {
-  return sqlite_iterate (type, iter, closure, NO, NO, YES, NO, NO);
+  return sqlite_iterate (type, YES, NO, NO, NO, 2, iter, closure);
 }
 
 /**
@@ -837,7 +858,7 @@
 static int
 iterateMigrationOrder (Datum_Iterator iter, void *closure)
 {
-  return sqlite_iterate (0, iter, closure, NO, YES, NO, NO, NO);
+  return sqlite_iterate (0, NO, NO, YES, NO, 3, iter, closure);
 }
 
 /**





reply via email to

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