Implemented a method to disables update signals from the FileList model. This will significantly speed-up adding a lot files, but comes with the drawback that updates won't be visible immediately.

This commit is contained in:
LoRd_MuldeR 2012-05-05 21:56:14 +02:00
parent 160b997c76
commit a7a776ed82
9 changed files with 68 additions and 16 deletions

View File

@ -20,6 +20,7 @@ a:visited { color: #0000EE; }
<li>Added Swedish translation, thanks to Åke Engelbrektson &lt;eson57@gmail.com&gt; <li>Added Swedish translation, thanks to Åke Engelbrektson &lt;eson57@gmail.com&gt;
<li>Implemented multi-threading in initialization code for faster application startup <li>Implemented multi-threading in initialization code for faster application startup
<li>Implemented multi-threading in file analyzer for faster file import <li>Implemented multi-threading in file analyzer for faster file import
<li>Fixed a potential crash (stack overflow) when adding a huge number of files
</ul><br> </ul><br>
<a name="4.04"></a>Changes between v4.03 and v4.04 [2012-04-26]:<br><ul> <a name="4.04"></a>Changes between v4.03 and v4.04 [2012-04-26]:<br><ul>

View File

@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 5 #define VER_LAMEXP_MINOR_LO 5
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 1 #define VER_LAMEXP_PATCH 1
#define VER_LAMEXP_BUILD 1005 #define VER_LAMEXP_BUILD 1008
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tool versions (minimum expected versions!) // Tool versions (minimum expected versions!)

View File

@ -519,7 +519,22 @@ void MainWindow::addFiles(const QStringList &files)
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection); connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection); connect(m_banner, SIGNAL(userAbort()), analyzer, SLOT(abortProcess()), Qt::DirectConnection);
m_banner->show(tr("Adding file(s), please wait..."), analyzer); try
{
m_fileListModel->setBlockUpdates(true);
m_banner->show(tr("Adding file(s), please wait..."), analyzer);
}
catch(...)
{
/* ignore any exceptions that may occur */
}
m_fileListModel->setBlockUpdates(false);
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
sourceFileView->update();
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
sourceFileView->scrollToBottom();
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
if(analyzer->filesDenied()) if(analyzer->filesDenied())
{ {
@ -539,7 +554,6 @@ void MainWindow::addFiles(const QStringList &files)
} }
LAMEXP_DELETE(analyzer); LAMEXP_DELETE(analyzer);
sourceFileView->scrollToBottom();
m_banner->close(); m_banner->close();
} }

View File

@ -50,7 +50,7 @@ WorkingBanner::WorkingBanner(QWidget *parent)
//Start animation //Start animation
m_working = new QMovie(":/images/Busy.gif"); m_working = new QMovie(":/images/Busy.gif");
m_working->setSpeed(25); m_working->setSpeed(50);
labelWorking->setMovie(m_working); labelWorking->setMovie(m_working);
m_working->start(); m_working->start();

View File

@ -40,6 +40,7 @@
FileListModel::FileListModel(void) FileListModel::FileListModel(void)
: :
m_blockUpdates(false),
m_fileIcon(":/icons/page_white_cd.png") m_fileIcon(":/icons/page_white_cd.png")
{ {
} }
@ -138,26 +139,28 @@ void FileListModel::addFile(const QString &filePath)
{ {
QFileInfo fileInfo(filePath); QFileInfo fileInfo(filePath);
const QString key = MAKE_KEY(fileInfo.canonicalFilePath()); const QString key = MAKE_KEY(fileInfo.canonicalFilePath());
const bool flag = (!m_blockUpdates);
if(!m_fileStore.contains(key)) if(!m_fileStore.contains(key))
{ {
beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count()); if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
m_fileStore.insert(key, AudioFileModel(fileInfo.canonicalFilePath(), fileInfo.baseName())); m_fileStore.insert(key, AudioFileModel(fileInfo.canonicalFilePath(), fileInfo.baseName()));
m_fileList.append(key); m_fileList.append(key);
endInsertRows(); if(flag) endInsertRows();
} }
} }
void FileListModel::addFile(const AudioFileModel &file) void FileListModel::addFile(const AudioFileModel &file)
{ {
const QString key = MAKE_KEY(file.filePath()); const QString key = MAKE_KEY(file.filePath());
const bool flag = (!m_blockUpdates);
if(!m_fileStore.contains(key)) if(!m_fileStore.contains(key))
{ {
beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count()); if(flag) beginInsertRows(QModelIndex(), m_fileList.count(), m_fileList.count());
m_fileStore.insert(key, file); m_fileStore.insert(key, file);
m_fileList.append(key); m_fileList.append(key);
endInsertRows(); if(flag) endInsertRows();
} }
} }

