27 #include <unordered_map>
38 class DSNVisitor :
public Visitor {
41 void visit(TextEntry& text)
override {
42 if (text.getKey() ==
"source-locator") {
43 base.setLocator(text.getText());
46 void visit(DurationEntry&
duration)
override {
47 if (
duration.getKey() ==
"runtime") {
52 void visit(SizeEntry&
size)
override {
53 if (
size.getKey() ==
"num-tuples") {
57 void visit(DirectoryEntry& )
override {}
67 class AtomFrequenciesVisitor :
public Visitor {
70 void visit(DirectoryEntry& directory)
override {
71 const std::string& clause = directory.getKey();
73 for (
auto& key : directory.getKeys()) {
74 auto* level =
dynamic_cast<SizeEntry*
>(directory.readDirectoryEntry(key)->readEntry(
"level"));
76 dynamic_cast<SizeEntry*
>(directory.readDirectoryEntry(key)->readEntry(
"num-tuples"));
78 size_t intFreq = frequency ==
nullptr ? 0 : frequency->getSize();
79 size_t intLevel = level ==
nullptr ? 0 : level->getSize();
80 rule.addAtomFrequency(clause, key, intLevel, intFreq);
92 class RecursiveRuleVisitor :
public DSNVisitor<Rule> {
94 RecursiveRuleVisitor(Rule&
rule) : DSNVisitor(
rule) {}
95 void visit(DirectoryEntry& directory)
override {
96 if (directory.getKey() ==
"atom-frequency") {
97 AtomFrequenciesVisitor atomFrequenciesVisitor(
base);
98 for (
auto& key : directory.getKeys()) {
99 directory.readDirectoryEntry(key)->accept(atomFrequenciesVisitor);
109 class RecursiveRulesVisitor :
public Visitor {
113 void visit(DirectoryEntry& ruleEntry)
override {
114 for (
const auto& key : ruleEntry.getKeys()) {
115 auto& versions = *ruleEntry.readDirectoryEntry(key);
116 auto rule = std::make_shared<Rule>(
117 ruleEntry.getKey(), std::stoi(key),
relation.createRecID(ruleEntry.getKey()));
118 RecursiveRuleVisitor visitor(*
rule);
119 for (
const auto& versionKey : versions.getKeys()) {
120 versions.readEntry(versionKey)->accept(visitor);
123 std::string ruleKey = key +
rule->getLocator() + key;
137 class NonRecursiveRuleVisitor :
public DSNVisitor<Rule> {
139 NonRecursiveRuleVisitor(Rule&
rule) : DSNVisitor(
rule) {}
140 void visit(DirectoryEntry& directory)
override {
141 if (directory.getKey() ==
"atom-frequency") {
142 AtomFrequenciesVisitor atomFrequenciesVisitor(
base);
143 for (
auto& key : directory.getKeys()) {
144 directory.readDirectoryEntry(key)->accept(atomFrequenciesVisitor);
154 class NonRecursiveRulesVisitor :
public Visitor {
157 void visit(DirectoryEntry& ruleEntry)
override {
158 auto rule = std::make_shared<Rule>(ruleEntry.getKey(),
relation.createID());
159 NonRecursiveRuleVisitor visitor(*
rule);
160 for (
const auto& key : ruleEntry.getKeys()) {
161 ruleEntry.readEntry(key)->accept(visitor);
174 class IterationVisitor :
public DSNVisitor<Iteration> {
177 void visit(DurationEntry&
duration)
override {
178 if (
duration.getKey() ==
"copytime") {
180 base.setCopytime(copytime);
184 void visit(DirectoryEntry& directory)
override {
185 if (directory.getKey() ==
"recursive-rule") {
187 for (
const auto& key : directory.getKeys()) {
188 directory.readEntry(key)->accept(rulesVisitor);
191 if (directory.getKey() ==
"maxRSS") {
192 auto* preMaxRSS =
dynamic_cast<SizeEntry*
>(directory.readEntry(
"pre"));
193 auto* postMaxRSS =
dynamic_cast<SizeEntry*
>(directory.readEntry(
"post"));
194 relation.setPreMaxRSS(preMaxRSS->getSize());
195 relation.setPostMaxRSS(postMaxRSS->getSize());
207 class IterationsVisitor :
public Visitor {
210 void visit(DirectoryEntry& ruleEntry)
override {
211 auto iteration = std::make_shared<Iteration>();
214 for (
const auto& key : ruleEntry.getKeys()) {
215 ruleEntry.readEntry(key)->accept(visitor);
227 class RelationVisitor :
public DSNVisitor<Relation> {
230 void visit(DurationEntry&
duration)
override {
231 if (
duration.getKey() ==
"loadtime") {
233 base.setLoadtime(loadtime);
234 }
else if (
duration.getKey() ==
"savetime") {
236 base.setSavetime(savetime);
240 void visit(DirectoryEntry& directory)
override {
241 if (directory.getKey() ==
"iteration") {
242 IterationsVisitor iterationsVisitor(
base);
243 for (
const auto& key : directory.getKeys()) {
244 directory.readEntry(key)->accept(iterationsVisitor);
246 }
else if (directory.getKey() ==
"non-recursive-rule") {
247 NonRecursiveRulesVisitor rulesVisitor(
base);
248 for (
const auto& key : directory.getKeys()) {
249 directory.readEntry(key)->accept(rulesVisitor);
251 }
else if (directory.getKey() ==
"maxRSS") {
252 auto* preMaxRSS =
dynamic_cast<SizeEntry*
>(directory.readEntry(
"pre"));
253 auto* postMaxRSS =
dynamic_cast<SizeEntry*
>(directory.readEntry(
"post"));
254 base.setPreMaxRSS(preMaxRSS->getSize());
255 base.setPostMaxRSS(postMaxRSS->getSize());
258 void visit(SizeEntry&
size)
override {
259 if (
size.getKey() ==
"reads") {
262 DSNVisitor::visit(
size);
279 std::unordered_map<std::string, std::shared_ptr<Relation>>
relationMap{};
283 std::shared_ptr<ProgramRun>
run;
285 Reader(std::string filename, std::shared_ptr<ProgramRun>
run)
289 }
catch (
const std::exception&
e) {
290 fatal(
"exception whilst reading profile DB: %s",
e.what());
301 auto programDuration =
dynamic_cast<DurationEntry*
>(
db.lookupEntry({
"program",
"runtime"}));
302 if (programDuration ==
nullptr) {
303 auto startTimeEntry =
dynamic_cast<TimeEntry*
>(
db.lookupEntry({
"program",
"starttime"}));
304 if (startTimeEntry !=
nullptr) {
305 run->setStarttime(startTimeEntry->getTime());
306 run->setEndtime(std::chrono::duration_cast<microseconds>(
now().time_since_epoch()));
309 run->setStarttime(programDuration->getStart());
310 run->setEndtime(programDuration->getEnd());
314 auto relations =
dynamic_cast<DirectoryEntry*
>(
db.lookupEntry({
"program",
"relation"}));
319 for (
const auto& cur :
relations->getKeys()) {
320 auto relation =
dynamic_cast<DirectoryEntry*
>(
db.lookupEntry({
"program",
"relation", cur}));
326 for (
const auto&
rule :
relation.second->getRuleMap()) {
327 for (
const auto& atom :
rule.second->getAtoms()) {
329 relationMap[relationName]->addReads(atom.frequency);
334 for (
const auto& atom :
rule.second->getAtoms()) {
336 if (relationName.substr(0, 6) ==
"@delta") {
337 relationName = relationName.substr(7);
339 assert(
relationMap.count(relationName) > 0 ||
"Relation name for atom not found");
340 relationMap[relationName]->addReads(atom.frequency);
345 run->setRelationMap(this->relationMap);
349 void save(std::string f_name);
360 RelationVisitor relationVisitor(
rel);
362 for (
const auto& key :
relation.getKeys()) {
363 relation.readEntry(key)->accept(relationVisitor);
372 return "R" + std::to_string(++
rel_id);
376 return "R" + std::to_string(++
rel_id);
381 std::string cleanName = relationName;
382 for (
auto& cur : cleanName) {