logic: indexer commands

* replaced parser arguments by project specific IndexerCommands that know everything the indexer needs to know to do its job
* added different language and project specific indexers that know how to handle a certain kind of indexer command
* refactored FileManager and FileRegister to have less overhead
* removed no-rtti restriction for clang files in lib cxx
* uncommented deprecated interprocess code.

fortune cookie message = Happiness will bring you good luck.
This commit is contained in:
malte_langkabel
2017-02-22 16:42:20 +01:00
parent 650cd8101e
commit 4563cbe90a
101 changed files with 1908 additions and 1120 deletions
+21 -2
View File
@@ -135,6 +135,22 @@ add_files(
data/graph/Node.h
data/graph/Token.cpp
data/graph/Token.h
data/indexer/Indexer.h
data/indexer/IndexerBase.cpp
data/indexer/IndexerBase.h
data/indexer/IndexerCommand.cpp
data/indexer/IndexerCommand.h
data/indexer/IndexerCommandList.cpp
data/indexer/IndexerCommandList.h
data/indexer/IndexerComposite.cpp
data/indexer/IndexerComposite.h
data/indexer/IndexerFactory.cpp
data/indexer/IndexerFactory.h
data/indexer/IndexerFactoryModule.cpp
data/indexer/IndexerFactoryModule.h
data/indexer/TaskBuildIndex.cpp
data/indexer/TaskBuildIndex.h
data/location/LocationType.cpp
data/location/LocationType.h
@@ -166,8 +182,6 @@ add_files(
data/parser/ReferenceKind.h
data/parser/SymbolKind.cpp
data/parser/SymbolKind.h
data/parser/TaskParse.cpp
data/parser/TaskParse.h
data/parser/TaskParseWrapper.cpp
data/parser/TaskParseWrapper.h
@@ -205,6 +219,8 @@ add_files(
data/TaskFinishParsing.h
data/TaskInjectStorage.cpp
data/TaskInjectStorage.h
data/TaskMergeStorages.cpp
data/TaskMergeStorages.h
data/TaskShowStatusDialog.cpp
data/TaskShowStatusDialog.h
@@ -236,6 +252,8 @@ add_files(
utility/file/FilePath.h
utility/file/FileRegister.cpp
utility/file/FileRegister.h
utility/file/FileRegisterStateData.cpp
utility/file/FileRegisterStateData.h
utility/file/FileSystem.cpp
utility/file/FileSystem.h
@@ -377,6 +395,7 @@ add_files(
utility/scheduling/TaskRunner.h
utility/scheduling/TaskScheduler.cpp
utility/scheduling/TaskScheduler.h
utility/scheduling/TaskSetValue.h
utility/solution/ISolutionParser.cpp
utility/solution/ISolutionParser.h
+84 -16
View File
@@ -2,18 +2,21 @@
#include "component/view/DialogView.h"
#include "data/access/StorageAccessProxy.h"
#include "data/indexer/IndexerCommand.h"
#include "data/indexer/IndexerCommandList.h"
#include "data/indexer/TaskBuildIndex.h"
#include "data/parser/TaskParseWrapper.h"
#include "data/parser/java/TaskParseJava.h"
#include "data/StorageProvider.h"
#include "data/PersistentStorage.h"
#include "data/TaskCleanStorage.h"
#include "data/TaskMergeStorages.h"
#include "data/TaskShowStatusDialog.h"
#include "data/TaskFinishParsing.h"
#include "data/TaskInjectStorage.h"
#include "settings/ApplicationSettings.h"
#include "settings/ProjectSettings.h"
#include "utility/file/FileRegister.h"
#include "utility/file/FileRegisterStateData.h"
#include "utility/messaging/type/MessageClearErrorCount.h"
#include "utility/messaging/type/MessageDispatchWhenLicenseValid.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
@@ -24,6 +27,7 @@
#include "utility/scheduling/TaskGroupSequence.h"
#include "utility/scheduling/TaskGroupParallel.h"
#include "utility/scheduling/TaskReturnSuccessWhile.h"
#include "utility/scheduling/TaskSetValue.h"
#include "utility/text/TextAccess.h"
#include "utility/utility.h"
#include "utility/utilityString.h"
@@ -152,6 +156,13 @@ std::string Project::getDescription() const
return getProjectSettings()->getDescription();
}
#include "utility/file/FileSystem.h"
std::set<FilePath> Project::getSourceFilePaths() const
{
return m_fileManager.getSourceFilePaths();
}
bool Project::settingsEqualExceptNameAndLocation(const ProjectSettings& otherSettings) const
{
return getProjectSettings()->equalsExceptNameAndLocation(otherSettings);
@@ -177,7 +188,7 @@ DialogView* Project::getDialogView() const
return m_dialogView;
}
const std::vector<FilePath>& Project::getSourcePaths() const
std::vector<FilePath> Project::getSourcePaths() const
{
return m_fileManager.getSourcePaths();
}
@@ -287,7 +298,7 @@ bool Project::requestIndex(bool forceRefresh, bool needsFullRefresh)
}
// handle referenced paths
std::set<FilePath> staticSourceFiles = fileSets.allFiles;
std::set<FilePath> staticSourceFiles = fileSets.allSourceFilePaths;
for (const FilePath& path : fileSets.updatedFiles)
{
staticSourceFiles.erase(path);
@@ -313,7 +324,7 @@ bool Project::requestIndex(bool forceRefresh, bool needsFullRefresh)
if (Application::getInstance()->hasGUI())
{
DialogView::IndexMode mode = m_dialogView->startIndexingDialog(
filesToClean.size(), filesToIndex.size(), fileSets.allFiles.size(),
filesToClean.size(), filesToIndex.size(), fileSets.allSourceFilePaths.size(),
forceRefresh, needsFullRefresh
);
@@ -333,7 +344,7 @@ bool Project::requestIndex(bool forceRefresh, bool needsFullRefresh)
if (fullRefresh)
{
filesToClean.clear();
filesToIndex = fileSets.allFiles;
filesToIndex = fileSets.allSourceFilePaths;
}
if (!filesToClean.size() && !filesToIndex.size())
@@ -362,6 +373,7 @@ void Project::buildIndex(const std::set<FilePath>& filesToClean, const std::set<
std::shared_ptr<TaskGroupSequence> taskSequential = std::make_shared<TaskGroupSequence>();
// add task for cleaning the database
if (!filesToClean.empty())
{
taskSequential->addTask(std::make_shared<TaskCleanStorage>(
@@ -371,17 +383,31 @@ void Project::buildIndex(const std::set<FilePath>& filesToClean, const std::set<
);
}
const size_t indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount();
std::shared_ptr<FileRegister> fileRegister = std::make_shared<FileRegister>(&m_fileManager, indexerThreadCount > 1);
if (!filesToIndex.empty())
{
fileRegister->setFilePaths(utility::toVector(filesToIndex));
const size_t indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount();
std::shared_ptr<IndexerCommandList> indexerCommandList = std::make_shared<IndexerCommandList>();
for (std::shared_ptr<IndexerCommand> indexerCommand: getIndexerCommands(filesToIndex))
{
indexerCommandList->addCommand(indexerCommand);
}
if (indexerThreadCount > 1)
{
indexerCommandList->shuffle();
}
std::shared_ptr<FileRegisterStateData> fileRegisterStateData = std::make_shared<FileRegisterStateData>();
std::shared_ptr<StorageProvider> storageProvider = std::make_shared<StorageProvider>();
// add tasks for setting some variables on the blackboard that are used during indexing
taskSequential->addTask(std::make_shared<TaskSetValue<int>>("source_file_count", indexerCommandList->size()));
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(),
fileRegister,
m_dialogView
);
taskSequential->addTask(taskParserWrapper);
@@ -389,17 +415,32 @@ void Project::buildIndex(const std::set<FilePath>& filesToClean, const std::set<
std::shared_ptr<TaskGroupParallel> taskParallelIndexing = std::make_shared<TaskGroupParallel>();
taskParserWrapper->setTask(taskParallelIndexing);
std::shared_ptr<StorageProvider> storageProvider = std::make_shared<StorageProvider>();
// add tasks for indexing and merging
for (size_t i = 0; i < indexerThreadCount && i < filesToIndex.size(); i++)
{
taskParallelIndexing->addChildTasks(
std::make_shared<TaskDecoratorRepeat>(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask(
createIndexerTask(storageProvider, fileRegister)
std::make_shared<TaskBuildIndex>(indexerCommandList, storageProvider, fileRegisterStateData, getDialogView())
)
);
}
// add task for merging the intermediate storages
taskParallelIndexing->addTask(
std::make_shared<TaskGroupSequence>()->addChildTasks(
std::make_shared<TaskDecoratorRepeat>(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask(
std::make_shared<TaskReturnSuccessWhile<int>>("indexer_count", TaskReturnSuccessWhile<int>::CONDITION_EQUALS, 0)
),
std::make_shared<TaskDecoratorRepeat>(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask(
std::make_shared<TaskGroupSelector>()->addChildTasks(
std::make_shared<TaskMergeStorages>(storageProvider),
std::make_shared<TaskReturnSuccessWhile<int>>("indexer_count", TaskReturnSuccessWhile<int>::CONDITION_GREATER_THAN, 0)
)
)
)
);
// add task for injecting the intermediate storages into the persistent storage
taskParallelIndexing->addTask(
std::make_shared<TaskGroupSequence>()->addChildTasks(
std::make_shared<TaskDecoratorRepeat>(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask(
@@ -419,10 +460,12 @@ void Project::buildIndex(const std::set<FilePath>& filesToClean, const std::set<
)
);
// add task that notifies the user of what's going on
taskSequential->addTask( // we don't need to hide this dialog again, because it's overridden by other dialogs later on.
std::make_shared<TaskShowStatusDialog>("Finish Indexing", "Saving\nRemaining Data", m_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)
@@ -430,7 +473,7 @@ void Project::buildIndex(const std::set<FilePath>& filesToClean, const std::set<
);
}
taskSequential->addTask(std::make_shared<TaskFinishParsing>(m_storage.get(), m_storageAccessProxy, fileRegister, m_dialogView));
taskSequential->addTask(std::make_shared<TaskFinishParsing>(m_storage.get(), m_storageAccessProxy, m_dialogView));
Task::dispatch(taskSequential);
}
@@ -444,3 +487,28 @@ bool Project::prepareRefresh()
{
return true;
}
std::vector<std::shared_ptr<IndexerCommand>> Project::getIndexerCommands(const std::set<FilePath>& sourceFiles)
{
struct special_compare : public std::unary_function<FilePath, bool>
{
explicit special_compare(const FilePath& baseline) : m_baseline(baseline) {}
bool operator() (const FilePath& arg)
{
return arg.str() == m_baseline.str();
}
const FilePath m_baseline;
};
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands;
for (std::shared_ptr<IndexerCommand> indexerCommand: getIndexerCommands())
{
if (std::find_if(sourceFiles.begin(), sourceFiles.end(), special_compare(indexerCommand->getSourceFilePath())) != sourceFiles.end())
{
indexerCommands.push_back(indexerCommand);
}
}
return indexerCommands;
}
+6 -5
View File
@@ -16,7 +16,7 @@ class PersistentStorage;
class StorageProvider;
class ProjectSettings;
class StorageAccessProxy;
class Task;
class IndexerCommand;
class Project
{
@@ -29,13 +29,15 @@ public:
LanguageType getLanguage() const;
std::string getDescription() const;
std::set<FilePath> getSourceFilePaths() const;
bool settingsEqualExceptNameAndLocation(const ProjectSettings& otherSettings) const;
void setStateSettingsUpdated();
protected:
Project(StorageAccessProxy* storageAccessProxy, DialogView* dialogView);
DialogView* getDialogView() const;
const std::vector<FilePath>& getSourcePaths() const;
std::vector<FilePath> getSourcePaths() const;
virtual std::shared_ptr<ProjectSettings> getProjectSettings() = 0;
virtual const std::shared_ptr<ProjectSettings> getProjectSettings() const = 0;
@@ -63,9 +65,8 @@ private:
virtual bool prepareIndexing();
virtual bool prepareRefresh();
virtual std::shared_ptr<Task> createIndexerTask(
std::shared_ptr<StorageProvider> storageProvider,
std::shared_ptr<FileRegister> fileRegister) = 0;
virtual std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands() = 0;
std::vector<std::shared_ptr<IndexerCommand>> getIndexerCommands(const std::set<FilePath>& sourceFiles);
virtual void updateFileManager(FileManager& fileManager) = 0;
StorageAccessProxy* const m_storageAccessProxy;
+3 -7
View File
@@ -8,7 +8,7 @@ int StorageProvider::getStorageCount() const
return m_storages.size();
}
void StorageProvider::pushIndexerTarget(std::shared_ptr<IntermediateStorage> storage)
void StorageProvider::insert(std::shared_ptr<IntermediateStorage> storage)
{
const std::size_t storageSize = storage->getSourceLocationCount();
std::list<std::shared_ptr<IntermediateStorage>>::iterator it;
@@ -24,7 +24,7 @@ void StorageProvider::pushIndexerTarget(std::shared_ptr<IntermediateStorage> sto
m_storages.insert(it, storage);
}
std::shared_ptr<IntermediateStorage> StorageProvider::popIndexerTarget()
std::shared_ptr<IntermediateStorage> StorageProvider::consumeSecondLargestStorage()
{
std::shared_ptr<IntermediateStorage> ret;
{
@@ -36,15 +36,11 @@ std::shared_ptr<IntermediateStorage> StorageProvider::popIndexerTarget()
ret = *it;
m_storages.erase(it);
}
else
{
ret = std::make_shared<IntermediateStorage>();
}
}
return ret;
}
std::shared_ptr<IntermediateStorage> StorageProvider::popInjectionSource()
std::shared_ptr<IntermediateStorage> StorageProvider::consumeLargestStorage()
{
std::shared_ptr<IntermediateStorage> ret;
{
+5 -4
View File
@@ -10,13 +10,14 @@ class StorageProvider
{
public:
int getStorageCount() const;
void pushIndexerTarget(std::shared_ptr<IntermediateStorage> storage);
// always returns a usable storage
std::shared_ptr<IntermediateStorage> popIndexerTarget();
void insert(std::shared_ptr<IntermediateStorage> storage);
// returns empty shared_ptr if no storages available
std::shared_ptr<IntermediateStorage> popInjectionSource();
std::shared_ptr<IntermediateStorage> consumeSecondLargestStorage();
// returns empty shared_ptr if no storages available
std::shared_ptr<IntermediateStorage> consumeLargestStorage();
void logCurrentState() const;
+8 -4
View File
@@ -10,12 +10,10 @@
TaskFinishParsing::TaskFinishParsing(
PersistentStorage* storage,
StorageAccess* storageAccess,
std::shared_ptr<FileRegister> fileRegister,
DialogView* dialogView
)
: m_storage(storage)
, m_storageAccess(storageAccess)
, m_fileRegister(fileRegister)
, m_dialogView(dialogView)
{
}
@@ -58,9 +56,15 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr<Blackboard> blackboa
time += indexTime;
}
int indexedSourceFileCount = 0;
blackboard->get("indexed_source_file_count", indexedSourceFileCount);
int sourceFileCount = 0;
blackboard->get("source_file_count", sourceFileCount);
m_dialogView->finishedIndexingDialog(
m_fileRegister->getParsedSourceFilesCount(),
m_fileRegister->getSourceFilesCount(),
indexedSourceFileCount,
sourceFileCount,
time,
m_storageAccess->getErrorCount()
);
-2
View File
@@ -18,7 +18,6 @@ public:
TaskFinishParsing(
PersistentStorage* storage,
StorageAccess* storageAccess,
std::shared_ptr<FileRegister> fileRegister,
DialogView* dialogView
);
@@ -32,7 +31,6 @@ private:
PersistentStorage* m_storage;
StorageAccess* m_storageAccess;
std::shared_ptr<FileRegister> m_fileRegister;
DialogView* m_dialogView;
};
+1 -1
View File
@@ -23,7 +23,7 @@ Task::TaskState TaskInjectStorage::doUpdate(std::shared_ptr<Blackboard> blackboa
{
if (m_storageProvider->getStorageCount() > 0)
{
std::shared_ptr<IntermediateStorage> source = m_storageProvider->popInjectionSource();
std::shared_ptr<IntermediateStorage> source = m_storageProvider->consumeLargestStorage();
if (source)
{
m_target->inject(source.get());
+58
View File
@@ -0,0 +1,58 @@
#include "data/TaskMergeStorages.h"
#include <chrono>
#include <thread>
#include "data/StorageProvider.h"
TaskMergeStorages::TaskMergeStorages(
std::shared_ptr<StorageProvider> storageProvider
)
: m_storageProvider(storageProvider)
{
}
void TaskMergeStorages::doEnter(std::shared_ptr<Blackboard> blackboard)
{
}
Task::TaskState TaskMergeStorages::doUpdate(std::shared_ptr<Blackboard> blackboard)
{
if (m_storageProvider->getStorageCount() > 2) // largest storage won't be touched here
{
std::shared_ptr<IntermediateStorage> target = m_storageProvider->consumeSecondLargestStorage();
std::shared_ptr<IntermediateStorage> source = m_storageProvider->consumeSecondLargestStorage();
if (target && source)
{
target->inject(source.get());
m_storageProvider->insert(target);
return STATE_SUCCESS;
}
else
{
if (target)
{
m_storageProvider->insert(target);
}
if (source)
{
m_storageProvider->insert(source);
}
}
}
else
{
const int SLEEP_TIME_MS = 25;
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS));
}
return STATE_FAILURE;
}
void TaskMergeStorages::doExit(std::shared_ptr<Blackboard> blackboard)
{
}
void TaskMergeStorages::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef TASK_MERGE_STORAGES_H
#define TASK_MERGE_STORAGES_H
#include <vector>
#include "utility/scheduling/Task.h"
class StorageProvider;
class TaskMergeStorages
: public Task
{
public:
TaskMergeStorages(
std::shared_ptr<StorageProvider> storageProvider
);
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);
std::shared_ptr<StorageProvider> m_storageProvider;
};
#endif // TASK_MERGE_STORAGES_H
+46
View File
@@ -0,0 +1,46 @@
#ifndef INDEXER_H
#define INDEXER_H
#include <memory>
#include "data/indexer/IndexerBase.h"
#include "utility/logging/logging.h"
template <typename IndexerCommandType>
class Indexer: public IndexerBase
{
public:
virtual ~Indexer();
virtual std::string getKindString() const;
virtual std::shared_ptr<IntermediateStorage> index(std::shared_ptr<IndexerCommand> indexerCommand, std::shared_ptr<FileRegister> fileRegister);
private:
virtual std::shared_ptr<IntermediateStorage> index(std::shared_ptr<IndexerCommandType> indexerCommand, std::shared_ptr<FileRegister> fileRegister) = 0;
};
template <typename IndexerCommandType>
Indexer<IndexerCommandType>::~Indexer()
{
}
template <typename IndexerCommandType>
std::string Indexer<IndexerCommandType>::getKindString() const
{
return IndexerCommandType::getIndexerKindString();
}
template <typename IndexerCommandType>
std::shared_ptr<IntermediateStorage> Indexer<IndexerCommandType>::index(std::shared_ptr<IndexerCommand> indexerCommand, std::shared_ptr<FileRegister> fileRegister)
{
if (std::shared_ptr<IndexerCommandType> castedCommand = std::dynamic_pointer_cast<IndexerCommandType>(indexerCommand))
{
return index(castedCommand, fileRegister);
}
LOG_ERROR("Trying to process " + indexerCommand->getKindString() + " indexer command with " + getKindString() + " indexer.");
return std::shared_ptr<IntermediateStorage>();
}
#endif // INDEXER_H
+20
View File
@@ -0,0 +1,20 @@
#include "data/indexer/IndexerBase.h"
IndexerBase::IndexerBase()
: m_interrupted(false)
{
}
IndexerBase::~IndexerBase()
{
}
void IndexerBase::interrupt()
{
m_interrupted = true;
}
bool IndexerBase::interrupted() const
{
return m_interrupted;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef INDEXER_BASE_H
#define INDEXER_BASE_H
#include <memory>
#include "data/indexer/IndexerCommand.h"
#include "data/IntermediateStorage.h"
class FileRegister;
class IndexerBase
{
public:
IndexerBase();
virtual ~IndexerBase();
virtual std::string getKindString() const = 0;
virtual std::shared_ptr<IntermediateStorage> index(std::shared_ptr<IndexerCommand> indexerCommand, std::shared_ptr<FileRegister> fileRegister) = 0;
virtual void interrupt();
bool interrupted() const;
private:
bool m_interrupted;
};
#endif // INDEXER_BASE_H
+28
View File
@@ -0,0 +1,28 @@
#include "data/indexer/IndexerCommand.h"
IndexerCommand::IndexerCommand(const FilePath& sourceFilePath, const std::set<FilePath>& indexedPaths, const std::set<FilePath>& excludedPaths)
: m_sourceFilePath(sourceFilePath)
, m_indexedPaths(indexedPaths)
, m_excludedPaths(excludedPaths)
{
}
IndexerCommand::~IndexerCommand()
{
}
FilePath IndexerCommand::getSourceFilePath() const
{
return m_sourceFilePath;
}
std::set<FilePath> IndexerCommand::getIndexedPaths() const
{
return m_indexedPaths;
}
std::set<FilePath> IndexerCommand::getExcludedPath() const
{
return m_excludedPaths;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef INDEXER_COMMAND_H
#define INDEXER_COMMAND_H
#include <set>
#include <string>
#include "utility/file/FilePath.h"
class IndexerCommand
{
public:
IndexerCommand(const FilePath& sourceFilePath, const std::set<FilePath>& indexedPaths, const std::set<FilePath>& excludedPaths);
virtual ~IndexerCommand();
virtual std::string getKindString() const = 0;
FilePath getSourceFilePath() const;
std::set<FilePath> getIndexedPaths() const;
std::set<FilePath> getExcludedPath() const;
private:
FilePath m_sourceFilePath;
std::set<FilePath> m_indexedPaths;
std::set<FilePath> m_excludedPaths;
};
#endif // INDEXER_COMMAND_H
@@ -0,0 +1,34 @@
#include "data/indexer/IndexerCommandList.h"
#include <algorithm>
#include <random>
void IndexerCommandList::addCommand(std::shared_ptr<IndexerCommand> command)
{
std::lock_guard<std::mutex> lock(m_commandsMutex);
m_commands.push_back(command);
}
int IndexerCommandList::size() const
{
return m_commands.size();
}
void IndexerCommandList::shuffle()
{
srand(unsigned(time(NULL)));
std::lock_guard<std::mutex> lock(m_commandsMutex);
std::random_shuffle(m_commands.begin(), m_commands.end());
}
std::shared_ptr<IndexerCommand> IndexerCommandList::consumeCommand()
{
std::lock_guard<std::mutex> lock(m_commandsMutex);
std::shared_ptr<IndexerCommand> ret;
if (!m_commands.empty())
{
ret = m_commands.front();
m_commands.pop_front();
}
return ret;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef INDEXER_COMMAND_LIST_H
#define INDEXER_COMMAND_LIST_H
#include <memory>
#include <mutex>
#include <deque>
#include "data/indexer/IndexerCommand.h"
class IndexerCommandList
{
public:
void addCommand(std::shared_ptr<IndexerCommand> command);
int size() const;
void shuffle();
std::shared_ptr<IndexerCommand> consumeCommand();
private:
std::deque<std::shared_ptr<IndexerCommand>> m_commands;
std::mutex m_commandsMutex;
};
#endif // INDEXER_COMMAND_LIST_H
+37
View File
@@ -0,0 +1,37 @@
#include "data/indexer/IndexerComposite.h"
#include "utility/logging/logging.h"
IndexerComposite::~IndexerComposite()
{
}
std::string IndexerComposite::getKindString() const
{
return "composite";
}
void IndexerComposite::addIndexer(std::shared_ptr<IndexerBase> indexer)
{
m_indexers.emplace(indexer->getKindString(), indexer);
}
std::shared_ptr<IntermediateStorage> IndexerComposite::index(std::shared_ptr<IndexerCommand> indexerCommand, std::shared_ptr<FileRegister> fileRegister)
{
auto it = m_indexers.find(indexerCommand->getKindString());
if (it != m_indexers.end())
{
return it->second->index(indexerCommand, fileRegister);
}
LOG_ERROR("No indexer found to handle " + indexerCommand->getKindString() + " indexer command.");
return std::shared_ptr<IntermediateStorage>();
}
void IndexerComposite::interrupt()
{
for (auto it: m_indexers)
{
it.second->interrupt();
}
IndexerBase::interrupt();
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef INDEXER_COMPOSITE_H
#define INDEXER_COMPOSITE_H
#include <memory>
#include <unordered_map>
#include "data/indexer/IndexerBase.h"
class IndexerComposite: public IndexerBase
{
public:
virtual ~IndexerComposite();
virtual std::string getKindString() const;
void addIndexer(std::shared_ptr<IndexerBase> indexer);
virtual std::shared_ptr<IntermediateStorage> index(std::shared_ptr<IndexerCommand> indexerCommand, std::shared_ptr<FileRegister> fileRegister);
virtual void interrupt();
private:
std::unordered_map<std::string, std::shared_ptr<IndexerBase>> m_indexers;
};
#endif // INDEXER_COMPOSITE_H
+41
View File
@@ -0,0 +1,41 @@
#include "data/indexer/IndexerFactory.h"
#include "data/indexer/IndexerBase.h"
#include "data/indexer/IndexerComposite.h"
#include "IndexerFactoryModule.h"
std::shared_ptr<IndexerFactory> IndexerFactory::getInstance()
{
if (!s_instance)
{
s_instance = std::shared_ptr<IndexerFactory>(new IndexerFactory());
}
return s_instance;
}
void IndexerFactory::destroyInstance()
{
s_instance.reset();
}
void IndexerFactory::addModule(std::shared_ptr<IndexerFactoryModule> module)
{
m_modules.push_back(module);
}
std::shared_ptr<IndexerComposite> IndexerFactory::createCompositeIndexerForAllRegisteredModules()
{
std::shared_ptr<IndexerComposite> composite = std::make_shared<IndexerComposite>();
for (auto it: m_modules)
{
composite->addIndexer(it->createIndexer());
}
return composite;
}
std::shared_ptr<IndexerFactory> IndexerFactory::s_instance;
IndexerFactory::IndexerFactory()
{
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef INDEXER_FACTORY_H
#define INDEXER_FACTORY_H
#include <memory>
#include <vector>
#include "settings/LanguageType.h"
class IndexerBase;
class IndexerComposite;
class IndexerFactoryModule;
class IndexerFactory
{
public:
static std::shared_ptr<IndexerFactory> getInstance();
static void destroyInstance();
void addModule(std::shared_ptr<IndexerFactoryModule> module);
std::shared_ptr<IndexerComposite> createCompositeIndexerForAllRegisteredModules();
private:
static std::shared_ptr<IndexerFactory> s_instance;
IndexerFactory();
std::vector<std::shared_ptr<IndexerFactoryModule>> m_modules;
};
#endif // INDEXER_FACTORY_H
@@ -0,0 +1,5 @@
#include "data/indexer/IndexerFactoryModule.h"
IndexerFactoryModule::~IndexerFactoryModule()
{
}
@@ -0,0 +1,17 @@
#ifndef INDEXER_FACTORY_MODULE_H
#define INDEXER_FACTORY_MODULE_H
#include <memory>
#include "settings/LanguageType.h"
class IndexerBase;
class IndexerFactoryModule
{
public:
virtual ~IndexerFactoryModule();
virtual std::shared_ptr<IndexerBase> createIndexer() = 0;
};
#endif // INDEXER_FACTORY_MODULE_H
+109
View File
@@ -0,0 +1,109 @@
#include "data/indexer/TaskBuildIndex.h"
#include "data/indexer/IndexerFactory.h"
#include "data/indexer/IndexerCommandList.h"
#include "data/indexer/IndexerComposite.h"
#include "data/StorageProvider.h"
#include "component/view/DialogView.h"
#include "utility/file/FileRegister.h"
#include "utility/file/FileRegisterStateData.h"
#include "utility/scheduling/Blackboard.h"
#include "ApplicationStateMonitor.h"
TaskBuildIndex::TaskBuildIndex(
std::shared_ptr<IndexerCommandList> indexerCommandList,
std::shared_ptr<StorageProvider> storageProvider,
std::shared_ptr<FileRegisterStateData> fileRegisterStateData,
DialogView* dialogView
)
: m_indexerCommandList(indexerCommandList)
, m_storageProvider(storageProvider)
, m_fileRegisterStateData(fileRegisterStateData)
, m_dialogView(dialogView)
{
m_indexer = IndexerFactory::getInstance()->createCompositeIndexerForAllRegisteredModules();
}
void TaskBuildIndex::doEnter(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int indexerCount = 0;
if (blackboard->get("indexer_count", indexerCount))
{
indexerCount++;
blackboard->set("indexer_count", indexerCount);
}
}
Task::TaskState TaskBuildIndex::doUpdate(std::shared_ptr<Blackboard> blackboard)
{
std::shared_ptr<IndexerCommand> indexerCommand = m_indexerCommandList->consumeCommand();
if (!indexerCommand)
{
return STATE_FAILURE;
}
else
{
ApplicationStateMonitor::getInstance()->addIndexingFile(indexerCommand->getSourceFilePath());
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int sourceFileCount = 0;
blackboard->get("source_file_count", sourceFileCount);
int indexedSourceFileCount = 0;
blackboard->get("indexed_source_file_count", indexedSourceFileCount);
m_dialogView->updateIndexingDialog(
indexedSourceFileCount, sourceFileCount, indexerCommand->getSourceFilePath().str()
);
}
// file register only copies the DileRegisterStateData
std::shared_ptr<FileRegister> fileRegister = std::make_shared<FileRegister>(
*(m_fileRegisterStateData.get()), indexerCommand->getIndexedPaths(), indexerCommand->getExcludedPath()
);
std::shared_ptr<IntermediateStorage> storage = m_indexer->index(indexerCommand, fileRegister);
if (storage)
{
// only write back the changes made to FileRegisterStateData if the indexer actually succeeded
m_fileRegisterStateData->inject(fileRegister->getStateData());
m_storageProvider->insert(storage);
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int indexedSourceFileCount = 0;
blackboard->get("indexed_source_file_count", indexedSourceFileCount);
blackboard->set("indexed_source_file_count", indexedSourceFileCount + 1);
}
ApplicationStateMonitor::getInstance()->removeIndexingFile(indexerCommand->getSourceFilePath());
}
return (m_indexer->interrupted() ? STATE_FAILURE : STATE_SUCCESS);
}
void TaskBuildIndex::doExit(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int indexerCount = 0;
if (blackboard->get("indexer_count", indexerCount))
{
indexerCount--;
blackboard->set("indexer_count", indexerCount);
}
}
void TaskBuildIndex::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
void TaskBuildIndex::handleMessage(MessageInterruptTasks* message)
{
m_indexer->interrupt();
}
@@ -1,5 +1,5 @@
#ifndef TASK_PARSE_H
#define TASK_PARSE_H
#ifndef TASK_BUILD_INDEX_H
#define TASK_BUILD_INDEX_H
#include "data/parser/Parser.h"
#include "utility/scheduling/Task.h"
@@ -8,18 +8,20 @@
class CxxParser;
class DialogView;
class FileRegister;
class FileRegisterStateData;
class StorageProvider;
class IndexerCommandList;
class IndexerBase;
class TaskParse
class TaskBuildIndex
: public Task
, public MessageListener<MessageInterruptTasks>
{
public:
TaskParse(
TaskBuildIndex(
std::shared_ptr<IndexerCommandList> indexerCommandList,
std::shared_ptr<StorageProvider> storageProvider,
std::shared_ptr<FileRegister> fileRegister,
const Parser::Arguments& arguments,
std::shared_ptr<FileRegisterStateData> fileRegisterStateData,
DialogView* dialogView
);
@@ -30,15 +32,13 @@ protected:
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
virtual void handleMessage(MessageInterruptTasks* message);
virtual void indexFile(FilePath sourcePath) = 0;
std::shared_ptr<IndexerCommandList> m_indexerCommandList;
std::shared_ptr<StorageProvider> m_storageProvider;
std::shared_ptr<FileRegister> m_fileRegister;
const Parser::Arguments m_arguments;
std::shared_ptr<FileRegisterStateData> m_fileRegisterStateData;
DialogView* m_dialogView;
bool m_interrupted;
std::shared_ptr<IndexerBase> m_indexer;
};
#endif // TASK_PARSE_H
+1 -5
View File
@@ -1,11 +1,7 @@
#include "data/parser/Parser.h"
Parser::Arguments::Arguments()
: logErrors(true)
{
}
Parser::Parser(ParserClient* client)
Parser::Parser(std::shared_ptr<ParserClient> client)
: m_client(client)
{
}
+2 -24
View File
@@ -13,33 +13,11 @@ class TextAccess;
class Parser
{
public:
struct Arguments
{
Arguments();
std::vector<FilePath> javaClassPaths;
std::vector<FilePath> headerSearchPaths;
std::vector<FilePath> systemHeaderSearchPaths;
std::vector<FilePath> frameworkSearchPaths;
std::vector<std::string> compilerFlags;
bool logErrors;
std::string language;
std::string languageStandard;
FilePath compilationDatabasePath;
};
Parser(ParserClient* client);
Parser(std::shared_ptr<ParserClient> client);
virtual ~Parser();
virtual void parseFiles(const std::vector<FilePath>& filePaths, const Arguments& arguments) = 0;
virtual void parseFile(const FilePath& filePath, std::shared_ptr<TextAccess> textAccess, const Arguments& arguments) = 0;
protected:
ParserClient* m_client;
std::shared_ptr<ParserClient> m_client;
};
#endif // PARSER_H
-75
View File
@@ -1,75 +0,0 @@
#include "data/parser/TaskParse.h"
#include "component/view/DialogView.h"
#include "utility/file/FileRegister.h"
#include "utility/scheduling/Blackboard.h"
#include "ApplicationStateMonitor.h"
TaskParse::TaskParse(
std::shared_ptr<StorageProvider> storageProvider,
std::shared_ptr<FileRegister> fileRegister,
const Parser::Arguments& arguments,
DialogView* dialogView
)
: m_storageProvider(storageProvider)
, m_fileRegister(fileRegister)
, m_arguments(arguments)
, m_dialogView(dialogView)
, m_interrupted(false)
{
}
void TaskParse::doEnter(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int indexerCount = 0;
if (blackboard->get("indexer_count", indexerCount))
{
indexerCount++;
blackboard->set("indexer_count", indexerCount);
}
}
Task::TaskState TaskParse::doUpdate(std::shared_ptr<Blackboard> blackboard)
{
FilePath sourcePath = m_fileRegister->consumeSourceFile();
if (sourcePath.empty())
{
return STATE_FAILURE;
}
else
{
ApplicationStateMonitor::getInstance()->addIndexingFile(sourcePath);
m_dialogView->updateIndexingDialog(
m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str()
);
indexFile(sourcePath);
ApplicationStateMonitor::getInstance()->removeIndexingFile(sourcePath);
}
return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS);
}
void TaskParse::doExit(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
int indexerCount = 0;
if (blackboard->get("indexer_count", indexerCount))
{
indexerCount--;
blackboard->set("indexer_count", indexerCount);
}
}
void TaskParse::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
void TaskParse::handleMessage(MessageInterruptTasks* message)
{
m_interrupted = true;
}
+2 -7
View File
@@ -2,17 +2,14 @@
#include "component/view/DialogView.h"
#include "data/PersistentStorage.h"
#include "utility/file/FileRegister.h"
#include "utility/scheduling/Blackboard.h"
#include "utility/utility.h"
TaskParseWrapper::TaskParseWrapper(
PersistentStorage* storage,
std::shared_ptr<FileRegister> fileRegister,
DialogView* dialogView
)
: m_storage(storage)
, m_fileRegister(fileRegister)
, m_dialogView(dialogView)
{
}
@@ -31,9 +28,8 @@ void TaskParseWrapper::setTask(std::shared_ptr<Task> task)
void TaskParseWrapper::doEnter(std::shared_ptr<Blackboard> blackboard)
{
blackboard->set("indexer_count", 0);
const size_t sourceFileCount = m_fileRegister->getSourceFilesCount();
int sourceFileCount = 0;
blackboard->get("source_file_count", sourceFileCount);
m_dialogView->updateIndexingDialog(0, sourceFileCount, "");
m_start = utility::durationStart();
@@ -51,7 +47,6 @@ Task::TaskState TaskParseWrapper::doUpdate(std::shared_ptr<Blackboard> blackboar
void TaskParseWrapper::doExit(std::shared_ptr<Blackboard> blackboard)
{
blackboard->clear("indexer_count");
blackboard->set("index_time", utility::duration(m_start));
}
-2
View File
@@ -20,7 +20,6 @@ class TaskParseWrapper
public:
TaskParseWrapper(
PersistentStorage* storage,
std::shared_ptr<FileRegister> fileRegister,
DialogView* dialogView
);
virtual ~TaskParseWrapper();
@@ -34,7 +33,6 @@ private:
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
PersistentStorage* m_storage;
std::shared_ptr<FileRegister> m_fileRegister;
DialogView* m_dialogView;
TimePoint m_start;
+1 -1
View File
@@ -114,7 +114,7 @@ bool ProjectSettings::setStandard(const std::string& standard)
return setValue<std::string>("language_settings/standard", standard);
}
std::vector<FilePath> ProjectSettings::getSourcePaths() const
std::vector<FilePath> ProjectSettings::getSourcePaths() const // TODO: rename to getIndexedPaths
{
return getPathValues("source/source_paths/source_path");
}
+24 -47
View File
@@ -15,11 +15,6 @@ FileManager::~FileManager()
{
}
const std::vector<FilePath>& FileManager::getSourcePaths() const
{
return m_sourcePaths;
}
void FileManager::setPaths(
std::vector<FilePath> sourcePaths,
std::vector<FilePath> headerPaths,
@@ -34,24 +29,26 @@ void FileManager::setPaths(
FileManager::FileSets FileManager::fetchFilePaths(const std::vector<FileInfo>& oldFileInfos)
{
m_files.clear();
m_filesInfos.clear();
for (FileInfo oldFileInfo: oldFileInfos)
{
m_files.emplace(oldFileInfo.path, oldFileInfo);
m_filesInfos.emplace(oldFileInfo.path, oldFileInfo);
}
FileSets fileSets;
for (std::map<FilePath, FileInfo>::iterator it = m_files.begin(); it != m_files.end(); it++)
// update old files that have been modified
// remove old files that don't exist anymore
for (std::map<FilePath, FileInfo>::iterator it = m_filesInfos.begin(); it != m_filesInfos.end(); it++)
{
const FilePath& filePath = it->first;
if (filePath.exists() && !hasSourceFilePath(filePath))
{
FileInfo fileInfo = FileSystem::getFileInfoForPath(filePath);
FileInfo newFileInfo = FileSystem::getFileInfoForPath(filePath);
if (fileInfo.lastWriteTime > it->second.lastWriteTime)
if (newFileInfo.lastWriteTime > it->second.lastWriteTime)
{
it->second.lastWriteTime = fileInfo.lastWriteTime;
it->second.lastWriteTime = newFileInfo.lastWriteTime;
fileSets.updatedFiles.insert(filePath);
}
}
@@ -70,10 +67,10 @@ FileManager::FileSets FileManager::fetchFilePaths(const std::vector<FileInfo>& o
continue;
}
fileSets.allFiles.insert(filePath);
fileSets.allSourceFilePaths.insert(filePath);
std::map<FilePath, FileInfo>::iterator it = m_files.find(filePath);
if (it != m_files.end())
std::map<FilePath, FileInfo>::iterator it = m_filesInfos.find(filePath);
if (it != m_filesInfos.end())
{
fileSets.removedFiles.erase(filePath);
if (fileInfo.lastWriteTime > it->second.lastWriteTime)
@@ -84,47 +81,39 @@ FileManager::FileSets FileManager::fetchFilePaths(const std::vector<FileInfo>& o
}
else
{
m_files.insert(std::pair<FilePath, FileInfo>(filePath, fileInfo));
m_filesInfos.insert(std::pair<FilePath, FileInfo>(filePath, fileInfo));
fileSets.addedFiles.insert(filePath);
}
}
for (const FilePath& filePath : fileSets.removedFiles)
{
m_files.erase(filePath);
m_filesInfos.erase(filePath);
}
m_sourceFiles = fileSets.allFiles;
m_sourceFilePaths = fileSets.allSourceFilePaths;
return fileSets;
}
bool FileManager::hasFilePath(const FilePath& filePath) const
std::vector<FilePath> FileManager::getSourcePaths() const
{
if (hasSourceFilePath(filePath))
{
return true;
}
return m_sourcePaths;
}
if (isExcluded(filePath))
std::set<FilePath> FileManager::getSourceFilePaths() const
{
std::set<FilePath> sourceFilePaths;
for (const FileInfo& fileInfo: FileSystem::getFileInfosFromPaths(m_sourcePaths, m_sourceExtensions))
{
return false;
sourceFilePaths.emplace(fileInfo.path);
}
for (FilePath path : m_headerPaths)
{
if (path == filePath || path.contains(filePath))
{
return true;
}
}
return false;
return sourceFilePaths;
}
bool FileManager::hasSourceFilePath(const FilePath& filePath) const
{
if (m_sourceFiles.find(filePath) != m_sourceFiles.end())
if (m_sourceFilePaths.find(filePath) != m_sourceFilePaths.end())
{
return true;
}
@@ -132,18 +121,6 @@ bool FileManager::hasSourceFilePath(const FilePath& filePath) const
return false;
}
const FileInfo FileManager::getFileInfo(const FilePath& filePath) const
{
std::map<FilePath, FileInfo>::const_iterator it = m_files.find(filePath);
if (it == m_files.end())
{
return FileSystem::getFileInfoForPath(filePath);
}
return it->second;
}
std::vector<FilePath> FileManager::makeCanonical(const std::vector<FilePath>& filePaths)
{
std::vector<FilePath> ret;
+11 -10
View File
@@ -12,17 +12,15 @@ class FileManager
public:
struct FileSets
{
std::set<FilePath> allFiles;
std::set<FilePath> addedFiles;
std::set<FilePath> updatedFiles;
std::set<FilePath> removedFiles;
std::set<FilePath> allSourceFilePaths;
};
FileManager();
virtual ~FileManager();
const std::vector<FilePath>& getSourcePaths() const;
void setPaths(
std::vector<FilePath> sourcePaths,
std::vector<FilePath> headerPaths,
@@ -32,24 +30,27 @@ public:
FileSets fetchFilePaths(const std::vector<FileInfo>& oldFileInfos);
virtual bool hasFilePath(const FilePath& filePath) const;
virtual bool hasSourceFilePath(const FilePath& filePath) const;
// returns a list of source paths (can be directories) specified in the project settings
std::vector<FilePath> getSourcePaths() const;
virtual const FileInfo getFileInfo(const FilePath& filePath) const;
// returns a list of paths to all files that reside in the non-excluded source paths
std::set<FilePath> getSourceFilePaths() const;
// checks if file is in non-excluded source directory
virtual bool hasSourceFilePath(const FilePath& filePath) const;
private:
std::vector<FilePath> makeCanonical(const std::vector<FilePath>& filePaths);
bool isExcluded(const FilePath& filePath) const;
std::map<FilePath, FileInfo> m_files;
std::vector<FilePath> m_sourcePaths;
std::vector<FilePath> m_headerPaths;
std::vector<FilePath> m_excludePaths;
std::vector<std::string> m_sourceExtensions;
std::set<FilePath> m_sourceFiles;
std::map<FilePath, FileInfo> m_filesInfos;
std::set<FilePath> m_sourceFilePaths;
};
#endif // FILE_MANAGER_H
+59 -230
View File
@@ -1,246 +1,75 @@
#include "utility/file/FileRegister.h"
#include "utility/file/FileManager.h"
#include "utility/file/FileSystem.h"
FileRegister::FileRegister(const FileRegisterStateData& stateData, const std::set<FilePath>& indexedPaths, const std::set<FilePath>& excludedPaths)
: m_stateData(stateData)
, m_indexedPaths(indexedPaths)
, m_excludedPaths(excludedPaths)
, m_hasFilePathCache(
[&](std::string filePath){
bool ret = false;
for (const FilePath& indexedPath: m_indexedPaths)
{
if (indexedPath.contains(filePath))
{
ret = true;
break;
}
}
FileRegister::FileRegister(const FileManager* fileManager, bool randomizeParseOrder)
: m_fileManager(fileManager)
, m_randomizeParseOrder(randomizeParseOrder)
if (ret)
{
for (const FilePath& excluded: m_excludedPaths)
{
if (excluded.isDirectory())
{
if (excluded.contains(filePath))
{
ret = false;
break;
}
}
else
{
if (excluded == filePath)
{
ret = false;
break;
}
}
}
}
return ret;
}
)
{
}
void FileRegister::setFilePaths(const std::vector<FilePath>& filePaths)
FileRegister::~FileRegister()
{
{
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
m_sourceFilePaths.clear();
}
for (const FilePath& p : filePaths)
{
FilePath path = p.exists() ? p.absolute() : p;
FileRegisterStateData FileRegister::getStateData() const
{
return m_stateData;
}
if (m_fileManager->hasSourceFilePath(path))
{
m_sourceFilePaths.emplace(path, STATE_UNPARSED);
}
}
}
void FileRegister::markFileIndexing(const FilePath& filePath)
{
m_stateData.markFileIndexing(filePath);
}
{
std::lock_guard<std::mutex> lock(m_includeFileMutex);
m_includeFilePaths.clear();
}
void FileRegister::markIndexingFilesIndexed()
{
m_stateData.markIndexingFilesIndexed();
}
{
std::lock_guard<std::mutex> lock(m_threadFileMutex);
m_threadParsingFiles.clear();
}
bool FileRegister::fileIsIndexed(const FilePath& filePath) const
{
return m_stateData.fileIsIndexed(filePath);
}
bool FileRegister::hasFilePath(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_projectFilesMutex);
std::unordered_map<std::string, bool>::iterator it = m_projectFiles.find(filePath.str());
if (it != m_projectFiles.end())
{
return it->second;
}
bool has = m_fileManager->hasFilePath(filePath);
m_projectFiles.emplace(filePath.str(), has);
return has;
}
const FileInfo FileRegister::getFileInfo(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_projectFileInfosMutex);
std::unordered_map<std::string, FileInfo>::iterator it = m_projectFileInfos.find(filePath.str());
if (it != m_projectFileInfos.end())
{
return it->second;
}
FileInfo info = m_fileManager->getFileInfo(filePath);
m_projectFileInfos.emplace(filePath.str(), info);
return info;
}
std::vector<FilePath> FileRegister::getUnparsedSourceFilePaths() const
{
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
std::vector<FilePath> files;
for (std::pair<FilePath, ParseState>&& p : m_sourceFilePaths)
{
if (p.second == STATE_UNPARSED)
{
files.push_back(p.first);
}
}
return files;
}
bool FileRegister::hasIncludeFile(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_includeFileMutex);
std::map<FilePath, ParseState>::const_iterator it = m_includeFilePaths.find(filePath);
return (it != m_includeFilePaths.end());
}
bool FileRegister::fileIsParsed(const FilePath& filePath) const
{
return sourceFileIsParsed(filePath) || includeFileIsParsed(filePath);
}
bool FileRegister::sourceFileIsParsed(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
std::map<FilePath, ParseState>::const_iterator it = m_sourceFilePaths.find(filePath);
if (it == m_sourceFilePaths.end())
{
return false;
}
if (it->second == STATE_PARSED)
{
return true;
}
return false;
}
bool FileRegister::includeFileIsParsed(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_includeFileMutex);
std::map<FilePath, ParseState>::const_iterator it = m_includeFilePaths.find(filePath);
if (it == m_includeFilePaths.end())
{
return false;
}
if (it->second == STATE_PARSED)
{
return true;
}
return false;
}
FilePath FileRegister::consumeSourceFile()
{
std::lock_guard<std::mutex> lock(m_consumeFileMutex);
std::vector<FilePath> paths = getUnparsedSourceFilePaths();
FilePath path;
if (paths.size())
{
if (m_randomizeParseOrder)
{
path = paths[rand() % paths.size()];
}
else
{
path = paths[0];
}
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
m_sourceFilePaths[path] = STATE_PARSING;
}
if (!path.empty())
{
std::lock_guard<std::mutex> lock(m_threadFileMutex);
m_threadParsingFiles[std::this_thread::get_id()].insert(path);
}
return path;
}
void FileRegister::markIncludeFileParsing(const FilePath& filePath)
{
bool unparsed = false;
{
std::lock_guard<std::mutex> lock(m_includeFileMutex);
std::map<FilePath, ParseState>::iterator it = m_includeFilePaths.find(filePath);
if (it != m_includeFilePaths.end())
{
if (it->second == STATE_UNPARSED)
{
it->second = STATE_PARSING;
unparsed = true;
}
}
else
{
m_includeFilePaths.emplace(filePath, STATE_PARSING);
unparsed = true;
}
}
if (unparsed)
{
std::lock_guard<std::mutex> lock(m_threadFileMutex);
m_threadParsingFiles[std::this_thread::get_id()].insert(filePath);
}
}
void FileRegister::markThreadFilesParsed()
{
std::lock_guard<std::mutex> sourceFileLock(m_sourceFileMutex);
std::lock_guard<std::mutex> includeFileLock(m_includeFileMutex);
std::lock_guard<std::mutex> threadFileLock(m_threadFileMutex);
std::set<FilePath>& threadFiles = m_threadParsingFiles[std::this_thread::get_id()];
for (std::set<FilePath>::iterator it = threadFiles.begin(); it != threadFiles.end(); it++)
{
std::map<FilePath, ParseState>::iterator it2;
it2 = m_sourceFilePaths.find(*it);
if (it2 != m_sourceFilePaths.end())
{
it2->second = STATE_PARSED;
continue;
}
it2 = m_includeFilePaths.find(*it);
if (it2 != m_includeFilePaths.end())
{
it2->second = STATE_PARSED;
}
}
threadFiles.clear();
}
size_t FileRegister::getSourceFilesCount() const
{
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
return m_sourceFilePaths.size();
}
size_t FileRegister::getParsedSourceFilesCount() const
{
std::lock_guard<std::mutex> lock(m_sourceFileMutex);
size_t count = 0;
for (std::pair<FilePath, ParseState>&& p : m_sourceFilePaths)
{
if (p.second == STATE_PARSED)
{
count++;
}
}
return count;
return m_hasFilePathCache.getValue(filePath.str());
}
+13 -56
View File
@@ -1,72 +1,29 @@
#ifndef FILE_REGISTER_H
#define FILE_REGISTER_H
#include <map>
#include <unordered_map>
#include <mutex>
#include <set>
#include <string>
#include <thread>
#include <vector>
#include "utility/file/FileInfo.h"
#include "utility/file/FilePath.h"
class FileManager;
#include "utility/file/FileRegisterStateData.h"
#include "utility/Cache.h"
class FileRegister
{
public:
explicit FileRegister(const FileManager* fileManager, bool randomizeParseOrder);
FileRegister(const FileRegisterStateData& stateData, const std::set<FilePath>& indexedPaths, const std::set<FilePath>& excludedPaths);
virtual ~FileRegister();
void setFilePaths(const std::vector<FilePath>& filePaths);
FileRegisterStateData getStateData() const;
bool hasFilePath(const FilePath& filePath) const;
const FileInfo getFileInfo(const FilePath& filePath) const;
std::vector<FilePath> getUnparsedSourceFilePaths() const;
bool hasIncludeFile(const FilePath& filePath) const;
bool fileIsParsed(const FilePath& filePath) const;
bool includeFileIsParsed(const FilePath& filePath) const;
bool sourceFileIsParsed(const FilePath& filePath) const;
FilePath consumeSourceFile();
void markIncludeFileParsing(const FilePath& filePath);
void markThreadFilesParsed();
size_t getSourceFilesCount() const;
size_t getParsedSourceFilesCount() const;
void markFileIndexing(const FilePath& filePath);
void markIndexingFilesIndexed();
virtual bool fileIsIndexed(const FilePath& filePath) const;
virtual bool hasFilePath(const FilePath& filePath) const;
private:
enum ParseState
{
STATE_UNPARSED,
STATE_PARSING,
STATE_PARSED
};
const FileManager* m_fileManager;
bool m_randomizeParseOrder;
mutable std::unordered_map<std::string, bool> m_projectFiles;
mutable std::mutex m_projectFilesMutex;
mutable std::unordered_map<std::string, FileInfo> m_projectFileInfos;
mutable std::mutex m_projectFileInfosMutex;
std::map<FilePath, ParseState> m_sourceFilePaths;
std::map<FilePath, ParseState> m_includeFilePaths;
std::map<std::thread::id, std::set<FilePath>> m_threadParsingFiles;
mutable std::mutex m_sourceFileMutex;
mutable std::mutex m_includeFileMutex;
mutable std::mutex m_threadFileMutex;
std::mutex m_consumeFileMutex;
FileRegisterStateData m_stateData;
const std::set<FilePath> m_indexedPaths;
const std::set<FilePath> m_excludedPaths;
mutable Cache<std::string, bool> m_hasFilePathCache;
};
#endif // FILE_REGISTER_H
@@ -0,0 +1,61 @@
#include "utility/file/FileRegisterStateData.h"
FileRegisterStateData::FileRegisterStateData()
{
}
FileRegisterStateData::FileRegisterStateData(const FileRegisterStateData& o)
{
this->inject(o);
}
void FileRegisterStateData::inject(const FileRegisterStateData& o)
{
std::lock_guard<std::mutex> oLock(o.m_filePathsMutex);
std::lock_guard<std::mutex> thisLock(m_filePathsMutex);
for (const auto& it: o.m_filePaths)
{
if (it.second == STATE_INDEXED)
{
m_filePaths[it.first] = STATE_INDEXED;
}
}
}
void FileRegisterStateData::markFileIndexing(const FilePath& filePath)
{
std::lock_guard<std::mutex> lock(m_filePathsMutex);
auto it = m_filePaths.find(filePath);
if (it != m_filePaths.end())
{
it->second = STATE_INDEXING;
}
else
{
m_filePaths.insert(std::make_pair(filePath, STATE_INDEXING));
}
}
void FileRegisterStateData::markIndexingFilesIndexed()
{
std::lock_guard<std::mutex> lock(m_filePathsMutex);
for (auto it: m_filePaths)
{
if (it.second == STATE_INDEXING)
{
it.second = STATE_INDEXED;
}
}
}
bool FileRegisterStateData::fileIsIndexed(const FilePath& filePath) const
{
std::lock_guard<std::mutex> lock(m_filePathsMutex);
auto it = m_filePaths.find(filePath);
if (it != m_filePaths.end())
{
return it->second == STATE_INDEXED;
}
return false;
}
@@ -0,0 +1,33 @@
#ifndef FILE_REGISTER_STATE_DATA_H
#define FILE_REGISTER_STATE_DATA_H
#include <mutex>
#include <map>
#include "utility/file/FilePath.h"
class FileRegisterStateData
{
public:
FileRegisterStateData();
FileRegisterStateData(const FileRegisterStateData& o);
void inject(const FileRegisterStateData& o);
void markFileIndexing(const FilePath& filePath);
void markIndexingFilesIndexed();
bool fileIsIndexed(const FilePath& filePath) const;
private:
enum IndexingState
{
STATE_NON_INDEXED,
STATE_INDEXING,
STATE_INDEXED
};
std::map<FilePath, IndexingState> m_filePaths;
mutable std::mutex m_filePathsMutex;
};
#endif // FILE_REGISTER_STATE_DATA_H
@@ -39,51 +39,51 @@ void InterprocessDataManager::initialize()
}
}
void InterprocessDataManager::pushParserArguments(const Parser::Arguments& arguments)
{
IF_INITIALIZED()
{
SharedParserArguments::VoidAllocator allocator(m_parserArguments.getSegmentManager());
SharedParserArguments args(allocator);
args.setCompilationDatabasePath(arguments.compilationDatabasePath.str());
args.setCompilerFlags(arguments.compilerFlags);
args.setFrameworkSearchPaths(arguments.frameworkSearchPaths);
args.setHeaderSearchPaths(arguments.headerSearchPaths);
args.setJavaClassPaths(arguments.javaClassPaths);
args.setLanguage(arguments.language);
args.setLanguageStandard(arguments.languageStandard);
args.setLogErrors(arguments.logErrors);
args.setSystemHeaderSearchPaths(arguments.systemHeaderSearchPaths);
m_parserArguments.pushValue(args);
}
}
Parser::Arguments InterprocessDataManager::popParserArguments()
{
IF_INITIALIZED(Parser::Arguments())
{
if (m_parserArguments.size() > 0)
{
SharedParserArguments args = m_parserArguments.popValue();
Parser::Arguments result;
result.compilationDatabasePath = FilePath(args.getCompilationDatabasePath());
result.compilerFlags = args.getCompilerFlags();
result.frameworkSearchPaths = args.getFrameworkSearchPaths();
result.headerSearchPaths = args.getHeaderSearchPaths();
result.javaClassPaths = args.getJavaClassPaths();
result.language = args.getLanguage();
result.languageStandard = args.getLanguageStandard();
result.logErrors = args.getLogErrors();
result.systemHeaderSearchPaths = args.getSystemHeaderSearchPaths();
return result;
}
}
}
//void InterprocessDataManager::pushParserArguments(const Parser::Arguments& arguments)
//{
// IF_INITIALIZED()
// {
// SharedParserArguments::VoidAllocator allocator(m_parserArguments.getSegmentManager());
// SharedParserArguments args(allocator);
//
// args.setCompilationDatabasePath(arguments.compilationDatabasePath.str());
// args.setCompilerFlags(arguments.compilerFlags);
// args.setFrameworkSearchPaths(arguments.frameworkSearchPaths);
// args.setHeaderSearchPaths(arguments.headerSearchPaths);
// args.setJavaClassPaths(arguments.javaClassPaths);
// args.setLanguage(arguments.language);
// args.setLanguageStandard(arguments.languageStandard);
// args.setLogErrors(arguments.logErrors);
// args.setSystemHeaderSearchPaths(arguments.systemHeaderSearchPaths);
//
// m_parserArguments.pushValue(args);
// }
//}
//
//Parser::Arguments InterprocessDataManager::popParserArguments()
//{
// IF_INITIALIZED(Parser::Arguments())
// {
// if (m_parserArguments.size() > 0)
// {
// SharedParserArguments args = m_parserArguments.popValue();
//
// Parser::Arguments result;
//
// result.compilationDatabasePath = FilePath(args.getCompilationDatabasePath());
// result.compilerFlags = args.getCompilerFlags();
// result.frameworkSearchPaths = args.getFrameworkSearchPaths();
// result.headerSearchPaths = args.getHeaderSearchPaths();
// result.javaClassPaths = args.getJavaClassPaths();
// result.language = args.getLanguage();
// result.languageStandard = args.getLanguageStandard();
// result.logErrors = args.getLogErrors();
// result.systemHeaderSearchPaths = args.getSystemHeaderSearchPaths();
//
// return result;
// }
// }
//}
unsigned int InterprocessDataManager::parserArgumentCount() const
{
@@ -15,8 +15,13 @@ public:
void initialize();
void pushParserArguments(const Parser::Arguments& arguments);
Parser::Arguments popParserArguments();
// TODO: use IndexerCommands here and rename SharedParserArguments to SharedIndexerCommand
// TODO: either make one SharedIndexerCommand that stores everything or make
// SharedIndexerCommandJava, SharedIndexerCommandCxxManual, ..., each having a separate datastructure here
//void pushParserArguments(const Parser::Arguments& arguments);
//Parser::Arguments popParserArguments();
unsigned int parserArgumentCount() const;
private:
@@ -1,8 +1,6 @@
#ifndef TASK_RETURN_SUCCESS_WHILE_H
#define TASK_RETURN_SUCCESS_WHILE_H
#include <vector>
#include "utility/scheduling/Task.h"
#include "utility/scheduling/Blackboard.h"
+54
View File
@@ -0,0 +1,54 @@
#ifndef TASK_SET_VALUE_H
#define TASK_SET_VALUE_H
#include "utility/scheduling/Task.h"
#include "utility/scheduling/Blackboard.h"
template <typename T>
class TaskSetValue:
public Task
{
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);
const std::string m_valueName;
const T m_value;
};
template <typename T>
TaskSetValue<T>::TaskSetValue(const std::string& valueName, T value)
: m_valueName(valueName)
, m_value(value)
{
}
template <typename T>
void TaskSetValue<T>::doEnter(std::shared_ptr<Blackboard> blackboard)
{
}
template <typename T>
Task::TaskState TaskSetValue<T>::doUpdate(std::shared_ptr<Blackboard> blackboard)
{
std::lock_guard<std::mutex> lock(blackboard->getMutex());
blackboard->set<T>(m_valueName, m_value);
return STATE_SUCCESS;
}
template <typename T>
void TaskSetValue<T>::doExit(std::shared_ptr<Blackboard> blackboard)
{
}
template <typename T>
void TaskSetValue<T>::doReset(std::shared_ptr<Blackboard> blackboard)
{
}
#endif // TASK_SET_VALUE_H