]> spindle.queued.net Git - midori/commitdiff
Store the 'day' of history items to reduce even more calls to localtime
authorDale Whittaker <dayul@users.sf.net>
Fri, 23 Jan 2009 21:38:39 +0000 (22:38 +0100)
committerChristian Dywan <christian@twotoasts.de>
Fri, 23 Jan 2009 21:38:39 +0000 (22:38 +0100)
By storing the timestamp of the day in the database we can significantly
reduce the calls to localtime, which should result in a noticible
speedup.

We are changing the database format. For the convenience of the user
the code automatically converts from the old format.

midori/main.c
midori/midori-browser.c
midori/sokoke.c
midori/sokoke.h

index 31efc1cab892b673adf778775ea1fd6c5665d299..6d0fe3b1003856c6a54a3073ba2d71d229cf972f 100644 (file)
@@ -716,10 +716,11 @@ midori_history_add_item_cb (KatzeArray* array,
         }
     }
     sqlcmd = sqlite3_mprintf ("INSERT INTO history VALUES"
-                              "('%q', '%q', %" G_GUINT64_FORMAT ", -1)",
+                              "('%q', '%q', %" G_GUINT64_FORMAT ", %" G_GUINT64_FORMAT ")",
                               katze_item_get_uri (item),
                               katze_item_get_name (item),
-                              katze_item_get_added (item));
+                              katze_item_get_added (item),
+                              katze_item_get_added (KATZE_ITEM (array)));
     success = db_exec (db, sqlcmd, &error);
     sqlite3_free (sqlcmd);
     if (!success)
