[Kde-pim] Trying to understand mail filtering handling with maildir resource

Martin Steigerwald Martin at lichtvoll.de
Sun Jul 13 19:07:17 BST 2014


Am Sonntag, 13. Juli 2014, 15:14:09 schrieb Martin Steigerwald:
> Hi!
> 
> In order to finally break^H^H^H^H^H fix up performance of maildir resource I
> try  to understand maildir filtering handling with maildir resource.
> Especially I want to ask the question:
> 
> Why does filtering mails into a folder trigger a full folder sync including 
> comparing all files each time?
> 
> 
> I started from libmaildir and the only case it compares full directory 
> contents seem to be in 
> 
> 838 void
> Maildir::refreshKeyCache()                                                 
>                                                                     839 {
> 840   KeyCache::self()->refreshKeys( d->path );
> 841 }
> 
> which calls:
> 
>  26 void KeyCache::addKeys( const QString& dir )
>  27 {
>  28   if ( !mNewKeys.contains( dir ) ) {
>  29     mNewKeys.insert( dir, listNew( dir ) );
>  30     //kDebug() << "Added new keys for: " << dir;
>  31   }
>  32 
>  33   if ( !mCurKeys.contains( dir ) ) {
>  34     mCurKeys.insert( dir, listCurrent( dir ) );
>  35     //kDebug() << "Added cur keys for: " << dir;
>  36   }
>  37 }
>  38                                                                         
>                                                                            
> 39 void KeyCache::refreshKeys( const QString& dir )
>  40 {
>  41     mNewKeys.remove( dir );
>  42     mCurKeys.remove( dir );
>  43     addKeys( dir );
>  44 }
> 
> which essential calls the routines I switched not to sort the filenames.
> The  routines which list all the filenames of a mail folder into a buffer.
> 
> 
> Maildir resource calls this in:
> 
> 711 void MaildirResource::slotDirChanged(const QString& dir)
> 712 { 
> 713   QFileInfo fileInfo( dir );
> 714   if ( fileInfo.isFile() ) {
> 715     slotFileChanged( fileInfo );
> 716     return;
> 717   }
> 718 
> 719   if ( dir == mSettings->path() ) {
> 720     synchronizeCollectionTree();
> 721    synchronizeCollection( Collection::root().id() );
> 722     return;
> 723   }
> 
> TODO: Figure out what these exactly do.
> 
> Documentation
> 
> void ResourceBase::synchronizeCollection        (
>       qint64          id      )        protected
> 
> This method is called whenever the collection with the given id shall be 
> synchronized.
> 
> Definition at line 1071 of file resourcebase.cpp.
> 
> isn´t exactly helpful. What does synchronize mean?
> 
> Hmmm, okay it calls an collection fetch job, so retrieves all items from it
> 
> 724 
> 725   if ( dir.endsWith( QLatin1String( ".directory" ) ) ) {
> 726     synchronizeCollectionTree(); //might be too much, but this is not a 
> common case anyway
> 727     return;
> 728   }
> 729 
> 730   QDir d( dir );
> 731   if ( !d.cdUp() )
> 732     return;
> 733 
> 734   Maildir md( d.path() );
> 735   if ( !md.isValid() )
> 736     return;
> 737 
> 738   md.refreshKeyCache();
> 
> And this probably is in there to make sure KeyCache of libmaildir also has
> the  most recent view on things… but why? Shouldn´t it always have it.
> 
> 
> So everytime the dir is changed this is called.

Wait. Everytime a mail is moved to a different folder, in some sense that 
destination folder is changed…

… still I really want to believe that Akonadi differentiates between a change 
made within Akonadi like moving a mail due to a filter where it can exactly 
know which mail and which mail file is to be moved from which source folder to 
which destination folder and any change made outside of Akonadi and being 
catched by inotify watches.

In several places in maildir resource itself I see calls to a function to stop 
maildir scanning before a call into libmaildir, like in maildirresource.cpp:

419   stopMaildirScan( sourceDir );
420   stopMaildirScan( destDir );
421 
422   const QString newRid = sourceDir.moveEntryTo( item.remoteId(), destDir 
);
423 
424   mChangedFiles.insert( newRid );
425   mChangedCleanerTimer->start( CLEANER_TIMEOUT );
426 
427   restartMaildirScan( sourceDir );
428   restartMaildirScan( destDir );


This basically disabled the filesystem watcher:

855 void MaildirResource::stopMaildirScan(const Maildir &maildir)
856 {
857     const QString path = maildir.path();
858     mFsWatcher->stopDirScan( path + QLatin1Literal( "/new" ) );
859     mFsWatcher->stopDirScan( path + QLatin1Literal( "/cur" ) );
860 }
861 
862 void MaildirResource::restartMaildirScan(const Maildir &maildir)
863 {
864     const QString path = maildir.path();
865     mFsWatcher->restartDirScan( path + QLatin1Literal( "/new" ) );
866     mFsWatcher->restartDirScan( path + QLatin1Literal( "/cur" ) );
867 }  


Okay, it boils down to where

711 void MaildirResource::slotDirChanged(const QString& dir)

is called.

If its called on filesystem changes detected by inotify, I think thats fine.


But if its triggered on filtering a mail into a new folder, then I think thats 
a bug. Yet, moving a mail with maildirresource exactly should not trigger it.


Well, okay, got this far. It really seems to be called on filesystem changes:

maildirresource.cpp:139:  connect( mFsWatcher, SIGNAL(dirty(QString)), 
SLOT(slotDirChanged(QString)) );


yet, maildirresource stops scanning on moving a mail… so why it is 
synchronizing the whole folder? Need to closer check mailfilteragent and 
filestore then I bet.

Ciao,
-- 
Martin 'Helios' Steigerwald - http://www.Lichtvoll.de
GPG: 03B0 0D6C 0040 0710 4AFA  B82F 991B EAAC A599 84C7
_______________________________________________
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