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