@@ -737,13 +738,17 @@ midori_history_add_items (void*  data,
                           char** colname)
 {
     KatzeItem* item;
-    KatzeArray* parent = NULL;
-    KatzeArray* array = KATZE_ARRAY (data);
+    KatzeArray* parent;
+    KatzeArray* array;
     gint64 date;
+    gint64 day;
     gint i;
-    gint ncols = 3;
+    gint j;
+    gint n;
+    gint ncols = 4;
     gchar token[50];
 
+    array = KATZE_ARRAY (data);
     g_return_val_if_fail (KATZE_IS_ARRAY (array), 1);
 
     /* Test whether have the right number of columns */
@@ -755,22 +760,29 @@ midori_history_add_items (void*  data,
         {
             if (colname[i] && !g_ascii_strcasecmp (colname[i], "uri") &&
                 colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "title") &&
-                colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "date"))
+                colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "date") &&
+                colname[i + 3] && !g_ascii_strcasecmp (colname[i + 3], "day"))
             {
                 item = katze_item_new ();
                 katze_item_set_uri (item, argv[i]);
                 katze_item_set_name (item, argv[i + 1]);
                 date = g_ascii_strtoull (argv[i + 2], NULL, 10);
+                day = g_ascii_strtoull (argv[i + 3], NULL, 10);
                 katze_item_set_added (item, date);
 
-                strftime (token, sizeof (token), "%Y-%m-%d",
-                          localtime ((time_t *)&date));
-                parent = katze_array_find_token (array, token);
-
-                if (!parent)
+                n = katze_array_get_length (array);
+                for (j = n - 1; j >= 0; j--)
+                {
+                    parent = katze_array_get_nth_item (array, j);
+                    if (day == katze_item_get_added (KATZE_ITEM (parent)))
+                        break;
+                }
+                if (j < 0)
                 {
                     parent = katze_array_new (KATZE_TYPE_ARRAY);
-                    katze_item_set_added (KATZE_ITEM (parent), date);
+                    katze_item_set_added (KATZE_ITEM (parent), day);
+                    strftime (token, sizeof (token), "%Y-%m-%d",
+                          localtime ((time_t *)&date));
                     katze_item_set_token (KATZE_ITEM (parent), token);
                     katze_array_add_item (array, parent);
                 }
@@ -781,6 +793,31 @@ midori_history_add_items (void*  data,
     return 0;
 }
 
+static int
+midori_history_test_day_column (void*  data,
+                                int    argc,
+                                char** argv,
+                                char** colname)
+{
+    gint i;
+    gboolean* has_day;
+
+    has_day = (gboolean*)data;
+
+    for (i = 0; i < argc; i++)
+    {
+        if (argv[i] &&
+            !g_ascii_strcasecmp (colname[i], "name") &&
+            !g_ascii_strcasecmp (argv[i], "day"))
+        {
+            *has_day = TRUE;
+            break;
+        }
+    }
+
+    return 0;
+}
+
 static sqlite3*
 midori_history_initialize (KatzeArray*  array,
                            const gchar* filename,
@@ -789,18 +826,45 @@ midori_history_initialize (KatzeArray*  array,
     sqlite3* db;
     KatzeItem* item;
     gint i, n;
+    gboolean has_day;
+
+    has_day = FALSE;
 
     if ((db = db_open (filename, error)) == NULL)
         return db;
 
     if (!db_exec (db,
                   "CREATE TABLE IF NOT EXISTS "
-                  "history(uri text, title text, date integer, visits integer)",
+                  "history(uri text, title text, date integer, day integer)",
                   error))
         return NULL;
 
     if (!db_exec_callback (db,
-                           "SELECT uri, title, date FROM history "
+                           "PRAGMA table_info(history)",
+                           midori_history_test_day_column,
+                           &has_day, error))
+        return NULL;
+
+    if (!has_day)
+    {
+        if (!db_exec (db,
+                      "BEGIN TRANSACTION;"
+                      "CREATE TEMPORARY TABLE backup (uri text, title text, date integer);"
+                      "INSERT INTO backup SELECT uri,title,date FROM history;"
+                      "DROP TABLE history;"
+                      "CREATE TABLE history (uri text, title text, date integer, day integer);"
+                      "INSERT INTO history SELECT uri,title,date,"
+                      "julianday(date(date,'unixepoch','start of day','+1 day'))"
+                      " - julianday('0001-01-01','start of day')"
+                      "FROM backup;"
+                      "DROP TABLE backup;"
+                      "COMMIT;",
+                      error))
+        return NULL;
+    }
+
+    if (!db_exec_callback (db,
+                           "SELECT uri, title, date, day FROM history "
                            "ORDER BY date ASC",
                            midori_history_add_items,
                            array,
index 222101e8a5e17f033817ba0853685d9c44ff6b16..256621ceca947f8be77e0d2ee5983eb286da4f87 100644 (file)
@@ -3623,25 +3623,24 @@ midori_browser_entry_clear_icon_released_cb (GtkIconEntry* entry,
 static void
 _tree_store_insert_history_item (GtkTreeStore* treestore,
                                  GtkTreeIter*  parent,
-                                 KatzeItem*    item)
+                                 KatzeItem*    item,
+                                 gint64        day)
 {
     GtkTreeIter iter;
     KatzeItem* child;
     guint i, n;
     GtkTreeIter* piter;
-    time_t now;
-    gint64 date;
-    gint age = -1;
+    gint64 pday;
+    gint64 age = -1;
 
     g_return_if_fail (KATZE_IS_ITEM (item));
 
     if (KATZE_IS_ARRAY (item))
     {
         piter = parent;
-        if ((date = katze_item_get_added (item)))
+        if ((pday = katze_item_get_added (item)))
         {
-            now = time (NULL);
-            age = sokoke_days_between ((time_t *)&date, (time_t *)&now);
+            age = day - pday;
             gtk_tree_store_insert_with_values (treestore, &iter, parent,
                                                0, 0, item, 1, age, -1);
             g_object_unref (item);
@@ -3651,7 +3650,7 @@ _tree_store_insert_history_item (GtkTreeStore* treestore,
         for (i = 0; i < n; i++)
         {
             child = katze_array_get_nth_item (KATZE_ARRAY (item), i);
-            _tree_store_insert_history_item (treestore, piter, child);
+            _tree_store_insert_history_item (treestore, piter, child, day);
         }
     }
     else
@@ -3673,10 +3672,10 @@ midori_browser_new_history_item (MidoriBrowser* browser,
     gint i;
     gboolean found;
     time_t now;
-    gint64 date;
-    time_t date_;
-    gint age;
-    gint newage;
+    gint64 day;
+    gint64 pday;
+    gint64 age;
+    gint64 newage;
     gchar token[50];
 
     if (!katze_object_get_boolean (browser->settings, "remember-last-visited-pages"))
@@ -3687,20 +3686,20 @@ midori_browser_new_history_item (MidoriBrowser* browser,
 
     now = time (NULL);
     katze_item_set_added (item, now);
+    day = sokoke_time_t_to_julian (&now);
 
     found = FALSE;
     i = 0;
     while (gtk_tree_model_iter_nth_child (treemodel, &iter, NULL, i++))
     {
         gtk_tree_model_get (treemodel, &iter, 0, &parent, 1, &age, -1);
-        date = katze_item_get_added (KATZE_ITEM (parent));
-        date_ = (time_t)date;
-        newage = sokoke_days_between ((time_t *)&date, (time_t *)&now);
+        pday = katze_item_get_added (KATZE_ITEM (parent));
+        newage = day - pday;
         if (newage == 0)
         {
             found = TRUE;
             _tree_store_insert_history_item (GTK_TREE_STORE (treemodel),
-                                             &iter, item);
+                                             &iter, item, day);
             katze_array_add_item (parent, item);
         }
         if (age != newage)
@@ -3712,12 +3711,12 @@ midori_browser_new_history_item (MidoriBrowser* browser,
     {
         strftime (token, sizeof (token), "%Y-%m-%d", localtime (&now));
         parent = katze_array_new (KATZE_TYPE_ARRAY);
-        katze_item_set_added (KATZE_ITEM (parent), now);
+        katze_item_set_added (KATZE_ITEM (parent), day);
         katze_item_set_token (KATZE_ITEM (parent), token);
         katze_array_add_item (browser->history, parent);
         katze_array_add_item (parent, item);
         _tree_store_insert_history_item (GTK_TREE_STORE (treemodel), NULL,
-                                         KATZE_ITEM (parent));
+                                         KATZE_ITEM (parent), day);
     }
 }
 
@@ -3773,6 +3772,8 @@ midori_browser_set_history (MidoriBrowser* browser,
     GtkTreeView* treeview;
     GtkTreeModel* treemodel;
     GtkAction* action;
+    time_t now;
+    gint64 day;
 
     if (browser->history == history)
         return;
@@ -3796,10 +3797,13 @@ midori_browser_set_history (MidoriBrowser* browser,
     g_signal_connect (browser->history, "clear",
                       G_CALLBACK (midori_browser_history_clear_cb), browser);
 
+    now = time (NULL);
+    day = sokoke_time_t_to_julian (&now);
+
     treeview = GTK_TREE_VIEW (browser->panel_history);
     treemodel = gtk_tree_view_get_model (treeview);
-    _tree_store_insert_history_item (GTK_TREE_STORE (treemodel),
-                                     NULL, KATZE_ITEM (browser->history));
+    _tree_store_insert_history_item (GTK_TREE_STORE (treemodel), NULL,
+                                     KATZE_ITEM (browser->history), day);
 
     action = _action_by_name (browser, "Location");
     midori_location_action_freeze (MIDORI_LOCATION_ACTION (action));
index e0f29b9704d53ff3b8d920fa5c59ee995a4982e1..3aa80561ae55f79131f5240f17595047aa2c08f9 100644 (file)
@@ -663,32 +663,25 @@ sokoke_tree_view_get_selected_iter (GtkTreeView*   tree_view,
 }
 
 /**
- * sokoke_days_between:
- * @day1: a time_t timestamp value
- * @day2: a time_t timestamp value
+ * sokoke_time_t_to_julian:
+ * @timestamp: a time_t timestamp value
  *
- * Calculates the number of days between two timestamps.
+ * Calculates a unix timestamp to a julian day value.
  *
  * Return value: an integer.
  **/
-gint
-sokoke_days_between (const time_t* day1,
-                     const time_t* day2)
+gint64
+sokoke_time_t_to_julian (const time_t* timestamp)
 {
-    GDate* date1;
-    GDate* date2;
-    gint age;
-
-    date1 = g_date_new ();
-    date2 = g_date_new ();
+    GDate* date;
+    gint64 julian;
 
-    g_date_set_time_t (date1, *day1);
-    g_date_set_time_t (date2, *day2);
+    date = g_date_new ();
 
-    age = g_date_days_between (date1, date2);
+    g_date_set_time_t (date, *timestamp);
+    julian = (gint64)g_date_get_julian (date);
 
-    g_date_free (date1);
-    g_date_free (date2);
+    g_date_free (date);
 
-    return age;
+    return julian;
 }
index 578e04cee0032844ad34ef62b9b963b4a248bc37..3f1fbb3050cd38dac8662c401c542ffb52d46b06 100644 (file)
@@ -126,8 +126,7 @@ sokoke_tree_view_get_selected_iter   (GtkTreeView*   tree_view,
                                       GtkTreeModel** model,
                                       GtkTreeIter*   iter);
 
-gint
-sokoke_days_between                  (const time_t*  day1,
-                                      const time_t*  day2);
+gint64
+sokoke_time_t_to_julian              (const time_t*  timestamp);
 
 #endif /* !__SOKOKE_H__ */