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) {