mirror of https://github.com/Icinga/icinga2.git
Introduce Type::GetConfigTypesSortedByLoadDependencies()
This commit is contained in:
parent
4f690a6fde
commit
b848934d57
|
@ -23,6 +23,7 @@ enum class InitializePriority {
|
|||
RegisterBuiltinTypes,
|
||||
RegisterFunctions,
|
||||
RegisterTypes,
|
||||
SortTypes,
|
||||
EvaluateConfigFragments,
|
||||
Default,
|
||||
FreezeNamespaces,
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "base/type.hpp"
|
||||
#include "base/atomic.hpp"
|
||||
#include "base/configobject.hpp"
|
||||
#include "base/debug.hpp"
|
||||
#include "base/scriptglobal.hpp"
|
||||
#include "base/namespace.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -32,6 +38,59 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
|
|||
Type::Register(type);
|
||||
}, InitializePriority::RegisterTypeType);
|
||||
|
||||
static std::vector<Type::Ptr> l_SortedByLoadDependencies;
|
||||
static Atomic l_SortingByLoadDependenciesDone (false);
|
||||
|
||||
typedef std::unordered_map<Type*, bool> Visited; // https://stackoverflow.com/a/8942986
|
||||
|
||||
INITIALIZE_ONCE_WITH_PRIORITY([] {
|
||||
auto types (Type::GetAllTypes());
|
||||
|
||||
types.erase(std::remove_if(types.begin(), types.end(), [](auto& type) {
|
||||
return !ConfigObject::TypeInstance->IsAssignableFrom(type);
|
||||
}), types.end());
|
||||
|
||||
// Depth-first search
|
||||
std::unordered_set<Type*> unsorted;
|
||||
Visited visited;
|
||||
std::vector<Type::Ptr> sorted;
|
||||
|
||||
for (auto type : types) {
|
||||
unsorted.emplace(type.get());
|
||||
}
|
||||
|
||||
std::function<void(Type*)> visit ([&visit, &unsorted, &visited, &sorted](Type* type) {
|
||||
if (unsorted.find(type) == unsorted.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool& alreadyVisited (visited.at(type));
|
||||
VERIFY(!alreadyVisited);
|
||||
alreadyVisited = true;
|
||||
|
||||
for (auto dep : type->GetLoadDependencies()) {
|
||||
visit(dep);
|
||||
}
|
||||
|
||||
unsorted.erase(type);
|
||||
sorted.emplace_back(type);
|
||||
});
|
||||
|
||||
while (!unsorted.empty()) {
|
||||
for (auto& type : types) {
|
||||
visited[type.get()] = false;
|
||||
}
|
||||
|
||||
visit(*unsorted.begin());
|
||||
}
|
||||
|
||||
VERIFY(sorted.size() == types.size());
|
||||
VERIFY(sorted[0]->GetLoadDependencies().empty());
|
||||
|
||||
std::swap(sorted, l_SortedByLoadDependencies);
|
||||
l_SortingByLoadDependenciesDone.store(true);
|
||||
}, InitializePriority::SortTypes);
|
||||
|
||||
String Type::ToString() const
|
||||
{
|
||||
return "type '" + GetName() + "'";
|
||||
|
@ -72,6 +131,12 @@ std::vector<Type::Ptr> Type::GetAllTypes()
|
|||
return types;
|
||||
}
|
||||
|
||||
const std::vector<Type::Ptr>& Type::GetConfigTypesSortedByLoadDependencies()
|
||||
{
|
||||
VERIFY(l_SortingByLoadDependenciesDone.load());
|
||||
return l_SortedByLoadDependencies;
|
||||
}
|
||||
|
||||
String Type::GetPluralName() const
|
||||
{
|
||||
String name = GetName();
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
static void Register(const Type::Ptr& type);
|
||||
static Type::Ptr GetByName(const String& name);
|
||||
static std::vector<Type::Ptr> GetAllTypes();
|
||||
static const std::vector<Ptr>& GetConfigTypesSortedByLoadDependencies();
|
||||
|
||||
void SetField(int id, const Value& value, bool suppress_events = false, const Value& cookie = Empty) override;
|
||||
Value GetField(int id) const override;
|
||||
|
|
Loading…
Reference in New Issue