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"
"('%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,

View 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));

View 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;
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;
}

View 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__ */