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.
This commit is contained in:
Dale Whittaker 2009-01-23 22:38:39 +01:00 committed by Christian Dywan
parent 5b5e6bd71a
commit fb2a962ad4
4 changed files with 116 additions and 56 deletions

View file

@ -716,10 +716,11 @@ midori_history_add_item_cb (KatzeArray* array,
} }
} }
sqlcmd = sqlite3_mprintf ("INSERT INTO history VALUES" 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_uri (item),
katze_item_get_name (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); success = db_exec (db, sqlcmd, &error);
sqlite3_free (sqlcmd); sqlite3_free (sqlcmd);
if (!success) if (!success)
@ -737,13 +738,17 @@ midori_history_add_items (void* data,
char** colname) char** colname)
{ {
KatzeItem* item; KatzeItem* item;
KatzeArray* parent = NULL; KatzeArray* parent;
KatzeArray* array = KATZE_ARRAY (data); KatzeArray* array;
gint64 date; gint64 date;
gint64 day;
gint i; gint i;
gint ncols = 3; gint j;
gint n;
gint ncols = 4;
gchar token[50]; gchar token[50];
array = KATZE_ARRAY (data);
g_return_val_if_fail (KATZE_IS_ARRAY (array), 1); g_return_val_if_fail (KATZE_IS_ARRAY (array), 1);
/* Test whether have the right number of columns */ /* 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") && if (colname[i] && !g_ascii_strcasecmp (colname[i], "uri") &&
colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "title") && 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 (); item = katze_item_new ();
katze_item_set_uri (item, argv[i]); katze_item_set_uri (item, argv[i]);
katze_item_set_name (item, argv[i + 1]); katze_item_set_name (item, argv[i + 1]);
date = g_ascii_strtoull (argv[i + 2], NULL, 10); date = g_ascii_strtoull (argv[i + 2], NULL, 10);
day = g_ascii_strtoull (argv[i + 3], NULL, 10);
katze_item_set_added (item, date); katze_item_set_added (item, date);
strftime (token, sizeof (token), "%Y-%m-%d", n = katze_array_get_length (array);
localtime ((time_t *)&date)); for (j = n - 1; j >= 0; j--)
parent = katze_array_find_token (array, token); {
parent = katze_array_get_nth_item (array, j);
if (!parent) if (day == katze_item_get_added (KATZE_ITEM (parent)))
break;
}
if (j < 0)
{ {
parent = katze_array_new (KATZE_TYPE_ARRAY); 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_item_set_token (KATZE_ITEM (parent), token);
katze_array_add_item (array, parent); katze_array_add_item (array, parent);
} }
@ -781,6 +793,31 @@ midori_history_add_items (void* data,
return 0; 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* static sqlite3*
midori_history_initialize (KatzeArray* array, midori_history_initialize (KatzeArray* array,
const gchar* filename, const gchar* filename,
@ -789,18 +826,45 @@ midori_history_initialize (KatzeArray* array,
sqlite3* db; sqlite3* db;
KatzeItem* item; KatzeItem* item;
gint i, n; gint i, n;
gboolean has_day;
has_day = FALSE;
if ((db = db_open (filename, error)) == NULL) if ((db = db_open (filename, error)) == NULL)
return db; return db;
if (!db_exec (db, if (!db_exec (db,
"CREATE TABLE IF NOT EXISTS " "CREATE TABLE IF NOT EXISTS "
"history(uri text, title text, date integer, visits integer)", "history(uri text, title text, date integer, day integer)",
error)) error))
return NULL; return NULL;
if (!db_exec_callback (db, 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", "ORDER BY date ASC",
midori_history_add_items, midori_history_add_items,
array, array,

View file

@ -3623,25 +3623,24 @@ midori_browser_entry_clear_icon_released_cb (GtkIconEntry* entry,
static void static void
_tree_store_insert_history_item (GtkTreeStore* treestore, _tree_store_insert_history_item (GtkTreeStore* treestore,
GtkTreeIter* parent, GtkTreeIter* parent,
KatzeItem* item) KatzeItem* item,
gint64 day)
{ {
GtkTreeIter iter; GtkTreeIter iter;
KatzeItem* child; KatzeItem* child;
guint i, n; guint i, n;
GtkTreeIter* piter; GtkTreeIter* piter;
time_t now; gint64 pday;
gint64 date; gint64 age = -1;
gint age = -1;
g_return_if_fail (KATZE_IS_ITEM (item)); g_return_if_fail (KATZE_IS_ITEM (item));
if (KATZE_IS_ARRAY (item)) if (KATZE_IS_ARRAY (item))
{ {
piter = parent; piter = parent;
if ((date = katze_item_get_added (item))) if ((pday = katze_item_get_added (item)))
{ {
now = time (NULL); age = day - pday;
age = sokoke_days_between ((time_t *)&date, (time_t *)&now);
gtk_tree_store_insert_with_values (treestore, &iter, parent, gtk_tree_store_insert_with_values (treestore, &iter, parent,
0, 0, item, 1, age, -1); 0, 0, item, 1, age, -1);
g_object_unref (item); g_object_unref (item);
@ -3651,7 +3650,7 @@ _tree_store_insert_history_item (GtkTreeStore* treestore,
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
child = katze_array_get_nth_item (KATZE_ARRAY (item), 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 else
@ -3673,10 +3672,10 @@ midori_browser_new_history_item (MidoriBrowser* browser,
gint i; gint i;
gboolean found; gboolean found;
time_t now; time_t now;
gint64 date; gint64 day;
time_t date_; gint64 pday;
gint age; gint64 age;
gint newage; gint64 newage;
gchar token[50]; gchar token[50];
if (!katze_object_get_boolean (browser->settings, "remember-last-visited-pages")) 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); now = time (NULL);
katze_item_set_added (item, now); katze_item_set_added (item, now);
day = sokoke_time_t_to_julian (&now);
found = FALSE; found = FALSE;
i = 0; i = 0;
while (gtk_tree_model_iter_nth_child (treemodel, &iter, NULL, i++)) while (gtk_tree_model_iter_nth_child (treemodel, &iter, NULL, i++))
{ {
gtk_tree_model_get (treemodel, &iter, 0, &parent, 1, &age, -1); gtk_tree_model_get (treemodel, &iter, 0, &parent, 1, &age, -1);
date = katze_item_get_added (KATZE_ITEM (parent)); pday = katze_item_get_added (KATZE_ITEM (parent));
date_ = (time_t)date; newage = day - pday;
newage = sokoke_days_between ((time_t *)&date, (time_t *)&now);
if (newage == 0) if (newage == 0)
{ {
found = TRUE; found = TRUE;
_tree_store_insert_history_item (GTK_TREE_STORE (treemodel), _tree_store_insert_history_item (GTK_TREE_STORE (treemodel),
&iter, item); &iter, item, day);
katze_array_add_item (parent, item); katze_array_add_item (parent, item);
} }
if (age != newage) if (age != newage)
@ -3712,12 +3711,12 @@ midori_browser_new_history_item (MidoriBrowser* browser,
{ {
strftime (token, sizeof (token), "%Y-%m-%d", localtime (&now)); strftime (token, sizeof (token), "%Y-%m-%d", localtime (&now));
parent = katze_array_new (KATZE_TYPE_ARRAY); 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_item_set_token (KATZE_ITEM (parent), token);
katze_array_add_item (browser->history, parent); katze_array_add_item (browser->history, parent);
katze_array_add_item (parent, item); katze_array_add_item (parent, item);
_tree_store_insert_history_item (GTK_TREE_STORE (treemodel), NULL, _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; GtkTreeView* treeview;
GtkTreeModel* treemodel; GtkTreeModel* treemodel;
GtkAction* action; GtkAction* action;
time_t now;
gint64 day;
if (browser->history == history) if (browser->history == history)
return; return;
@ -3796,10 +3797,13 @@ midori_browser_set_history (MidoriBrowser* browser,
g_signal_connect (browser->history, "clear", g_signal_connect (browser->history, "clear",
G_CALLBACK (midori_browser_history_clear_cb), browser); 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); treeview = GTK_TREE_VIEW (browser->panel_history);
treemodel = gtk_tree_view_get_model (treeview); treemodel = gtk_tree_view_get_model (treeview);
_tree_store_insert_history_item (GTK_TREE_STORE (treemodel), _tree_store_insert_history_item (GTK_TREE_STORE (treemodel), NULL,
NULL, KATZE_ITEM (browser->history)); KATZE_ITEM (browser->history), day);
action = _action_by_name (browser, "Location"); action = _action_by_name (browser, "Location");
midori_location_action_freeze (MIDORI_LOCATION_ACTION (action)); midori_location_action_freeze (MIDORI_LOCATION_ACTION (action));

View file

@ -663,32 +663,25 @@ sokoke_tree_view_get_selected_iter (GtkTreeView* tree_view,
} }
/** /**
* sokoke_days_between: * sokoke_time_t_to_julian:
* @day1: a time_t timestamp value * @timestamp: a time_t timestamp value
* @day2: 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. * Return value: an integer.
**/ **/
gint gint64
sokoke_days_between (const time_t* day1, sokoke_time_t_to_julian (const time_t* timestamp)
const time_t* day2)
{ {
GDate* date1; GDate* date;
GDate* date2; gint64 julian;
gint age;
date1 = g_date_new (); date = g_date_new ();
date2 = g_date_new ();
g_date_set_time_t (date1, *day1); g_date_set_time_t (date, *timestamp);
g_date_set_time_t (date2, *day2); julian = (gint64)g_date_get_julian (date);
age = g_date_days_between (date1, date2); g_date_free (date);
g_date_free (date1); return julian;
g_date_free (date2);
return age;
} }

View file

@ -126,8 +126,7 @@ sokoke_tree_view_get_selected_iter (GtkTreeView* tree_view,
GtkTreeModel** model, GtkTreeModel** model,
GtkTreeIter* iter); GtkTreeIter* iter);
gint gint64
sokoke_days_between (const time_t* day1, sokoke_time_t_to_julian (const time_t* timestamp);
const time_t* day2);
#endif /* !__SOKOKE_H__ */ #endif /* !__SOKOKE_H__ */