After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 774191 - Turn PhotosBaseManager into a GListModel
Turn PhotosBaseManager into a GListModel
Status: RESOLVED FIXED
Product: gnome-photos
Classification: Applications
Component: general
unspecified
Other All
: Normal enhancement
: ---
Assigned To: GNOME photos maintainer(s)
GNOME photos maintainer(s)
Depends on:
Blocks: 690623
 
 
Reported: 2016-11-10 10:39 UTC by Debarshi Ray
Modified: 2016-12-05 13:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
base-manager: Stop using photos_base_manager_get_objects (1.87 KB, patch)
2016-11-11 10:31 UTC, Debarshi Ray
committed Details | Review
base-manager: Consolidate the removal logic in one place (2.04 KB, patch)
2016-11-11 10:31 UTC, Debarshi Ray
none Details | Review
item-manager: Rename a variable (1.42 KB, patch)
2016-11-11 10:31 UTC, Debarshi Ray
committed Details | Review
base-manager: Directly access the GHashTable in remove_object_by_id (1.05 KB, patch)
2016-11-11 10:32 UTC, Debarshi Ray
committed Details | Review
Turn PhotosBaseManager and PhotosItemManager into GListModels (28.48 KB, patch)
2016-11-11 10:32 UTC, Debarshi Ray
none Details | Review
base-manager: Consolidate the removal logic in one place (2.09 KB, patch)
2016-11-15 11:06 UTC, Debarshi Ray
committed Details | Review
source-manager: Rearrange the code for subsequent changes (1.44 KB, patch)
2016-11-15 11:07 UTC, Debarshi Ray
committed Details | Review
share-point-manager: Rearrange the code for subsequent changes (2.18 KB, patch)
2016-11-15 11:07 UTC, Debarshi Ray
committed Details | Review
Turn PhotosBaseManager and PhotosItemManager into GListModels (27.67 KB, patch)
2016-11-15 11:07 UTC, Debarshi Ray
none Details | Review
Turn PhotosBaseManager and PhotosItemManager into GListModels (28.12 KB, patch)
2016-11-18 10:37 UTC, Debarshi Ray
committed Details | Review
item-manager: Emit GListModel::items-changed (1.49 KB, patch)
2016-12-03 09:47 UTC, Debarshi Ray
committed Details | Review

Description Debarshi Ray 2016-11-10 10:39:46 UTC
PhotosBaseManager, the class that we use as a model for tracking images, sources, share-points, etc., should offer the GListModel interface, so that we can replace our GtkIconView-based view with a GtkFlowBox-based one. It would also mean that we will no longer use PhotosViewModel (which is a GtkListStore) and the changes in bug 770342 have moved us closer towards this goal.
Comment 1 Debarshi Ray 2016-11-11 10:08:32 UTC
Summarizing my discussions with Alessandro for the sake of any onlookers...

There is one bone of contention with GListModel-ifying PhotosBaseManager. The GListModel interface is primarily for rendering the contents of a BaseManager. eg., a GtkFlowBox to show all the images or collections or share-points. Rendering can involve having the objects sorted in a particular order. eg., for images and collections we want to show the most recent objects first. At the same time, we want to retain the ability of BaseManager to look up an object from its ID in O(1) time.

This means that we cannot simply replace the internals of PhotosBaseManager with a GListStore (which is a GListModel implementation that comes with GLib).

GListStore is very good at letting a GtkFlowBox render the objects, possibly sorted. It uses GSequence, which is a balanced binary tree, so it is easy and efficient to iterate over it like a GList, and given a GCompareDataFunc it can keep the tree sorted in O(nlogn). Random access is O(logn), which, I guess, is acceptable.

However, looking up an object from its ID will be O(n), which is quite a loss from our current O(1) behaviour. This is because the GSequence (ie. the balanced binary tree) is sorted based on how the objects will be rendered, not based on their IDs. eg., it might sorted based on the images' mtimes, not their URNs.

So, can we add a GListStore inside PhotosBaseManager alongside our existing GHashTable based implementation?

Almost, but no.

Things like photos_base_manager_remove_by_id are currently O(1). To keep the GListModel updated, we will have to iterate over the GListStore in O(n) time to find the object to remove. This would be more efficient if we had the GSequenceIter pointing to the actual node inside the GSequence. eg., our GHashTable could be a mapping from ID to (GObject, GSequenceIter). Unfortunately, GListStore doesn't expose its internal GSequence.

Therefore, instead of using a GListStore inside BaseManager, we add a GSequence inside PhotosBaseManager and basically reimplement GListStore ourselves. It isn't as bad as it sounds. We don't need most of the GListStore modification API, because BaseManager already has its own. The guts of what we really need are in GSequence itself. Hence it is not a lot of code.

Credit goes to Alessandro Bono for investigating this.
Comment 2 Debarshi Ray 2016-11-11 10:31:21 UTC
Created attachment 339604 [details] [review]
base-manager: Stop using photos_base_manager_get_objects
Comment 3 Debarshi Ray 2016-11-11 10:31:38 UTC
Created attachment 339605 [details] [review]
base-manager: Consolidate the removal logic in one place
Comment 4 Debarshi Ray 2016-11-11 10:31:58 UTC
Created attachment 339606 [details] [review]
item-manager: Rename a variable
Comment 5 Debarshi Ray 2016-11-11 10:32:25 UTC
Created attachment 339607 [details] [review]
base-manager: Directly access the GHashTable in remove_object_by_id
Comment 6 Debarshi Ray 2016-11-11 10:32:46 UTC
Created attachment 339608 [details] [review]
Turn PhotosBaseManager and PhotosItemManager into GListModels
Comment 7 Alessandro Bono 2016-11-15 10:31:22 UTC
Review of attachment 339604 [details] [review]:

