Line data Source code
1 : #include "CLI/CLI.hpp"
2 : #include "oks/kernel.hpp"
3 : #include <deque>
4 : #include <fmt/core.h>
5 : #include <iostream>
6 :
7 : namespace dunedaq {
8 : namespace oks {
9 :
10 : std::deque<std::set<OksClass*>>
11 0 : construct_class_domains(const OksKernel& k)
12 : {
13 :
14 0 : std::deque<std::set<OksClass*>> domains;
15 :
16 : // Find classes with no superclasses.
17 : // They are domain (or inheritance cluster) seeds
18 0 : std::deque<OksClass*> progenitors;
19 0 : for (auto const& [key, kl] : k.classes()) {
20 0 : if (kl->direct_super_classes() == nullptr) {
21 0 : progenitors.push_back(kl);
22 : }
23 : }
24 :
25 : // Loop over seeds
26 0 : for (auto kl : progenitors) {
27 :
28 : // Make a candidate cluster based using the seed subclasses
29 0 : std::set<OksClass*> klass_cluster;
30 0 : klass_cluster.insert(kl);
31 0 : klass_cluster.insert(kl->all_sub_classes()->begin(), kl->all_sub_classes()->end());
32 :
33 : // Look for overlaps with other domains
34 0 : std::deque<std::set<OksClass*>> overlapping;
35 0 : for (auto& dom : domains) {
36 0 : std::set<OksClass*> intersection;
37 0 : std::set_intersection(dom.begin(),
38 : dom.end(),
39 : klass_cluster.begin(),
40 : klass_cluster.end(),
41 : std::inserter(intersection, intersection.begin()));
42 : // non-zero intersection, overlap found
43 0 : if (intersection.size() > 0) {
44 0 : overlapping.push_back(dom);
45 : }
46 0 : }
47 :
48 : // If overlapping are found, merge all overlapping domains
49 0 : if (overlapping.size() > 0) {
50 0 : for (auto& dom : overlapping) {
51 : // merge the existing cluster in klass_cluster
52 0 : klass_cluster.insert(dom.begin(), dom.end());
53 : // Remove the old cluster from the list
54 0 : auto it = std::find(domains.begin(), domains.end(), dom);
55 0 : if (it != domains.end()) {
56 0 : domains.erase(it);
57 : }
58 : }
59 : }
60 :
61 0 : domains.push_back(klass_cluster);
62 0 : }
63 :
64 0 : return domains;
65 0 : }
66 :
67 : } // namespace oks
68 : } // namespace dunedaq
69 :
70 : int
71 0 : main(int argc, char const* argv[])
72 : {
73 0 : using namespace dunedaq::oks;
74 :
75 0 : CLI::App app{ "App description" };
76 :
77 0 : std::string file;
78 0 : app.add_option("-f,--file", file, "Schema file")->required()->check(CLI::ExistingFile);
79 :
80 0 : CLI11_PARSE(app, argc, argv);
81 :
82 0 : fmt::print("Schema file: {}\n", file);
83 :
84 0 : OksKernel k;
85 0 : fmt::print("Kernel allow duplicated objects: {}\n", k.get_allow_duplicated_objects_mode());
86 0 : fmt::print("Kernel test duplicated objects via inheritance: {}\n",
87 0 : k.get_test_duplicated_objects_via_inheritance_mode());
88 0 : k.set_test_duplicated_objects_via_inheritance_mode(true);
89 0 : fmt::print("Kernel test duplicated objects via inheritance: {}\n",
90 0 : k.get_test_duplicated_objects_via_inheritance_mode());
91 :
92 0 : k.load_schema(file);
93 :
94 0 : auto domains = construct_class_domains(k);
95 :
96 0 : std::map<const OksClass*, uint> class_domain_map;
97 :
98 : // Print the clustered domains
99 0 : fmt::print("Found {} inheritance domains\n", domains.size());
100 0 : for (size_t i(0); i < domains.size(); ++i) {
101 0 : auto& d = domains[i];
102 0 : fmt::print(" - {} : [", i);
103 0 : for (const auto* kl : d) {
104 0 : fmt::print(" {},", kl->get_name());
105 0 : class_domain_map[kl] = i;
106 : }
107 0 : fmt::print("]\n");
108 : }
109 :
110 : /* code */
111 0 : return 0;
112 0 : }
|