[Kde-pim] More about KRecursiveFilterProxyModel
Christian Mollekopf
chrigi_1 at fastmail.fm
Mon Jan 26 08:54:11 GMT 2015
On Sunday 25 January 2015 19.55:41 David Faure wrote:
> The problem with the superfluous dataChanged() signals emitted by
> KRecursiveFilterProxyModel (see e.g.
> https://git.reviewboard.kde.org/r/122227/)
>
> is that they trigger many calls to "reload()" in the
> FavoritesCollectionModel. Try adding a kDebug in there and using kmail,
> it's horrendous (and it's a real time sink, any time I interrupt kmail with
> gdb, it's in that code - even before my changes to
> KRecursiveFilterProxyModel, but possibly even more so now that it handles
> dataChanged more correctly).
>
Yeah, FavoriteCollectionsModel is a timesink.
> Somehow it's made even worse by the stack of proxies used in kmail, because
> in the debug output I see this:
> imagine you have nested folders like A / B / C / D, if the number of unread
> emails in D changes, then dataChanged signals are received by
> FavoritesCollectionModel like this: D, C, B, A, C, B, A, B, A, A.
> It's as if there were two KRecursiveFilterProxyModel in the stack....
> (I didn't check whether that was the case).
>
I don't think there are two, see below.
>
> So, I spent some time this weekend trying to fix KRecursiveFilterProxyModel
> so that it doesn't emit superfluous signals. Since there's no
> dataAboutToBeChanged in Qt, the only way to know if dataChanged actually
> changed the filtering status of an index, is to have a cache, and compare
> before/after.
> I implemented all this, and it works great AFAICS, see
> https://git.reviewboard.kde.org/r/122252/
>
> Every call to Akonadi::EntityTreeModelPrivate::monitoredCollectionChanged,
> which triggers one dataChanged signal in the ETM, still leads to 4 calls to
> Akonadi::FavoriteCollectionsModel::Private::reload for some reason,
> but at least it's not 4+3+2+1=10 calls, anymore.
>
> Apart from reviewing my two RB patches, I'd welcome any input on whether:
>
> * ETM's monitoredCollectionChanged really needs to be emitted so often
> (it seems any FetchJob emits it, even if nothing changed?)
>
What do you mean by *any* fetchjob? Internal fetchjobs?
We need emit dataChanged rather frequently because we update i.e. collection
statistics through it (whenever an item is added/removed), or the fetch state
(if a fetch job is running or not). External fetch jobs should of course not
result in a dataChanged signal in the ETM, otherwise we have a bug in akonadi
server.
> * FavoriteCollectionsModel really needs to do so much work on dataChanged
> (Christian, I can't help but wonder if your changes a year ago to this
> class, for performance reasons, actually made it worse - I keep seeing
> kmail spending time there)
>
It's of course possible that FavoriteCollectionsModel ends up emitting more
dataChanged signals due to this patch. I think at least superfluous
selectionChanged signals could be avoided by checking the current selection
before selecting it again (QItemSelectionModel::select doesn't do that it
seems). Currently we're reselecting the index on every dataChanged signal, and
reselecting all indexes on every layoutChanged signals. And since
QSortFilterProxyModel turns dataChanged into layoutChanged, that happens a
lot.
> * Maybe FavoriteCollectionsModel could sit on top of ETM (or some
> intermediate model that just filters for folders) rather than sitting on
> top of so many proxies, so that it gets called less often? (the fact that
> any QSFPM turns any source dataChanged into a layoutChanged really doesn't
> help with performance in models sitting on top...)
The stack is (from my notes):
KMKernel::collectionModel() (the ETM)
QuotaColorProxyModel (KIdentityProxyModel)
KPIM:StatisticsProxyModel (KIdentityProxyModel)
FolderTreeWidgetProxyModel (KRecursiveFilterProxyModel)
EntityCollectionOrderProxyModel (QSortFilterProxyModel)
FavoriteCollectionsModel
The problem is we probably want the same sorting and filtering, but we could
of course just add those models on top of the FavoriteCollectionsModel again.
Cheers,
Christian
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/
More information about the kde-pim
mailing list