ok
Comment 8 Alessandro Bono 2016-11-15 10:41:54 UTC
Review of attachment 339605 [details] [review]:

Looks ok to me otherwise.

::: src/photos-base-manager.c
@@ +483,3 @@
   GHashTableIter iter;
+  GList *l;
+  GList *removed_ids = NULL;

We could start using GSList (https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html) when we don't need a double linked structure. What do you think about it?
Comment 9 Alessandro Bono 2016-11-15 10:42:11 UTC
Review of attachment 339606 [details] [review]:

ok
Comment 10 Alessandro Bono 2016-11-15 10:43:42 UTC
Review of attachment 339607 [details] [review]:

ok
Comment 11 Debarshi Ray 2016-11-15 10:55:08 UTC
Comment on attachment 339604 [details] [review]
base-manager: Stop using photos_base_manager_get_objects

Pushed to master.
Comment 12 Debarshi Ray 2016-11-15 10:56:38 UTC
Comment on attachment 339606 [details] [review]
item-manager: Rename a variable

Pushed to master.
Comment 13 Debarshi Ray 2016-11-15 10:58:15 UTC
Comment on attachment 339607 [details] [review]
base-manager: Directly access the GHashTable in remove_object_by_id

Pushed to master.
Comment 14 Debarshi Ray 2016-11-15 11:05:25 UTC
(In reply to Alessandro Bono from comment #8)
> Review of attachment 339605 [details] [review] [review]:

Thanks for the review, Alessandro!

> ::: src/photos-base-manager.c
> @@ +483,3 @@
>    GHashTableIter iter;
> +  GList *l;
> +  GList *removed_ids = NULL;
> 
> We could start using GSList
> (https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html) when
> we don't need a double linked structure. What do you think about it?

Sure, why not?
Comment 15 Debarshi Ray 2016-11-15 11:06:45 UTC
Created attachment 339912 [details] [review]
base-manager: Consolidate the removal logic in one place

Use GSList instead of GList.
Comment 16 Debarshi Ray 2016-11-15 11:07:05 UTC
Created attachment 339913 [details] [review]
source-manager: Rearrange the code for subsequent changes
Comment 17 Debarshi Ray 2016-11-15 11:07:26 UTC
Created attachment 339914 [details] [review]
share-point-manager: Rearrange the code for subsequent changes
Comment 18 Debarshi Ray 2016-11-15 11:07:51 UTC
Created attachment 339915 [details] [review]
Turn PhotosBaseManager and PhotosItemManager into GListModels
Comment 19 Alessandro Bono 2016-11-17 11:38:58 UTC
Review of attachment 339912 [details] [review]:

ok
Comment 20 Alessandro Bono 2016-11-17 11:39:53 UTC
Review of attachment 339913 [details] [review]:

ok
Comment 21 Alessandro Bono 2016-11-17 11:41:04 UTC
Review of attachment 339914 [details] [review]:

ok
Comment 22 Alessandro Bono 2016-11-17 11:42:30 UTC
Review of attachment 339915 [details] [review]:

::: src/photos-base-manager.c
@@ +483,3 @@
   g_clear_object (&priv->active_object);
+
+  count = photos_base_manager_get_objects_count (self);

Shouldn't we get the count before removing all the objects in the Hashtable? Even better if we get it before removing all the objects in the GSequence too.
Comment 23 Debarshi Ray 2016-11-18 08:07:30 UTC
Comment on attachment 339912 [details] [review]
base-manager: Consolidate the removal logic in one place

Pushed to master.
Comment 24 Debarshi Ray 2016-11-18 08:26:04 UTC
Comment on attachment 339913 [details] [review]
source-manager: Rearrange the code for subsequent changes

Pushed to master.
Comment 25 Debarshi Ray 2016-11-18 10:29:41 UTC
Comment on attachment 339914 [details] [review]
share-point-manager: Rearrange the code for subsequent changes

Pushed to master.
Comment 26 Debarshi Ray 2016-11-18 10:37:58 UTC
Created attachment 340227 [details] [review]
Turn PhotosBaseManager and PhotosItemManager into GListModels

Get the count before removing the contents of the GSequence and the GHashTable.
Comment 27 Alessandro Bono 2016-11-18 10:42:30 UTC
Review of attachment 340227 [details] [review]:

ok
Comment 28 Debarshi Ray 2016-11-18 15:06:19 UTC
Comment on attachment 340227 [details] [review]
Turn PhotosBaseManager and PhotosItemManager into GListModels

Pushed to master.
Comment 29 Debarshi Ray 2016-12-03 09:47:33 UTC
Created attachment 341302 [details] [review]
item-manager: Emit GListModel::items-changed
Comment 30 Debarshi Ray 2016-12-05 13:00:22 UTC
Comment on attachment 341302 [details] [review]
item-manager: Emit GListModel::items-changed

Pushed to master. Let me know if something is wrong.