logic: allow the user to discard an aborted indexer run

* keep old database on filesystem while indexing
* migrate old ".coatiproject" settings to new ".srctrlprj" extension when loading project
* send new errors in MessageErrorCountUpdate after injecting
* recheck filepath exist() in FileSystem's remove, rename, copy and create functions
* updated tasks to new "override" policy
This commit is contained in:
mlangkabel
2018-07-03 18:54:53 +02:00
parent c8a885be83
commit a1dd1a77c9
41 changed files with 434 additions and 215 deletions
+49 -16
View File
@@ -1,5 +1,17 @@
#include "Application.h"
#include "component/controller/IDECommunicationController.h"
#include "component/NetworkFactory.h"
#include "component/view/DialogView.h"
#include "component/view/GraphViewStyle.h"
#include "component/view/MainView.h"
#include "component/view/ViewFactory.h"
#include "data/storage/StorageCache.h"
#include "LicenseChecker.h"
#include "settings/ApplicationSettings.h"
#include "settings/ProjectSettings.h"
#include "settings/ColorScheme.h"
#include "utility/file/FileSystem.h"
#include "utility/interprocess/SharedMemoryGarbageCollector.h"
#include "utility/logging/logging.h"
#include "utility/logging/LogManager.h"
@@ -16,18 +28,6 @@
#include "utility/utilityString.h"
#include "utility/utilityUuid.h"
#include "utility/Version.h"
#include "component/controller/IDECommunicationController.h"
#include "component/NetworkFactory.h"
#include "component/view/DialogView.h"
#include "component/view/GraphViewStyle.h"
#include "component/view/MainView.h"
#include "component/view/ViewFactory.h"
#include "data/storage/StorageCache.h"
#include "LicenseChecker.h"
#include "settings/ApplicationSettings.h"
#include "settings/ProjectSettings.h"
#include "settings/ColorScheme.h"
#include "UpdateChecker.h"
std::shared_ptr<Application> Application::s_instance;
@@ -85,6 +85,9 @@ std::shared_ptr<Application> Application::getInstance()
void Application::destroyInstance()
{
MessageQueue::getInstance()->stopMessageLoop();
TaskScheduler::getInstance()->stopSchedulerLoop();
s_instance.reset();
}
@@ -126,9 +129,6 @@ Application::Application(bool withGUI)
Application::~Application()
{
MessageQueue::getInstance()->stopMessageLoop();
TaskScheduler::getInstance()->stopSchedulerLoop();
if (m_hasGUI)
{
m_mainView->saveLayout();
@@ -191,9 +191,12 @@ void Application::updateBookmarks(const std::vector<std::shared_ptr<Bookmark>>&
m_mainView->updateBookmarksMenu(bookmarks);
}
void Application::createAndLoadProject(const FilePath& projectSettingsFilePath)
void Application::createAndLoadProject(FilePath projectSettingsFilePath)
{
MessageStatus(L"Loading Project: " + projectSettingsFilePath.wstr(), false, true).dispatch();
projectSettingsFilePath = migrateProjectSettings(projectSettingsFilePath);
try
{
updateRecentProjects(projectSettingsFilePath);
@@ -354,6 +357,36 @@ void Application::handleMessage(MessageWindowFocus* message)
}
}
FilePath Application::migrateProjectSettings(const FilePath& projectSettingsFilePath) const
{
if (projectSettingsFilePath.extension() == L".coatiproject")
{
MessageStatus(L"Migrating deprecated project file extension \".coatiproject\" to new file extension \".srctrlprj\"").dispatch();
const FilePath newSettingsPath = projectSettingsFilePath.replaceExtension(Project::PROJECT_FILE_EXTENSION);
{
FileSystem::rename(projectSettingsFilePath, newSettingsPath);
const FilePath oldDbPath = projectSettingsFilePath.replaceExtension(L"coatidb");
if (oldDbPath.exists())
{
FileSystem::rename(oldDbPath, oldDbPath.replaceExtension(L"srctrldb"));
}
}
{
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
std::vector<FilePath> recentProjects = appSettings->getRecentProjects();
std::vector<FilePath>::iterator it = std::find(recentProjects.begin(), recentProjects.end(), projectSettingsFilePath);
if (it != recentProjects.end())
{
recentProjects.erase(it);
}
appSettings->setRecentProjects(recentProjects);
appSettings->save(UserPaths::getAppSettingsPath());
}
return newSettingsPath;
}
return projectSettingsFilePath;
}
void Application::startMessagingAndScheduling()
{
TaskScheduler::getInstance()->startSchedulerLoopThreaded();
+2 -1
View File
@@ -47,7 +47,7 @@ public:
const std::shared_ptr<Project> getCurrentProject();
void createAndLoadProject(const FilePath& projectSettingsFilePath);
void createAndLoadProject(FilePath projectSettingsFilePath);
void refreshProject(RefreshMode refreshMode);
bool hasGUI();
@@ -74,6 +74,7 @@ private:
virtual void handleMessage(MessageSwitchColorScheme* message);
virtual void handleMessage(MessageWindowFocus* message);
FilePath migrateProjectSettings(const FilePath& projectSettingsFilePath) const;
void startMessagingAndScheduling();
void updateRecentProjects(const FilePath& projectSettingsFilePath);
+2
View File
@@ -519,6 +519,8 @@ add_files(
utility/scheduling/TaskDecoratorRepeat.h
utility/scheduling/TaskDecoratorDelay.cpp
utility/scheduling/TaskDecoratorDelay.h
utility/scheduling/TaskFindValue.cpp
utility/scheduling/TaskFindValue.h
utility/scheduling/TaskGroup.cpp
utility/scheduling/TaskGroup.h
utility/scheduling/TaskGroupParallel.cpp
@@ -84,16 +84,22 @@ void ErrorController::handleMessage(MessageErrorCountUpdate* message)
if (room > 0)
{
filter.limit = 0;
std::vector<ErrorInfo> errors = m_storageAccess->getErrorsLimited(filter);
ErrorCountInfo errorCount(errors);
std::vector<ErrorInfo> errors;
auto startIt = errors.begin() + m_errorCount;
errors = std::vector<ErrorInfo>(
startIt,
(errors.size() < m_errorCount + room) ? errors.end() : startIt + room
);
for (const ErrorInfo& error : message->newErrors)
{
if (filter.filter(error))
{
errors.push_back(error);
getView()->addErrors(errors, errorCount, true);
if (room > 0 && errors.size() >= size_t(room))
{
break;
}
}
}
getView()->addErrors(errors, message->errorCount, true);
getView()->showDockWidget();
m_errorCount += errors.size();
+2 -1
View File
@@ -35,10 +35,11 @@ void DialogView::updateIndexingDialog(
{
}
void DialogView::finishedIndexingDialog(
DatabasePolicy DialogView::finishedIndexingDialog(
size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount,
float time, ErrorCountInfo errorInfo, bool interrupted)
{
return DATABASE_POLICY_KEEP; // used in non-gui mode
}
void DialogView::hideDialogs(bool unblockUI)
+8 -1
View File
@@ -10,6 +10,13 @@
class Project;
class StorageAccess;
enum DatabasePolicy
{
DATABASE_POLICY_KEEP,
DATABASE_POLICY_DISCARD,
DATABASE_POLICY_UNKNOWN
};
class DialogView
{
public:
@@ -26,7 +33,7 @@ public:
Project* project, const std::vector<RefreshMode>& enabledModes, const RefreshInfo& info);
virtual void updateIndexingDialog(
size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const FilePath& sourcePath);
virtual void finishedIndexingDialog(
virtual DatabasePolicy finishedIndexingDialog(
size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount,
float time, ErrorCountInfo errorInfo, bool interrupted);
+4 -4
View File
@@ -21,10 +21,10 @@ public:
);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
PersistentStorage* m_storage;
std::vector<FilePath> m_filePaths;
+26 -26
View File
@@ -10,17 +10,21 @@
#include "utility/utilityString.h"
#include "Application.h"
TaskFinishParsing::TaskFinishParsing(
PersistentStorage* storage,
StorageAccess* storageAccess
)
TaskFinishParsing::TaskFinishParsing(std::shared_ptr<PersistentStorage> storage)
: m_storage(storage)
, m_storageAccess(storageAccess)
{
}
TaskFinishParsing::~TaskFinishParsing()
void TaskFinishParsing::terminate()
{
Application* app = Application::getInstance().get();
if (app)
{
app->getDialogView()->hideDialogs();
}
MessageStatus(L"An unknown exception was thrown during indexing.", true, false).dispatch();
MessageFinishedParsing().dispatch();
}
void TaskFinishParsing::doEnter(std::shared_ptr<Blackboard> blackboard)
@@ -36,12 +40,7 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr<Blackboard> blackboa
dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Optimizing database");
m_storage->optimizeMemory();
dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Building caches");
m_storage->buildCaches();
dialogView->hideUnknownProgressDialog();
MessageFinishedParsing().dispatch();
float time = utility::duration(start);
@@ -68,7 +67,7 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr<Blackboard> blackboa
bool interruptedIndexing = false;
blackboard->get("interrupted_indexing", interruptedIndexing);
ErrorCountInfo errorInfo = m_storageAccess->getErrorCount();
ErrorCountInfo errorInfo = m_storage->getErrorCount();
std::wstring status;
status += L"Finished indexing: ";
@@ -81,8 +80,8 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr<Blackboard> blackboa
}
MessageStatus(status, false, false).dispatch();
StorageStats stats = m_storageAccess->getStorageStats();
dialogView->finishedIndexingDialog(
StorageStats stats = m_storage->getStorageStats();
DatabasePolicy policy = dialogView->finishedIndexingDialog(
indexedSourceFileCount,
sourceFileCount,
stats.completedFileCount,
@@ -92,6 +91,19 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr<Blackboard> blackboa
interruptedIndexing
);
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
if (policy == DATABASE_POLICY_KEEP)
{
blackboard->set("keep_database", true);
}
else if (policy == DATABASE_POLICY_DISCARD)
{
blackboard->set("discard_database", true);
}
}
return STATE_SUCCESS;
}
@@ -102,15 +114,3 @@ void TaskFinishParsing::doExit(std::shared_ptr<Blackboard> blackboard)
void TaskFinishParsing::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
void TaskFinishParsing::terminate()
{
Application* app = Application::getInstance().get();
if (app)
{
app->getDialogView()->hideDialogs();
}
MessageStatus(L"An unknown exception was thrown during indexing.", true, false).dispatch();
MessageFinishedParsing().dispatch();
}
+7 -12
View File
@@ -14,22 +14,17 @@ class TaskFinishParsing
: public Task
{
public:
TaskFinishParsing(
PersistentStorage* storage,
StorageAccess* storageAccess
);
TaskFinishParsing(std::shared_ptr<PersistentStorage> storage);
virtual ~TaskFinishParsing();
void terminate() override;
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void terminate();
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
PersistentStorage* m_storage;
StorageAccess* m_storageAccess;
std::shared_ptr<PersistentStorage> m_storage;
};
#endif // TASK_FINISH_PARSING_H
+4 -4
View File
@@ -18,10 +18,10 @@ public:
);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
std::shared_ptr<StorageProvider> m_storageProvider;
std::shared_ptr<Storage> m_target;
+4 -4
View File
@@ -16,10 +16,10 @@ public:
);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
std::shared_ptr<StorageProvider> m_storageProvider;
};
@@ -12,10 +12,6 @@ TaskShowUnknownProgressDialog::TaskShowUnknownProgressDialog(
{
}
TaskShowUnknownProgressDialog::~TaskShowUnknownProgressDialog()
{
}
void TaskShowUnknownProgressDialog::doEnter(std::shared_ptr<Blackboard> blackboard)
{
}
+4 -6
View File
@@ -14,13 +14,11 @@ public:
const std::wstring& message
);
virtual ~TaskShowUnknownProgressDialog();
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
const std::wstring m_title;
const std::wstring m_message;
+13 -5
View File
@@ -233,9 +233,12 @@ void PersistentStorage::finishInjection()
{
m_sqliteIndexStorage.commitTransaction();
if (m_preInjectionErrorCount != m_sqliteIndexStorage.getErrorCount())
std::vector<ErrorInfo> errors = m_sqliteIndexStorage.getAll<StorageError>();
if (m_preInjectionErrorCount < errors.size())
{
MessageErrorCountUpdate(getErrorCount()).dispatch();
ErrorCountInfo errorCount(errors);
errors.erase(errors.begin(), errors.begin() + m_preInjectionErrorCount);
MessageErrorCountUpdate(errorCount, errors).dispatch();
}
}
@@ -244,11 +247,16 @@ void PersistentStorage::setMode(const SqliteIndexStorage::StorageModeType mode)
m_sqliteIndexStorage.setMode(mode);
}
FilePath PersistentStorage::getDbFilePath() const
FilePath PersistentStorage::getIndexDbFilePath() const
{
return m_sqliteIndexStorage.getDbFilePath();
}
FilePath PersistentStorage::getBookmarkDbFilePath() const
{
return m_sqliteBookmarkStorage.getDbFilePath();
}
bool PersistentStorage::isEmpty() const
{
return m_sqliteIndexStorage.isEmpty();
@@ -430,7 +438,7 @@ void PersistentStorage::optimizeMemory()
m_sqliteIndexStorage.setTime();
m_sqliteIndexStorage.optimizeMemory();
m_sqliteBookmarkStorage.optimizeMemory();
}
@@ -2758,7 +2766,7 @@ void PersistentStorage::buildSearchIndex()
{
TRACE();
const FilePath dbPath = getDbFilePath();
const FilePath dbPath = getIndexDbFilePath();
for (StorageNode& node : m_sqliteIndexStorage.getAll<StorageNode>())
{
+3 -2
View File
@@ -47,7 +47,8 @@ public:
void setMode(const SqliteIndexStorage::StorageModeType mode);
FilePath getDbFilePath() const;
FilePath getIndexDbFilePath() const;
FilePath getBookmarkDbFilePath() const;
bool isEmpty() const;
bool isIncompatible() const;
@@ -190,7 +191,7 @@ private:
void buildMemberEdgeIdOrderMap();
void buildHierarchyCache();
int m_preInjectionErrorCount = 0;
size_t m_preInjectionErrorCount = 0;
SearchIndex m_commandIndex;
SearchIndex m_symbolIndex;
+117 -34
View File
@@ -27,9 +27,11 @@
#include "utility/messaging/type/MessageRefresh.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/scheduling/TaskDecoratorRepeat.h"
#include "utility/scheduling/TaskFindValue.h"
#include "utility/scheduling/TaskGroupSelector.h"
#include "utility/scheduling/TaskGroupSequence.h"
#include "utility/scheduling/TaskGroupParallel.h"
#include "utility/scheduling/TaskLambda.h"
#include "utility/scheduling/TaskReturnSuccessWhile.h"
#include "utility/scheduling/TaskSetValue.h"
#include "utility/ScopedFunctor.h"
@@ -38,6 +40,12 @@
#include "utility/utilityApp.h"
#include "utility/utilityFile.h"
#include "utility/utilityString.h"
#include "Application.h"
const std::wstring Project::PROJECT_FILE_EXTENSION = L".srctrlprj";
const std::wstring Project::BOOKMARK_DB_FILE_EXTENSION = L".srctrlbm";
const std::wstring Project::INDEX_DB_FILE_EXTENSION = L".srctrldb";
const std::wstring Project::TEMP_INDEX_DB_FILE_EXTENSION = L".srctrldb_tmp";
Project::Project(std::shared_ptr<ProjectSettings> settings, StorageCache* storageCache, bool hasGUI)
: m_settings(settings)
@@ -76,22 +84,49 @@ void Project::setStateOutdated()
void Project::load()
{
m_storageCache->clear();
m_storageCache->setSubject(nullptr);
bool loadedSettings = m_settings->reload();
if (!loadedSettings)
if (!m_settings->reload())
{
return;
}
const FilePath projectSettingsPath = m_settings->getFilePath();
const std::wstring dbExtension = (projectSettingsPath.extension() == L".coatiproject" ? L"coatidb" : L"srctrldb");
const FilePath dbPath = FilePath(projectSettingsPath).replaceExtension(dbExtension);
const FilePath bookmarkPath = FilePath(projectSettingsPath).replaceExtension(L"srctrlbm");
{
const FilePath dbPath = projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION);
const FilePath tempDbPath = projectSettingsPath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION);
if (tempDbPath.exists())
{
if (dbPath.exists())
{
if (Application::getInstance()->getDialogView()->confirm(
"Sourcetrail has been closed unexpectedly while indexing this project. You can either choose to keep the data that has "
"already been indexed or discard that data and restore the state of your project before indexing?", { "Keep and Continue", "Discard and Restore" }) == 0)
{
LOG_INFO("Switching to temporary indexing data on user's decision");
FileSystem::remove(dbPath);
FileSystem::rename(tempDbPath, dbPath);
}
else
{
LOG_INFO("Discarding temporary indexing data on user's decision");
FileSystem::remove(tempDbPath);
}
}
else
{
LOG_INFO("Switching to temporary indexing data because no other persistent data was found");
FileSystem::rename(tempDbPath, dbPath);
}
}
}
m_storage = std::make_shared<PersistentStorage>(dbPath, bookmarkPath);
m_storage = std::make_shared<PersistentStorage>(
projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION),
projectSettingsPath.replaceExtension(BOOKMARK_DB_FILE_EXTENSION)
);
bool canLoad = false;
@@ -233,10 +268,7 @@ void Project::refresh(RefreshMode refreshMode, DialogView* dialogView)
if (question.size() && m_hasGUI)
{
std::vector<std::string> options = { "Yes", "No" };
int result = dialogView->confirm(question, options);
if (result == 1)
if (dialogView->confirm(question, { "Yes", "No" }) == 1)
{
return;
}
@@ -245,14 +277,10 @@ void Project::refresh(RefreshMode refreshMode, DialogView* dialogView)
if (ApplicationSettings::getInstance()->getLoggingEnabled() &&
ApplicationSettings::getInstance()->getVerboseIndexerLoggingEnabled() && m_hasGUI)
{
std::vector<std::string> options = { "Yes", "No" };
int result = dialogView->confirm(
"Warning: You are about to index your project with the \"verbose indexer logging\" setting "
"enabled. This will cause a significant slowdown in indexing performance. Do you want to proceed?",
options
);
if (result == 1)
if (dialogView->confirm(
"Warning: You are about to index your project with the \"verbose indexer logging\" setting "
"enabled. This will cause a significant slowdown in indexing performance. Do you want to proceed?",
{ "Yes", "No" }) == 1)
{
return;
}
@@ -346,25 +374,33 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView)
dialogView->showUnknownProgressDialog(L"Preparing Indexing", L"Setting up Indexers");
m_storageCache->clear();
m_storageCache->setSubject(m_storage.get());
const FilePath indexDbFilePath = m_storage->getIndexDbFilePath();
const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION);
if (info.mode != REFRESH_ALL_FILES)
{
FileSystem::copyFile(indexDbFilePath, tempIndexDbFilePath);
}
std::shared_ptr<PersistentStorage> tempStorage = std::make_shared<PersistentStorage>(tempIndexDbFilePath, m_storage->getBookmarkDbFilePath());
tempStorage->setup();
std::shared_ptr<TaskGroupSequence> taskSequential = std::make_shared<TaskGroupSequence>();
if (info.mode == REFRESH_ALL_FILES)
{
m_storage->clear();
}
else if (info.filesToClear.size() || info.nonIndexedFilesToClear.size())
if (info.mode != REFRESH_ALL_FILES && (info.filesToClear.size() || info.nonIndexedFilesToClear.size()))
{
taskSequential->addTask(std::make_shared<TaskCleanStorage>(
m_storage.get(),
tempStorage.get(),
utility::toVector(utility::concat(info.filesToClear, info.nonIndexedFilesToClear)),
info.mode == REFRESH_UPDATED_AND_INCOMPLETE_FILES
));
}
m_storageCache->clear();
m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath())->getText());
m_storage->updateVersion();
tempStorage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath())->getText());
tempStorage->updateVersion();
std::shared_ptr<IndexerCommandList> indexerCommandList = std::make_shared<IndexerCommandList>();
for (const std::shared_ptr<SourceGroup>& sourceGroup : m_sourceGroups)
@@ -402,7 +438,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView)
taskSequential->addTask(std::make_shared<TaskSetValue<int>>("indexed_source_file_count", 0));
taskSequential->addTask(std::make_shared<TaskSetValue<int>>("indexer_count", 0));
std::shared_ptr<TaskParseWrapper> taskParserWrapper = std::make_shared<TaskParseWrapper>(m_storage.get());
std::shared_ptr<TaskParseWrapper> taskParserWrapper = std::make_shared<TaskParseWrapper>(tempStorage.get());
taskSequential->addTask(taskParserWrapper);
std::shared_ptr<TaskGroupParallel> taskParallelIndexing = std::make_shared<TaskGroupParallel>();
@@ -443,7 +479,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView)
// stopping when indexer count is zero, regardless wether there are still storages left to insert.
std::make_shared<TaskReturnSuccessWhile<int>>("indexer_count", TaskReturnSuccessWhile<int>::CONDITION_GREATER_THAN, 0),
std::make_shared<TaskGroupSelector>()->addChildTasks(
std::make_shared<TaskInjectStorage>(storageProvider, m_storage),
std::make_shared<TaskInjectStorage>(storageProvider, tempStorage),
// continuing when indexer count is greater than zero, even if there are no storages right now.
std::make_shared<TaskReturnSuccessWhile<int>>("indexer_count", TaskReturnSuccessWhile<int>::CONDITION_GREATER_THAN, 0)
)
@@ -459,7 +495,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView)
// add task that injects the remaining intermediate storages into the persistent storage
taskSequential->addTask(
std::make_shared<TaskDecoratorRepeat>(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask(
std::make_shared<TaskInjectStorage>(storageProvider, m_storage)
std::make_shared<TaskInjectStorage>(storageProvider, tempStorage)
)
);
}
@@ -468,12 +504,59 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView)
dialogView->hideUnknownProgressDialog();
}
taskSequential->addTask(std::make_shared<TaskFinishParsing>(m_storage.get(), m_storageCache));
taskSequential->addTask(std::make_shared<TaskFinishParsing>(tempStorage));
taskSequential->addTask(std::make_shared<TaskGroupSelector>()->addChildTasks(
std::make_shared<TaskGroupSequence>()->addChildTasks(
std::make_shared<TaskFindValue>("keep_database"),
std::make_shared<TaskLambda>([this]() {
Task::dispatch(std::make_shared<TaskLambda>([this]() {
swapToTempStorage();
m_state = PROJECT_STATE_LOADED;
}));
})
),
std::make_shared<TaskGroupSequence>()->addChildTasks(
std::make_shared<TaskFindValue>("discard_database"),
std::make_shared<TaskLambda>([this]() {
Task::dispatch(std::make_shared<TaskLambda>([this]() {
const FilePath tempIndexDbPath = m_storage->getIndexDbFilePath().replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION);
if (tempIndexDbPath.exists())
{
LOG_INFO("Discarding temporary indexing data");
FileSystem::remove(tempIndexDbPath);
}
}));
})
)
));
taskSequential->addTask(std::make_shared<TaskLambda>([]() {
MessageFinishedParsing().dispatch();
}));
Task::dispatch(taskSequential);
}
void Project::swapToTempStorage()
{
LOG_INFO("Switching to temporary indexing data");
const FilePath indexDbFilePath = m_storage->getIndexDbFilePath();
const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION);
const FilePath bookmarkDbFilePath = m_storage->getBookmarkDbFilePath();
m_storage.reset();
FileSystem::remove(indexDbFilePath);
FileSystem::rename(tempIndexDbFilePath, indexDbFilePath);
m_storage = std::make_shared<PersistentStorage>(indexDbFilePath, bookmarkDbFilePath);
m_storage->setup();
//std::shared_ptr<DialogView> dialogView = Application::getInstance()->getDialogView();
//dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Building caches");
m_storage->buildCaches();
//dialogView->hideUnknownProgressDialog();
m_storageCache->setSubject(m_storage.get());
m_state = PROJECT_STATE_LOADED;
}
bool Project::hasCxxSourceGroup() const
+6
View File
@@ -19,6 +19,11 @@ class StorageCache;
class Project
{
public:
static const std::wstring PROJECT_FILE_EXTENSION;
static const std::wstring BOOKMARK_DB_FILE_EXTENSION;
static const std::wstring INDEX_DB_FILE_EXTENSION;
static const std::wstring TEMP_INDEX_DB_FILE_EXTENSION;
Project(std::shared_ptr<ProjectSettings> settings, StorageCache* storageCache, bool hasGUI);
virtual ~Project();
@@ -50,6 +55,7 @@ private:
Project(const Project&);
void swapToTempStorage();
bool hasCxxSourceGroup() const;
bool didFileChange(const FileInfo& info) const;
+2 -2
View File
@@ -1,5 +1,6 @@
#include "settings/ProjectSettings.h"
#include "project/Project.h"
#include "settings/migration/SettingsMigrationDeleteKey.h"
#include "settings/migration/SettingsMigrationLambda.h"
#include "settings/migration/SettingsMigrationMoveKey.h"
@@ -17,7 +18,6 @@
#include "utility/utilityUuid.h"
const size_t ProjectSettings::VERSION = 7;
const wchar_t PROJECT_FILE_EXTENSION[] = L".srctrlprj";
LanguageType ProjectSettings::getLanguageOfProject(const FilePath& filePath)
{
@@ -115,7 +115,7 @@ FilePath ProjectSettings::getProjectFilePath() const
void ProjectSettings::setProjectFilePath(std::wstring projectName, const FilePath& projectFileLocation)
{
setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + PROJECT_FILE_EXTENSION));
setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + Project::PROJECT_FILE_EXTENSION));
}
std::wstring ProjectSettings::getProjectName() const
+10 -4
View File
@@ -203,45 +203,51 @@ TimeStamp FileSystem::getLastWriteTime(const FilePath& filePath)
bool FileSystem::remove(const FilePath& path)
{
return boost::filesystem::remove(path.getPath());
const bool ret = boost::filesystem::remove(path.getPath());
path.recheckExists();
return ret;
}
bool FileSystem::rename(const FilePath& from, const FilePath& to)
{
if (!from.exists() || to.exists())
if (!from.recheckExists() || to.recheckExists())
{
return false;
}
boost::filesystem::rename(from.getPath(), to.getPath());
to.recheckExists();
return true;
}
bool FileSystem::copyFile(const FilePath& from, const FilePath& to)
{
if (!from.exists() || to.exists())
if (!from.recheckExists() || to.recheckExists())
{
return false;
}
boost::filesystem::copy_file(from.getPath(), to.getPath());
to.recheckExists();
return true;
}
bool FileSystem::copy_directory(const FilePath& from, const FilePath& to)
{
if (!from.exists() || to.exists())
if (!from.recheckExists() || to.recheckExists())
{
return false;
}
boost::filesystem::copy_directory(from.getPath(), to.getPath());
to.recheckExists();
return true;
}
void FileSystem::createDirectory(const FilePath& path)
{
boost::filesystem::create_directories(path.str());
path.recheckExists();
}
std::vector<FilePath> FileSystem::getDirectSubDirectories(const FilePath& path)
@@ -21,6 +21,15 @@ class MessageFilterErrorCountUpdate
{
if ((*it)->getType() == MessageErrorCountUpdate::getStaticType())
{
MessageErrorCountUpdate* frontErrorsMessage = dynamic_cast<MessageErrorCountUpdate*>(message);
MessageErrorCountUpdate* backErrorsMessage = dynamic_cast<MessageErrorCountUpdate*>(it->get());
backErrorsMessage->newErrors.insert(
backErrorsMessage->newErrors.begin(),
frontErrorsMessage->newErrors.begin(),
frontErrorsMessage->newErrors.end()
);
messageBuffer->pop_front();
return;
}
@@ -14,13 +14,20 @@ public:
return "MessageErrorCountUpdate";
}
MessageErrorCountUpdate(const ErrorCountInfo& errorCount)
MessageErrorCountUpdate(const ErrorCountInfo& errorCount, const std::vector<ErrorInfo>& newErrors)
: errorCount(errorCount)
, newErrors(newErrors)
{
setSendAsTask(false);
}
virtual void print(std::wostream& os) const
{
os << errorCount.total << '/' << errorCount.fatal << L" - " << newErrors.size() << L" new errors";
}
const ErrorCountInfo errorCount;
std::vector<ErrorInfo> newErrors;
};
#endif // MESSAGE_ERROR_COUNT_UPDATE_H
@@ -6,10 +6,6 @@ TaskDecorator::TaskDecorator()
{
}
TaskDecorator::~TaskDecorator()
{
}
std::shared_ptr<TaskDecorator> TaskDecorator::addChildTask(std::shared_ptr<Task> child)
{
setTask(child);
+1 -2
View File
@@ -13,11 +13,10 @@ class TaskDecorator
{
public:
TaskDecorator();
virtual ~TaskDecorator();
std::shared_ptr<TaskDecorator> addChildTask(std::shared_ptr<Task> child);
virtual void setTask(std::shared_ptr<Task> task);
virtual void terminate();
void terminate() override;
protected:
std::shared_ptr<TaskRunner> m_taskRunner;
@@ -14,11 +14,11 @@ public:
TaskDecoratorDelay(size_t delayMS);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void doTerminate();
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
void doTerminate() override;
const size_t m_delayMS;
@@ -18,10 +18,10 @@ public:
TaskDecoratorRepeat(ConditionType condition, TaskState exitState);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
const ConditionType m_condition;
const TaskState m_exitState;
@@ -0,0 +1,26 @@
#include "utility/scheduling/TaskFindValue.h"
#include "utility/scheduling/Blackboard.h"
TaskFindValue::TaskFindValue(const std::string& valueName)
: m_valueName(valueName)
{
}
void TaskFindValue::doEnter(std::shared_ptr<Blackboard> blackboard)
{
}
Task::TaskState TaskFindValue::doUpdate(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
return (blackboard->exists(m_valueName)) ? STATE_SUCCESS : STATE_FAILURE;
}
void TaskFindValue::doExit(std::shared_ptr<Blackboard> blackboard)
{
}
void TaskFindValue::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
@@ -0,0 +1,25 @@
#ifndef TASK_FIND_VALUE_H
#define TASK_FIND_VALUE_H
#include <string>
#include "utility/scheduling/Task.h"
class Blackboard;
class TaskFindValue:
public Task
{
public:
TaskFindValue(const std::string& valueName);
private:
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
const std::string m_valueName;
};
#endif // TASK_FIND_VALUE_H
-4
View File
@@ -4,10 +4,6 @@ TaskGroup::TaskGroup()
{
}
TaskGroup::~TaskGroup()
{
}
std::shared_ptr<TaskGroup> TaskGroup::addChildTasks(std::shared_ptr<Task> child1)
{
addTask(child1);
+1 -2
View File
@@ -12,13 +12,12 @@ class TaskGroup
{
public:
TaskGroup();
virtual ~TaskGroup();
std::shared_ptr<TaskGroup> addChildTasks(std::shared_ptr<Task> child1);
std::shared_ptr<TaskGroup> addChildTasks(std::shared_ptr<Task> child1, std::shared_ptr<Task> child2);
std::shared_ptr<TaskGroup> addChildTasks(std::shared_ptr<Task> child1, std::shared_ptr<Task> child2, std::shared_ptr<Task> child3);
virtual void addTask(std::shared_ptr<Task> task) = 0;
virtual void terminate();
void terminate() override;
private:
virtual void doTerminate() = 0;
@@ -15,7 +15,7 @@ public:
TaskGroupParallel();
virtual ~TaskGroupParallel();
virtual void addTask(std::shared_ptr<Task> task);
void addTask(std::shared_ptr<Task> task) override;
private:
struct TaskInfo
@@ -29,11 +29,11 @@ private:
volatile bool active;
};
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void doTerminate();
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
void doTerminate() override;
void processTaskThreaded(
std::shared_ptr<TaskInfo> taskInfo,
@@ -4,10 +4,6 @@ TaskGroupSelector::TaskGroupSelector()
{
}
TaskGroupSelector::~TaskGroupSelector()
{
}
void TaskGroupSelector::addTask(std::shared_ptr<Task> task)
{
m_taskRunners.push_back(std::make_shared<TaskRunner>(task));
@@ -9,16 +9,15 @@ class TaskGroupSelector
{
public:
TaskGroupSelector();
virtual ~TaskGroupSelector();
virtual void addTask(std::shared_ptr<Task> task);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void doTerminate();
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
void doTerminate() override;
std::vector<std::shared_ptr<TaskRunner>> m_taskRunners;
int m_taskIndex;
@@ -4,10 +4,6 @@ TaskGroupSequence::TaskGroupSequence()
{
}
TaskGroupSequence::~TaskGroupSequence()
{
}
void TaskGroupSequence::addTask(std::shared_ptr<Task> task)
{
m_taskRunners.push_back(std::make_shared<TaskRunner>(task));
@@ -9,16 +9,15 @@ class TaskGroupSequence
{
public:
TaskGroupSequence();
virtual ~TaskGroupSequence();
virtual void addTask(std::shared_ptr<Task> task);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void doTerminate();
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
void doTerminate() override;
std::vector<std::shared_ptr<TaskRunner>> m_taskRunners;
int m_taskIndex;
@@ -5,10 +5,6 @@ TaskLambda::TaskLambda(std::function<void()> func)
{
}
TaskLambda::~TaskLambda()
{
}
void TaskLambda::doEnter(std::shared_ptr<Blackboard> blackboard)
{
}
+4 -5
View File
@@ -10,13 +10,12 @@ class TaskLambda
{
public:
TaskLambda(std::function<void()> func);
virtual ~TaskLambda();
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
std::function<void()> m_func;
};
@@ -18,10 +18,10 @@ public:
TaskReturnSuccessWhile(const std::string& lhsValueName, ConditionType condition, T rhsValue);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
const std::string m_lhsValueName;
const ConditionType m_condition;
+4 -4
View File
@@ -12,10 +12,10 @@ public:
TaskSetValue(const std::string& valueName, T value);
private:
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
void doEnter(std::shared_ptr<Blackboard> blackboard) override;
TaskState doUpdate(std::shared_ptr<Blackboard> blackboard) override;
void doExit(std::shared_ptr<Blackboard> blackboard) override;
void doReset(std::shared_ptr<Blackboard> blackboard) override;
const std::string m_valueName;
const T m_value;
+29 -3
View File
@@ -221,24 +221,50 @@ void QtDialogView::updateIndexingDialog(
);
}
void QtDialogView::finishedIndexingDialog(
DatabasePolicy QtDialogView::finishedIndexingDialog(
size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount,
float time, ErrorCountInfo errorInfo, bool interrupted)
{
DatabasePolicy policy = DATABASE_POLICY_UNKNOWN;
m_resultReady = false;
m_onQtThread(
[=]()
[=, &policy]()
{
m_windowStack.clearWindows();
QtIndexingDialog* window = createWindow<QtIndexingDialog>();
window->setupReport(indexedFileCount, totalIndexedFileCount, completedFileCount, totalFileCount, time, interrupted);
window->updateErrorCount(errorInfo.total, errorInfo.fatal);
connect(window, &QtWindow::finished,
[this, &policy]()
{
setUIBlocked(false);
policy = DATABASE_POLICY_KEEP;
m_resultReady = true;
}
);
connect(window, &QtWindow::canceled,
[this, &policy]()
{
setUIBlocked(false);
policy = DATABASE_POLICY_DISCARD;
m_resultReady = true;
}
);
setUIBlocked(false);
m_mainWindow->hideWindowsTaskbarProgress();
setUIBlocked(true);
}
);
while (!m_resultReady)
{
const int SLEEP_TIME_MS = 25;
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
}
return policy;
}
void QtDialogView::hideDialogs(bool unblockUI)
+11 -11
View File
@@ -25,26 +25,26 @@ class QtDialogView
public:
QtDialogView(QtMainWindow* mainWindow, StorageAccess* storageAccess);
virtual ~QtDialogView();
~QtDialogView() override;
virtual void showUnknownProgressDialog(const std::wstring& title, const std::wstring& message) override;
virtual void hideUnknownProgressDialog() override;
void showUnknownProgressDialog(const std::wstring& title, const std::wstring& message) override;
void hideUnknownProgressDialog() override;
virtual void showProgressDialog(const std::wstring& title, const std::wstring& message, size_t progress) override;
virtual void hideProgressDialog() override;
void showProgressDialog(const std::wstring& title, const std::wstring& message, size_t progress) override;
void hideProgressDialog() override;
virtual void startIndexingDialog(
void startIndexingDialog(
Project* project, const std::vector<RefreshMode>& enabledModes, const RefreshInfo& info) override;
virtual void updateIndexingDialog(
void updateIndexingDialog(
size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const FilePath& sourcePath) override;
virtual void finishedIndexingDialog(
DatabasePolicy finishedIndexingDialog(
size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount,
float time, ErrorCountInfo errorInfo, bool interrupted) override;
virtual void hideDialogs(bool unblockUI = true) override;
void hideDialogs(bool unblockUI = true) override;
virtual int confirm(const std::string& message, const std::vector<std::string>& options) override;
virtual int confirm(const std::wstring& message, const std::vector<std::wstring>& options) override;
int confirm(const std::string& message, const std::vector<std::string>& options) override;
int confirm(const std::wstring& message, const std::vector<std::wstring>& options) override;
void setParentWindow(QtWindow* window);
+10 -2
View File
@@ -207,8 +207,16 @@ void QtIndexingDialog::setupReport(
layout->addStretch();
addButtons(layout);
updateNextButton("OK");
setCloseVisible(false);
if (interrupted)
{
updateNextButton("Keep");
updateCloseButton("Discard");
}
else
{
updateNextButton("OK");
setCloseVisible(false);
}
m_sizeHint = QSize(interrupted ? 400 : 430, 280);