data: indexer processes

* TaskBuildIndex starts seperate indexer processes and communicates via shared memory
* indexer processes get restarted if they fail
* indexer processes are killed when the app closes or crashes
* added utility class SharedMemory to allocate and access shared memory, providing basic data structures
* added SharedMemoryGarbageCollector for keeping track of running instances and cleaning up shared memory in case of a crash
* show errors for source files that crashed during indexing
* added basic exception handling to task scheduling
* added option to turn off processes and use threads in preferences, but still use shared memory

fortune cookie message = Good news from someone dear is coming soon.
This commit is contained in:
Eberhard Graether
2017-05-04 15:50:59 +02:00
parent 9beea94fd8
commit 706119ebcc
109 changed files with 3351 additions and 1261 deletions
+1
View File
@@ -23,6 +23,7 @@ add_files(
SettingsTestSuite.h
SettingsMigratorTestSuite.h
SearchIndexTestSuite.h
SharedMemoryTestSuite.h
SourceLocationCollectionTestSuite.h
SqliteBookmarkStorageTestSuite.h
SqliteIndexStorageTestSuite.h
-1
View File
@@ -12,7 +12,6 @@
#include "helper/TestParserClient.h"
class JavaParserTestSuite: public CxxTest::TestSuite
{
public:
+95
View File
@@ -0,0 +1,95 @@
#include <cxxtest/TestSuite.h>
#include "utility/interprocess/SharedMemory.h"
class SharedMemoryTestSuite : public CxxTest::TestSuite
{
public:
void test_shared_memory(void)
{
SharedMemory memory("memory", 1000, SharedMemory::CREATE_AND_DELETE);
{
SharedMemory::ScopedAccess access(&memory);
TS_ASSERT_EQUALS(access.getMemorySize(), 1000);
*access.accessValue<int>("count") = 0;
}
std::vector<std::shared_ptr<std::thread>> threads;
for (unsigned int i = 0; i < 4; i++)
{
threads.push_back(std::make_shared<std::thread>(
[]()
{
SharedMemory memory("memory", 0, SharedMemory::OPEN_ONLY);
SharedMemory::ScopedAccess access(&memory);
if (access.getMemorySize() < 5000)
{
access.growMemory(5000 - access.getMemorySize());
}
int* count = access.accessValue<int>("count");
*count += 1;
SharedMemory::String* str = access.accessValueWithAllocator<SharedMemory::String>("string");
str->append("hi");
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
nums->push_back(nums->size());
SharedMemory::Vector<SharedMemory::String>* strings =
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
strings->push_back(SharedMemory::String("ho", access.getAllocator()));
SharedMemory::Map<int, int>* vals =
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
vals->emplace(vals->size(), vals->size() * vals->size());
}
));
}
for (auto thread : threads)
{
thread->join();
}
threads.clear();
{
SharedMemory::ScopedAccess access(&memory);
TS_ASSERT_EQUALS(access.getMemorySize(), 5000);
TS_ASSERT_EQUALS(*access.accessValue<int>("count"), 4);
TS_ASSERT_EQUALS(access.accessValueWithAllocator<SharedMemory::String>("string")->c_str(), "hihihihi");
SharedMemory::Vector<int>* nums = access.accessValueWithAllocator<SharedMemory::Vector<int>>("nums");
TS_ASSERT_EQUALS(nums->size(), 4);
for (int i : *nums)
{
TS_ASSERT_EQUALS(i, i);
}
SharedMemory::Vector<SharedMemory::String>* strings =
access.accessValueWithAllocator<SharedMemory::Vector<SharedMemory::String>>("strings");
TS_ASSERT_EQUALS(strings->size(), 4);
for (SharedMemory::String str : *strings)
{
TS_ASSERT_EQUALS(str, "ho");
}
SharedMemory::Map<int, int>* vals =
access.accessValueWithAllocator<SharedMemory::Map<int, int>>("vals");
TS_ASSERT_EQUALS(vals->size(), 4);
size_t i = 0;
for (auto val : *vals)
{
TS_ASSERT_EQUALS(val.first, i);
TS_ASSERT_EQUALS(val.second, i * i);
i++;
}
}
}
};