Merge lp:~aauzi/midori/fix-1179200-6 into lp:midori

Proposed by André Auzi
Status: Merged
Approved by: Cris Dywan
Approved revision: 6328
Merged at revision: 6452
Proposed branch: lp:~aauzi/midori/fix-1179200-6
Merge into: lp:midori
Diff against target: 233 lines (+127/-9)
1 file modified
midori/midori-bookmarks-db.c (+127/-9)
To merge this branch: bzr merge lp:~aauzi/midori/fix-1179200-6
Reviewer Review Type Date Requested Status
Cris Dywan Approve
Review via email: mp+186400@code.launchpad.net

This proposal supersedes a proposal from 2013-09-17.

Commit message

Cache bookmark items to avoid their recreation on database reads

Description of the change

Sixth step for the merge of fix-1179200

This step cache all bookmark items in order to avoid their recreation on database reads.

The cache is recursively populated and cleared for folders addition or removals.

Thanks tp this change, items are consistent in bookmark bar and panel and the following use case/sequence works.

Having a bookmark that's not in the boolùark bar, visible in the panel
Edit it from the panel and add it to the bookmark bar
It appears in the bookmark bar
Edit it from the bar and remove it from the bar
Edit it from the panel

Without the fix:
  the item appears with the bookmark bar state checked (the last state it had when it was edited in the panel)

With the fix:
  the item appears with the current bookmark bar state: unchecked

To post a comment you must log in.
Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

Works as expected

Revision history for this message
Cris Dywan (kalikiana) wrote :

The code looks sensible overall.
Did you consider if using sqlite lookup instead of hash tables could conserve memory and possibly be as fast as or faster than the hash tables? Provided handling of updates is reliably done you could also avoid overhead reading through all items.

review: Needs Information
Revision history for this message
André Auzi (aauzi) wrote :

> Did you consider if using sqlite lookup instead of hash tables could conserve
> memory and possibly be as fast as or faster than the hash tables? Provided
> handling of updates is reliably done you could also avoid overhead reading
> through all items.

My goal here was to limit the need of update for the different items attached to UI widgets.

With this cache mechanism I wanted to have the same items attached to the toolitems of bookmarks tool bar, the menuitem of the bookmarks menu and the treeitems of the bookmarks panel.

When the item is changed, the widgets are most often updated by the change notify signal,the update_item being provided for reparenting in the panel treeview.

I considered that doing it this way would preserve the data flow from the UI to the database, reduce the memory footprint and keep at the strict minimum the need to search items in the UI widget trees for copy/update after a modification.

I also wanted to centralize the data to be able, later, to implement Undo of massive changes like recursive deletes or imports.

Unless I'm mistaken, sqlite lookups would only partially provide these properties unless we could implement an association table of items with UI widgets.
It may be implemented with a temporary (in memory) table but would it be as straight forward as the proposed hash table? I don't know.

The avoidance of reread of items is implemented, at least for the bookmarks panel, at step 8 in branch fix-1179200-8.

Revision history for this message
Cris Dywan (kalikiana) wrote :

