[KPhotoAlbum] Speeding up directory scanning
Shawn Willden
shawn-kimdaba at willden.org
Fri Dec 29 04:35:35 GMT 2006
I thought for a moment that this patch made starting kphotoalbum *hugely*
faster on OS X. It used to be impossiblly slow -- taking over five minutes
when a similarly-powered Linux box started in 20-30 seconds. This is with
just under 12,000 images, on a 1.2GHz G4 iBook.
Wondering if maybe OS X had an insanely slow stat() call, I updated to SVN
head and then applied the patch.
I was excited to see that startup time dropped to ~30 seconds. Just to get
some good numbers, I removed the patch and rebuilt and retested -- still 30
seconds. I rebooted to make sure there weren't a bunch of cached inodes.
Still 30 seconds.
AFAICT, the patch made no difference at all, but something did. There was an
OS X kernel update a few days ago, so I'm wondering if that was it.
Shawn.
On Thursday 28 December 2006 07:28, Robert L Krawitz wrote:
> I think this is cleaner, since .thm files are related to raw images.
>
> Index: DB/NewImageFinder.cpp
> ===================================================================
> --- DB/NewImageFinder.cpp (revision 617031)
> +++ DB/NewImageFinder.cpp (working copy)
> @@ -20,7 +20,9 @@
> #include <qfileinfo.h>
> #include "Settings/SettingsData.h"
> #include "Browser/BrowserWidget.h"
> -#include <qdir.h>
> +#include "ImageManager/RawImageDecoder.h"
> +#include <sys/types.h>
> +#include <dirent.h>
> #include "Utilities/Util.h"
> #include <qprogressdialog.h>
> #include <klocale.h>
> @@ -56,6 +58,54 @@
> return (!_pendingLoad.isEmpty()); // returns if new images was found.
> }
>
> +class MyDir
> +{
> +public:
> + MyDir();
> + MyDir(const QString &path);
> + virtual QStringList entryList(void) const;
> + virtual ~MyDir();
> +private:
> + QString path_;
> +};
> +
> +MyDir::MyDir()
> + : path_(QString::fromLatin1("."))
> +{
> +}
> +
> +MyDir::MyDir(const QString &path)
> + : path_(path)
> +{
> +}
> +
> +MyDir::~MyDir()
> +{
> +}
> +
> +QStringList MyDir::entryList(void) const
> +{
> + QStringList answer;
> + DIR *dir;
> + dirent *file;
> + dir = opendir( QFile::encodeName(path_) );
> + if ( !dir )
> + return answer; // cannot read the directory
> +
> +#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) &&
> !defined(Q_OS_CYGWIN) + union {
> + struct dirent mt_file;
> + char b[sizeof(struct dirent) + MAXNAMLEN + 1];
> + } u;
> + while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file )
> +#else
> + while ( (file = readdir(dir)) )
> +#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
> + answer.append(QFile::decodeName(file->d_name));
> + (void) closedir(dir);
> + return answer;
> +}
> +
> void NewImageFinder::searchForNewFiles( const QDict<void>& loadedFiles,
> QString directory ) {
> if ( directory.endsWith( QString::fromLatin1("/") ) )
> @@ -65,18 +115,24 @@
> if ( imageDir.endsWith( QString::fromLatin1("/") ) )
> imageDir = imageDir.mid( 0, imageDir.length()-1 );
>
> - QDir dir( directory );
> - QStringList dirList = dir.entryList( QDir::All );
> + MyDir dir( directory );
> + QStringList dirList = dir.entryList( );
> + ImageManager::RAWImageDecoder dec;
> for( QStringList::Iterator it = dirList.begin(); it != dirList.end();
> ++it ) { QString file = directory + QString::fromLatin1("/") + *it; -
> QFileInfo fi( file );
> if ( (*it) == QString::fromLatin1(".") || (*it) ==
> QString::fromLatin1("..") || (*it) == QString::fromLatin1("ThumbNails") ||
> (*it) == QString::fromLatin1("CategoryImages") ||
> - !fi.isReadable() )
> + loadedFiles.find( file ) ||
> + dec._skipThisFile(loadedFiles, file) )
> continue;
>
> - if ( fi.isFile() && loadedFiles.find( file ) == 0) {
> + QFileInfo fi( file );
> +
> + if ( !fi.isReadable() )
> + continue;
> +
> + if ( fi.isFile() ) {
> QString baseName = file.mid( imageDir.length()+1 );
> if ( ! DB::ImageDB::instance()->isBlocking( baseName ) ) {
> if ( Utilities::canReadImage(file) )
> Index: ImageManager/RawImageDecoder.cpp
> ===================================================================
> --- ImageManager/RawImageDecoder.cpp (revision 617031)
> +++ ImageManager/RawImageDecoder.cpp (working copy)
> @@ -109,4 +109,52 @@
> return false;
> }
>
> +bool RAWImageDecoder::_skipThisFile( const QDict<void>& loadedFiles, const
> QString& imageFile ) +{
> + /* Known RAW file extensions. TODO: Complete */
> + static const QString extensions[] = { QString::fromLatin1("crw"),
> +
> QString::fromLatin1("cr2"), +
> QString::fromLatin1("nef"), +
>
> QString::fromLatin1("bay"), +
> QString::fromLatin1("mos"), +
>
> QString::fromLatin1("mrw"), +
> QString::fromLatin1("orf"), +
>
> QString::fromLatin1("cs1"), +
> QString::fromLatin1("dc2"), +
>
> QString::fromLatin1("kdc"), +
> QString::fromLatin1("raf"), +
>
> QString::fromLatin1("rdc"), +
> QString::fromLatin1("x3f"), +
>
> QString::null }; + if
> (imageFile.endsWith(QString::fromLatin1(".thm")) ||
> + imageFile.endsWith(QString::fromLatin1(".THM")))
> + return true;
> + if (!
> (Settings::SettingsData::instance()->dontReadRawFilesWithOtherMatchingFile(
>))) + return false;
> + bool isRaw = false;
> + for( int i = 0; !extensions[i].isNull(); ++i ) {
> + if( imageFile.endsWith( extensions[i], false ) ) {
> + isRaw = true;
> + break;
> + }
> + }
> + if (!isRaw)
> + return false;
> + static const QString standardExtensions[] = {
> + QString::fromLatin1("jpg"),
> + QString::fromLatin1("JPG"),
> + QString::fromLatin1("tif"),
> + QString::fromLatin1("TIF"),
> + QString::fromLatin1("png"),
> + QString::fromLatin1("PNG"),
> + QString::null };
> + QString baseFileName = imageFile;
> + baseFileName.remove(baseFileName.length() - 3, 3);
> + for (int i = 0; !standardExtensions[i].isNull(); ++i) {
> + if (loadedFiles.find(baseFileName + standardExtensions[i]))
> + return true;
> + }
> + return false;
> }
> +
> +}
> Index: ImageManager/RawImageDecoder.h
> ===================================================================
> --- ImageManager/RawImageDecoder.h (revision 617031)
> +++ ImageManager/RawImageDecoder.h (working copy)
> @@ -19,6 +19,7 @@
> #define RAWIMAGEDECODER_H
>
> #include "ImageDecoder.h"
> +#include <qdict.h>
>
> namespace ImageManager
> {
> @@ -29,6 +30,7 @@
>
> virtual bool _decode(QImage *img, const QString& imageFile, QSize*
> fullSize, int dim=-1); virtual bool _mightDecode( const QString& imageFile
> );
> + virtual bool _skipThisFile( const QDict<void>& loadedFiles, const
> QString& imageFile ); };
>
> }
> _______________________________________________
> KPhotoAlbum mailing list
> KPhotoAlbum at kdab.net
> http://mail.kdab.net/mailman/listinfo/kphotoalbum
More information about the Kphotoalbum
mailing list