View File

@ -65,11 +65,19 @@ public:
} }
CsvError; CsvError;
//Speed hacks
void setBlockUpdates(bool flag)
{
m_blockUpdates = flag;
if(!flag) reset();
}
public slots: public slots:
void addFile(const QString &filePath); void addFile(const QString &filePath);
void addFile(const AudioFileModel &file); void addFile(const AudioFileModel &file);
private: private:
bool m_blockUpdates;
QList<QString> m_fileList; QList<QString> m_fileList;
QHash<QString, AudioFileModel> m_fileStore; QHash<QString, AudioFileModel> m_fileStore;
const QIcon m_fileIcon; const QIcon m_fileIcon;

View File

@ -143,13 +143,18 @@ void FileAnalyzer::run()
while(!pool->tryStart(task)) while(!pool->tryStart(task))
{ {
AnalyzeTask::waitForOneThread(1250); if(!AnalyzeTask::waitForOneThread(1250))
{
qWarning("FileAnalyzer::run() -> Timeout !!!");
}
if(m_abortFlag) if(m_abortFlag)
{ {
LAMEXP_DELETE(task); LAMEXP_DELETE(task);
break; break;
} }
QThread::yieldCurrentThread();
} }
if(m_abortFlag) if(m_abortFlag)

View File

@ -80,7 +80,7 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile,
AnalyzeTask::~AnalyzeTask(void) AnalyzeTask::~AnalyzeTask(void)
{ {
QWriteLocker lock(&s_lock); QWriteLocker lock(&s_lock);
s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1); s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
s_waitCond.wakeAll(); s_waitCond.wakeAll();
} }
@ -88,7 +88,23 @@ AnalyzeTask::~AnalyzeTask(void)
// Thread Main // Thread Main
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void AnalyzeTask::run(void) void AnalyzeTask::run()
{
try
{
run_ex();
}
catch(...)
{
qWarning("WARNING: Caught an in exception AnalyzeTask thread!");
}
QWriteLocker lock(&s_lock);
s_threadIdx_finished = qMax(s_threadIdx_finished, m_threadIdx + 1ui64);
s_waitCond.wakeAll();
}
void AnalyzeTask::run_ex(void)
{ {
int fileType = fileTypeNormal; int fileType = fileTypeNormal;
QString currentFile = QDir::fromNativeSeparators(m_inputFile); QString currentFile = QDir::fromNativeSeparators(m_inputFile);
@ -707,7 +723,10 @@ void AnalyzeTask::waitForPreviousThreads(void)
} }
lock.unlock(); lock.unlock();
waitForOneThread(1250); if(!AnalyzeTask::waitForOneThread(1250))
{
qWarning("AnalyzeTask::waitForPreviousThreads -> Timeout !!!");
}
} }
} }

View File

@ -54,20 +54,22 @@ public:
static unsigned int filesCueSheet(void); static unsigned int filesCueSheet(void);
//Wait till the next running thread terminates //Wait till the next running thread terminates
static void waitForOneThread(unsigned long timeout) static __forceinline bool waitForOneThread(unsigned long timeout)
{ {
bool ret = false;
s_waitMutex.lock(); s_waitMutex.lock();
s_waitCond.wait(&s_waitMutex, timeout); ret = s_waitCond.wait(&s_waitMutex, timeout);
s_waitMutex.unlock(); s_waitMutex.unlock();
return ret;
} }
void run(void);
signals: signals:
void fileSelected(const QString &fileName); void fileSelected(const QString &fileName);
void fileAnalyzed(const AudioFileModel &file); void fileAnalyzed(const AudioFileModel &file);
protected: protected:
void run(void);
void run_ex(void);
private: private:
enum cover_t enum cover_t