Warning, /pim/akonadi/docs/internals.md is written in an unsupported language. File is not indexed.
0001 # Internals documentation for Akonadi developers # {#internals} 0002 0003 ## Lazy Model Population ## 0004 0005 NOTE: This page is not part of the Akonadi API. It is provided as internal documentation for Akonadi maintainers. It was originally a blog post here: https://steveire.wordpress.com/2009/10/06/cache-invalidation-in-akonadi-models/ 0006 @internal 0007 0008 If using EntityTreeModel::LazyPopulation with your model, items will be fetched into the model when the collection they are a part of is selected. This ensures that the model is as sparsely populated as possible for performance reasons. As a consequence however, it is necessary to purge unused items from the model too. This is handled automatically when using an Akonadi::SelectionProxyModel. 0009 0010 The problem is knowing when to invalidate the cache. If no application is currently showing the contents of a Collection, there is no need for the Items in that Collection to be fetched, cached and kept up to date in the model. The effect we would like to achieve is to purge the Items in a Collection when those items are no longer shown anywhere in the application. Generally, that will mean that the Collection is not selected. 0011 0012 In Qt Model-View, the application data is stored in a model, and there may be one or more views attached to it displaying its contents. The model doesn’t have any knowledge of the views, and so it can’t know whether any particular Collection is selected, and purge its Iitems. 0013 0014 To solve this, we use the KSelectionProxyModel, which already has a lot of code for managing the selection a user makes in a view. A subclass, Akonadi::SelectionProxyModel implements a reference counting system which increments the refcount of a Collection when it is selected, and decrements it when deselected. If the reference count of a Collection goes down to zero, it is put in a queue to be purged. It is not purged immediately, but queued because if the user is clicking around several Collection in a short time, we don’t want to purge the Collections each click or we’d lose the benefit of the caching. Like other <a href="http://qt-project.org/doc/qt-4.7/qobject.html#id-aa43c933-c869-42eb-af14-ff17b8304c96">similar optimisation techniques</a>, this violates the object-oriented principle of modularity, but it is worth it for the benefit it brings. The effect can be seen in the akonadiconsole tool by not filtering out the items from the tree. 0015 0016 In the screenshots below I removed the filtering out of Items in the tree so that the fetching/purging can be seen. In real applications, the Items in the tree on the left would not be visible. 0017 0018 @image html dox/bufferedcaching1.png "When a Collection is clicked, its Items are put into the model. The rest of the Collections have no items." 0019 0020 @image html dox/bufferedcaching2.png "The Inbox Collection is selected, so its items are fetched. Personal Contacts is no longer selected, so it is put into a queue to be purged." 0021 0022 @image html dox/bufferedcaching3.png "Select another Collection and its items are fetched too." 0023 0024 @image html dox/bufferedcaching4.png "Another Collection is selected, pushing the Personal contacts out of the queue and purging them" 0025 0026 @image html dox/bufferedcaching6.png "If the Collection is selected again, its Items are refetched" 0027 0028 For this example, I used a queue length of just two Collections, so that if a Collection was deselected two clicks ago, it will be purged. In real applications, a longer queue length will be used, but it’s harder to illustrate in screenshots. Another unrealistic part of this demo is that this feature will like be used in applications like KMail where Collections can contain tens of thousands of Items and fetching them is an expensive operation. 0029 0030 This feature should be totally invisible to users and even developers using Akonadi, but it should offset the main disadvantage of using a cache of Items in the EntityTreeModel. 0031 0032 */ 0033