I concur. I don't have any evidence sqlite would do the trick and it might need significant research. I would think undo which is backed by sqlite on disk could be interesting, but not necessarily as part of the main table. So given the hash table approach works very well, there is no reason not to go with it now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'midori/midori-bookmarks-db.c'
2--- midori/midori-bookmarks-db.c 2013-09-17 19:34:23 +0000
3+++ midori/midori-bookmarks-db.c 2013-09-18 17:39:50 +0000
4@@ -39,6 +39,7 @@
5 KatzeArray parent_instance;
6
7 sqlite3* db;
8+ GHashTable* all_items;
9 };
10
11 struct _MidoriBookmarksDbClass
12@@ -97,6 +98,21 @@
13 midori_bookmarks_db_remove_item_db (sqlite3* db,
14 KatzeItem* item);
15
16+static guint
17+item_hash (gconstpointer item)
18+{
19+ gint64 id = katze_item_get_meta_integer (KATZE_ITEM (item), "id");
20+ return g_int64_hash (&id);
21+}
22+
23+static gboolean
24+item_equal (gconstpointer item_a, gconstpointer item_b)
25+{
26+ gint64 id_a = katze_item_get_meta_integer (KATZE_ITEM (item_a), "id");
27+ gint64 id_b = katze_item_get_meta_integer (KATZE_ITEM (item_b), "id");
28+ return (id_a == id_b)? TRUE : FALSE;
29+}
30+
31 static void
32 midori_bookmarks_db_class_init (MidoriBookmarksDbClass* class)
33 {
34@@ -131,9 +147,11 @@
35 midori_bookmarks_db_init (MidoriBookmarksDb* bookmarks)
36 {
37 bookmarks->db = NULL;
38+ bookmarks->all_items = g_hash_table_new (item_hash, item_equal);
39
40 katze_item_set_meta_integer (KATZE_ITEM (bookmarks), "id", 0);
41 katze_item_set_name (KATZE_ITEM (bookmarks), _("Bookmarks"));
42+ g_hash_table_insert (bookmarks->all_items, bookmarks, bookmarks);
43 /* g_object_ref (bookmarks); */
44 }
45
46@@ -147,6 +165,8 @@
47 sqlite3_close (bookmarks->db);
48 }
49
50+ g_hash_table_unref (bookmarks->all_items);
51+
52 G_OBJECT_CLASS (midori_bookmarks_db_parent_class)->finalize (object);
53 }
54
55@@ -172,7 +192,13 @@
56 }
57 else
58 {
59- parent = NULL;
60+ KatzeItem *search = katze_item_new ();
61+
62+ katze_item_set_meta_integer(search, "id", parentid);
63+
64+ parent = KATZE_ARRAY (g_hash_table_lookup (bookmarks->all_items, search));
65+
66+ g_object_unref (search);
67 }
68
69 return parent;
70@@ -216,7 +242,7 @@
71
72 if (IS_MIDORI_BOOKMARKS_DB (parent))
73 KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->add_item (parent, item);
74- else
75+ else if (KATZE_IS_ARRAY (parent))
76 katze_array_add_item (parent, item);
77 }
78
79@@ -267,7 +293,7 @@
80
81 if (IS_MIDORI_BOOKMARKS_DB (parent))
82 KATZE_ARRAY_CLASS (midori_bookmarks_db_parent_class)->remove_item (parent, item);
83- else
84+ else if (KATZE_IS_ARRAY (parent))
85 katze_array_remove_item (parent, item);
86 }
87
88@@ -331,6 +357,84 @@
89 }
90
91 /**
92+ * midori_bookmarks_db_add_item_recursive:
93+ * @item: the removed #KatzeItem
94+ * @bookmarks : the main bookmarks array
95+ *
96+ * Internal function that creates memory records of the added @item.
97+ * If @item is a #KatzeArray, the function recursiveley adds records
98+ * of all its childs.
99+ **/
100+static gint
101+midori_bookmarks_db_add_item_recursive (MidoriBookmarksDb* bookmarks,
102+ KatzeItem* item)
103+{
104+ GList* list;
105+ KatzeArray* array;
106+ gint64 id = 0;
107+ gint count = 0;
108+ gint64 parentid = katze_item_get_meta_integer (item, "parentid");
109+
110+ id = midori_bookmarks_db_insert_item_db (bookmarks->db, item, parentid);
111+ count++;
112+
113+ g_object_ref (item);
114+ g_hash_table_insert (bookmarks->all_items, item, item);
115+
116+ if (!KATZE_IS_ARRAY (item))
117+ return count;
118+
119+ array = KATZE_ARRAY (item);
120+
121+ KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
122+ {
123+ katze_item_set_meta_integer (item, "parentid", id);
124+ count += midori_bookmarks_db_add_item_recursive (bookmarks, item);
125+ }
126+
127+ g_list_free (list);
128+ return count;
129+}
130+
131+/**
132+ * midori_bookmarks_db_remove_item_recursive:
133+ * @item: the removed #KatzeItem
134+ * @bookmarks : the main bookmarks array
135+ *
136+ * Internal function that removes memory records of the removed @item.
137+ * If @item is a #KatzeArray, the function recursiveley removes records
138+ * of all its childs.
139+ **/
140+static void
141+midori_bookmarks_db_remove_item_recursive (KatzeItem* item,
142+ MidoriBookmarksDb* bookmarks)
143+{
144+ GHashTableIter hash_iter;
145+ gpointer found;
146+ KatzeArray* array;
147+ KatzeItem* child;
148+ GList* list;
149+
150+ if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item)))
151+ {
152+ g_hash_table_remove (bookmarks->all_items, found);
153+ g_object_unref (found);
154+ }
155+
156+ if (!KATZE_IS_ARRAY (item))
157+ return;
158+
159+ array = KATZE_ARRAY (item);
160+
161+ KATZE_ARRAY_FOREACH_ITEM_L (child, array, list)
162+ {
163+ midori_bookmarks_db_remove_item_recursive (child, bookmarks);
164+ }
165+
166+ g_list_free (list);
167+}
168+
169+/**
170 * midori_bookmarks_db_insert_item_db:
171 * @db: the #sqlite3
172 * @item: #KatzeItem the item to insert
173@@ -531,8 +635,7 @@
174 g_return_if_fail (KATZE_IS_ITEM (item));
175 g_return_if_fail (NULL == katze_item_get_meta_string (item, "id"));
176
177- midori_bookmarks_db_insert_item_db (bookmarks->db, item,
178- katze_item_get_meta_integer (item, "parentid"));
179+ midori_bookmarks_db_add_item_recursive (bookmarks, item);
180
181 katze_array_add_item (KATZE_ARRAY (bookmarks), item);
182 }
183@@ -576,6 +679,7 @@
184 g_return_if_fail (katze_item_get_meta_string (item, "id"));
185 g_return_if_fail (0 != katze_item_get_meta_integer (item, "id"));
186
187+ midori_bookmarks_db_remove_item_recursive (item, bookmarks);
188 midori_bookmarks_db_remove_item_db (bookmarks->db, item);
189
190 katze_array_remove_item (KATZE_ARRAY (bookmarks), item);
191@@ -882,9 +986,6 @@
192 {
193 katze_item_set_meta_integer (item, "parentid", parentid);
194 midori_bookmarks_db_add_item (bookmarks, item);
195- if (KATZE_IS_ARRAY (item))
196- midori_bookmarks_db_import_array (bookmarks, KATZE_ARRAY (item),
197- katze_item_get_meta_integer(item, "id"));
198 }
199 g_list_free (list);
200 }
201@@ -929,7 +1030,16 @@
202 for (i = 0; i < cols; i++)
203 katze_item_set_value_from_column (stmt, i, item);
204
205- if (KATZE_ITEM_IS_FOLDER (item))
206+ if (NULL != (found = g_hash_table_lookup (bookmarks->all_items, item)))
207+ {
208+ for (i = 0; i < cols; i++)
209+ katze_item_set_value_from_column (stmt, i, found);
210+
211+ g_object_unref (item);
212+
213+ item = found;
214+ }
215+ else if (KATZE_ITEM_IS_FOLDER (item))
216 {
217 g_object_unref (item);
218
219@@ -937,6 +1047,14 @@
220
221 for (i = 0; i < cols; i++)
222 katze_item_set_value_from_column (stmt, i, item);
223+
224+ g_object_ref (item);
225+ g_hash_table_insert (bookmarks->all_items, item, item);
226+ }
227+ else
228+ {
229+ g_object_ref (item);
230+ g_hash_table_insert (bookmarks->all_items, item, item);
231 }
232
233 katze_array_add_item (array, item);

Subscribers

People subscribed via source and target branches

to all changes: