diff options
author | Knut Petter Svendsen <knutpett@pvv.org> | 2013-12-05 13:30:20 +0100 |
---|---|---|
committer | Knut Petter Svendsen <knutpett@pvv.org> | 2013-12-05 13:47:25 +0100 |
commit | 0bb76dc984f022ddc7508f783d67d5fb82d6df98 (patch) | |
tree | 54c4a15e873c63a496a285d31a054b148a368343 /src/plugins/clearcase/clearcasesync.cpp | |
parent | 6277bdbff6cb0af84653558cb384d6d542550471 (diff) |
ClearCase: Improved performance for indexing dynamic views
For dynamic views we only at initial sync/indexing check for checked out
files. When a file is opened it will be reindexed if needed. The very time
consuming recursive listing of all vobs is not needed as for snapshot
views.
Change-Id: I83d4ab70efdd311b6f3239ab45569c6d1810e10f
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/plugins/clearcase/clearcasesync.cpp')
-rw-r--r-- | src/plugins/clearcase/clearcasesync.cpp | 172 |
1 files changed, 139 insertions, 33 deletions
diff --git a/src/plugins/clearcase/clearcasesync.cpp b/src/plugins/clearcase/clearcasesync.cpp index 969e7e91e27..769c4707bda 100644 --- a/src/plugins/clearcase/clearcasesync.cpp +++ b/src/plugins/clearcase/clearcasesync.cpp @@ -50,8 +50,7 @@ ClearCaseSync::ClearCaseSync(ClearCasePlugin *plugin, QSharedPointer<StatusMap> { } -QStringList ClearCaseSync::updateStatusHotFiles(const QString &viewRoot, - const bool isDynamic, int &total) +QStringList ClearCaseSync::updateStatusHotFiles(const QString &viewRoot, int &total) { QStringList hotFiles; // find all files whose permissions changed OR hijacked files @@ -64,31 +63,31 @@ QStringList ClearCaseSync::updateStatusHotFiles(const QString &viewRoot, hotFiles.append(it.key()); it.value().status = FileStatus::Unknown; ++total; - } else if (isDynamic && !fi.isWritable()) { // assume a read only file is checked in - it.value().status = FileStatus::CheckedIn; - ++total; } } return hotFiles; } -void ClearCaseSync::updateStatus(const QDir &viewRootDir, const bool isDynamic, +// Set status for all files to unknown until we're done indexing +void ClearCaseSync::invalidateStatus(const QDir &viewRootDir, const QStringList &files) { foreach (const QString &file, files) { - if (isDynamic) { // assume a read only file is checked in - const QFileInfo fi(viewRootDir, file); - if (!fi.isWritable()) - m_plugin->setStatus(fi.absoluteFilePath(), FileStatus::CheckedIn, false); - } else { m_plugin->setStatus(viewRootDir.absoluteFilePath(file), FileStatus::Unknown, false); - } } } -void ClearCaseSync::processLine(const QDir &viewRootDir, const QString &buffer) +void ClearCaseSync::invalidateStatusAllFiles() +{ + const StatusMap::ConstIterator send = m_statusMap->end(); + for (StatusMap::ConstIterator it = m_statusMap->begin(); it != send; ++it) + m_plugin->setStatus(it.key(), FileStatus::Unknown, false); +} + +void ClearCaseSync::processCleartoolLsLine(const QDir &viewRootDir, const QString &buffer) { const int atatpos = buffer.indexOf(QLatin1String("@@")); + if (atatpos == -1) return; @@ -98,6 +97,7 @@ void ClearCaseSync::processLine(const QDir &viewRootDir, const QString &buffer) viewRootDir.absoluteFilePath( QDir::fromNativeSeparators(buffer.left(atatpos))); QTC_CHECK(QFile(absFile).exists()); + QTC_CHECK(!absFile.isEmpty()); QString ccState; const QRegExp reState(QLatin1String("^\\s*\\[[^\\]]*\\]")); // [hijacked]; [loaded but missing] @@ -132,38 +132,26 @@ void ClearCaseSync::updateStatusForNotManagedFiles(const QStringList &files) } } -void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files) +void ClearCaseSync::syncSnapshotView(QFutureInterface<void> &future, QStringList &files, + const ClearCaseSettings &settings) { - ClearCaseSettings settings = m_plugin->settings(); - if (settings.disableIndexer) - return; + QString view = m_plugin->currentView(); - const QString program = settings.ccBinaryPath; - if (program.isEmpty()) - return; int totalFileCount = files.size(); const bool hot = (totalFileCount < 10); int processed = 0; - QString view = m_plugin->currentView(); - if (view.isEmpty()) - emit updateStreamAndView(); if (!hot) totalFileCount = settings.totalFiles.value(view, totalFileCount); - // refresh activities list - if (m_plugin->isUcm()) - m_plugin->refreshActivities(); - - const bool isDynamic = m_plugin->isDynamic(); const QString viewRoot = m_plugin->viewRoot(); const QDir viewRootDir(viewRoot); QStringList args(QLatin1String("ls")); if (hot) { - files << updateStatusHotFiles(viewRoot, isDynamic, totalFileCount); + files << updateStatusHotFiles(viewRoot, totalFileCount); args << files; } else { - updateStatus(viewRootDir, isDynamic, files); + invalidateStatus(viewRootDir, files); args << QLatin1String("-recurse"); QStringList vobs; @@ -181,6 +169,8 @@ void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files) QProcess process; process.setWorkingDirectory(viewRoot); + const QString program = settings.ccBinaryPath; + process.start(program, args); if (!process.waitForStarted()) return; @@ -192,7 +182,7 @@ void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files) const QString line = QString::fromLocal8Bit(process.readLine().constData()); buffer += line; if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) { - processLine(viewRootDir, buffer); + processCleartoolLsLine(viewRootDir, buffer); buffer.clear(); future.setProgressValue(qMin(totalFileCount, ++processed)); } @@ -212,6 +202,82 @@ void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files) process.waitForFinished(); } +void ClearCaseSync::processCleartoolLscheckoutLine(const QString &buffer) +{ + QString absFile = buffer.trimmed(); + m_plugin->setStatus(absFile, FileStatus::CheckedOut, true); +} + +/// +/// Update the file status for dynamic views. +/// +void ClearCaseSync::syncDynamicView(QFutureInterface<void> &future, + const ClearCaseSettings& settings) +{ + // Always invalidate status for all files + invalidateStatusAllFiles(); + + QStringList args(QLatin1String("lscheckout")); + args << QLatin1String("-avobs") + << QLatin1String("-me") + << QLatin1String("-cview") + << QLatin1String("-s"); + + const QString viewRoot = m_plugin->viewRoot(); + + QProcess process; + process.setWorkingDirectory(viewRoot); + + const QString program = settings.ccBinaryPath; + process.start(program, args); + if (!process.waitForStarted()) + return; + + QString buffer; + int processed = 0; + while (process.waitForReadyRead() && !future.isCanceled()) { + while (process.state() == QProcess::Running && + process.bytesAvailable() && !future.isCanceled()) { + const QString line = QString::fromLocal8Bit(process.readLine().constData()); + buffer += line; + if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) { + processCleartoolLscheckoutLine(buffer); + buffer.clear(); + future.setProgressValue(++processed); + } + } + } + + if (process.state() == QProcess::Running) + process.kill(); + + process.waitForFinished(); +} + +void ClearCaseSync::run(QFutureInterface<void> &future, QStringList &files) +{ + ClearCaseSettings settings = m_plugin->settings(); + if (settings.disableIndexer) + return; + + const QString program = settings.ccBinaryPath; + if (program.isEmpty()) + return; + + // refresh activities list + if (m_plugin->isUcm()) + m_plugin->refreshActivities(); + + QString view = m_plugin->currentView(); + if (view.isEmpty()) + emit updateStreamAndView(); + + if (m_plugin->isDynamic()) + syncDynamicView(future, settings); + else + syncSnapshotView(future, files, settings); +} + #ifdef WITH_TESTS namespace { class TempFile @@ -243,14 +309,14 @@ void ClearCaseSync::verifyParseStatus(const QString &fileName, const FileStatus::Status status) { QCOMPARE(m_statusMap->count(), 0); - processLine(QDir(QLatin1String("/")), cleartoolLsLine); + processCleartoolLsLine(QDir(QLatin1String("/")), cleartoolLsLine); if (status == FileStatus::CheckedIn) { // The algorithm doesn't store checked in files in the index, unless it was there already QCOMPARE(m_statusMap->count(), 0); QCOMPARE(m_statusMap->contains(fileName), false); m_plugin->setStatus(fileName, FileStatus::Unknown, false); - processLine(QDir(QLatin1String("/")), cleartoolLsLine); + processCleartoolLsLine(QDir(QLatin1String("/")), cleartoolLsLine); } QCOMPARE(m_statusMap->count(), 1); @@ -274,6 +340,46 @@ void ClearCaseSync::verifyFileNotManaged() QCOMPARE(m_statusMap->value(fileName).status, FileStatus::NotManaged); } +void ClearCaseSync::verifyFileCheckedOutDynamicView() +{ + QCOMPARE(m_statusMap->count(), 0); + + QString fileName(QLatin1String("/hello.C")); + processCleartoolLscheckoutLine(fileName); + + QCOMPARE(m_statusMap->count(), 1); + + QVERIFY(m_statusMap->contains(fileName)); + QCOMPARE(m_statusMap->value(fileName).status, FileStatus::CheckedOut); + + QVERIFY(!m_statusMap->contains(QLatin1String(("notexisting")))); +} + +void ClearCaseSync::verifyFileCheckedInDynamicView() +{ + QCOMPARE(m_statusMap->count(), 0); + + QString fileName(QLatin1String("/hello.C")); + + // checked in files are not kept in the index + QCOMPARE(m_statusMap->count(), 0); + QCOMPARE(m_statusMap->contains(fileName), false); +} + +void ClearCaseSync::verifyFileNotManagedDynamicView() +{ + QCOMPARE(m_statusMap->count(), 0); + TempFile temp(QDir::currentPath() + QLatin1String("/notmanaged.cpp")); + const QString fileName = temp.fileName(); + + updateStatusForNotManagedFiles(QStringList(fileName)); + + QCOMPARE(m_statusMap->count(), 1); + + QVERIFY(m_statusMap->contains(fileName)); + QCOMPARE(m_statusMap->value(fileName).status, FileStatus::NotManaged); +} + #endif |