From fb2a962ad4d4a0976307e532cfe16316fde8dbcc Mon Sep 17 00:00:00 2001 From: Dale Whittaker Date: Fri, 23 Jan 2009 22:38:39 +0100 Subject: [PATCH] Store the 'day' of history items to reduce even more calls to localtime 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 | 92 ++++++++++++++++++++++++++++++++++------- midori/midori-browser.c | 44 +++++++++++--------- midori/sokoke.c | 31 ++++++-------- midori/sokoke.h | 5 +-- 4 files changed, 116 insertions(+), 56 deletions(-) diff --git a/midori/main.c b/midori/main.c index 31efc1ca..6d0fe3b1 100644 --- a/midori/main.c +++ b/midori/main.c @@ -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, diff --git a/midori/midori-browser.c b/midori/midori-browser.c index 222101e8..256621ce 100644 --- a/midori/midori-browser.c +++ b/midori/midori-browser.c @@ -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)); diff --git a/midori/sokoke.c b/midori/sokoke.c index e0f29b97..3aa80561 100644 --- a/midori/sokoke.c +++ b/midori/sokoke.c @@ -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; + GDate* date; + gint64 julian; - date1 = g_date_new (); - date2 = g_date_new (); + date = g_date_new (); - g_date_set_time_t (date1, *day1); - g_date_set_time_t (date2, *day2); + g_date_set_time_t (date, *timestamp); + julian = (gint64)g_date_get_julian (date); - age = g_date_days_between (date1, date2); + g_date_free (date); - g_date_free (date1); - g_date_free (date2); - - return age; + return julian; } diff --git a/midori/sokoke.h b/midori/sokoke.h index 578e04ce..3f1fbb30 100644 --- a/midori/sokoke.h +++ b/midori/sokoke.h @@ -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__ */