| 1 | /*
 | 
| 2 |  * Souffle - A Datalog Compiler
 | 
| 3 |  * Copyright (c) 2016, The Souffle Developers. All rights reserved
 | 
| 4 |  * Licensed under the Universal Permissive License v 1.0 as shown at:
 | 
| 5 |  * - https://opensource.org/licenses/UPL
 | 
| 6 |  * - <souffle root>/licenses/SOUFFLE-UPL.txt
 | 
| 7 |  */
 | 
| 8 | 
 | 
| 9 | #pragma once
 | 
| 10 | 
 | 
| 11 | #include <chrono>
 | 
| 12 | #include <set>
 | 
| 13 | #include <sstream>
 | 
| 14 | #include <string>
 | 
| 15 | #include <tuple>
 | 
| 16 | #include <utility>
 | 
| 17 | 
 | 
| 18 | namespace souffle {
 | 
| 19 | namespace profile {
 | 
| 20 | 
 | 
| 21 | /*
 | 
| 22 |  * Class to hold information about souffle Atom profile information
 | 
| 23 |  */
 | 
| 24 | class Atom {
 | 
| 25 | public:
 | 
| 26 |     const std::string identifier;
 | 
| 27 |     const std::string rule;
 | 
| 28 |     const std::size_t level;
 | 
| 29 |     const std::size_t frequency;
 | 
| 30 | 
 | 
| 31 |     Atom(std::string identifier, std::string rule, std::size_t level, std::size_t frequency)
 | 
| 32 |             : identifier(std::move(identifier)), rule(std::move(rule)), level(level), frequency(frequency) {}
 | 
| 33 | 
 | 
| 34 |     bool operator<(const Atom& other) const {
 | 
| 35 |         if (rule != other.rule) {
 | 
| 36 |             return rule < other.rule;
 | 
| 37 |         } else if (level != other.level) {
 | 
| 38 |             return level < other.level;
 | 
| 39 |         }
 | 
| 40 |         return identifier < other.identifier;
 | 
| 41 |     }
 | 
| 42 | };
 | 
| 43 | 
 | 
| 44 | /*
 | 
| 45 |  * Class to hold information about souffle Rule profile information
 | 
| 46 |  */
 | 
| 47 | class Rule {
 | 
| 48 | protected:
 | 
| 49 |     const std::string name;
 | 
| 50 |     std::chrono::microseconds starttime{};
 | 
| 51 |     std::chrono::microseconds endtime{};
 | 
| 52 |     std::size_t numTuples{0};
 | 
| 53 |     std::string identifier;
 | 
| 54 |     std::string locator{};
 | 
| 55 |     std::set<Atom> atoms;
 | 
| 56 | 
 | 
| 57 | private:
 | 
| 58 |     bool recursive = false;
 | 
| 59 |     int version = 0;
 | 
| 60 | 
 | 
| 61 | public:
 | 
| 62 |     Rule(std::string name, std::string id) : name(std::move(name)), identifier(std::move(id)) {}
 | 
| 63 | 
 | 
| 64 |     Rule(std::string name, int version, std::string id)
 | 
| 65 |             : name(std::move(name)), identifier(std::move(id)), recursive(true), version(version) {}
 | 
| 66 | 
 | 
| 67 |     std::string getId() const {
 | 
| 68 |         return identifier;
 | 
| 69 |     }
 | 
| 70 | 
 | 
| 71 |     std::chrono::microseconds getRuntime() const {
 | 
| 72 |         return endtime - starttime;
 | 
| 73 |     }
 | 
| 74 | 
 | 
| 75 |     std::chrono::microseconds getStarttime() const {
 | 
| 76 |         return starttime;
 | 
| 77 |     }
 | 
| 78 | 
 | 
| 79 |     std::chrono::microseconds getEndtime() const {
 | 
| 80 |         return endtime;
 | 
| 81 |     }
 | 
| 82 | 
 | 
| 83 |     std::size_t size() {
 | 
| 84 |         return numTuples;
 | 
| 85 |     }
 | 
| 86 | 
 | 
| 87 |     void setStarttime(std::chrono::microseconds time) {
 | 
| 88 |         starttime = time;
 | 
| 89 |     }
 | 
| 90 | 
 | 
| 91 |     void setEndtime(std::chrono::microseconds time) {
 | 
| 92 |         endtime = time;
 | 
| 93 |     }
 | 
| 94 | 
 | 
| 95 |     void setNumTuples(std::size_t numTuples) {
 | 
| 96 |         this->numTuples = numTuples;
 | 
| 97 |     }
 | 
| 98 | 
 | 
| 99 |     void addAtomFrequency(
 | 
| 100 |             const std::string& subruleName, std::string atom, std::size_t level, std::size_t frequency) {
 | 
| 101 |         atoms.emplace(atom, subruleName, level, frequency);
 | 
| 102 |     }
 | 
| 103 | 
 | 
| 104 |     const std::set<Atom>& getAtoms() const {
 | 
| 105 |         return atoms;
 | 
| 106 |     }
 | 
| 107 |     std::string getName() const {
 | 
| 108 |         return name;
 | 
| 109 |     }
 | 
| 110 | 
 | 
| 111 |     void setId(std::string id) {
 | 
| 112 |         identifier = id;
 | 
| 113 |     }
 | 
| 114 | 
 | 
| 115 |     std::string getLocator() const {
 | 
| 116 |         return locator;
 | 
| 117 |     }
 | 
| 118 | 
 | 
| 119 |     void setLocator(std::string locator) {
 | 
| 120 |         this->locator = locator;
 | 
| 121 |     }
 | 
| 122 | 
 | 
| 123 |     bool isRecursive() const {
 | 
| 124 |         return recursive;
 | 
| 125 |     }
 | 
| 126 | 
 | 
| 127 |     void setRecursive(bool recursive) {
 | 
| 128 |         this->recursive = recursive;
 | 
| 129 |     }
 | 
| 130 | 
 | 
| 131 |     int getVersion() const {
 | 
| 132 |         return version;
 | 
| 133 |     }
 | 
| 134 | 
 | 
| 135 |     void setVersion(int version) {
 | 
| 136 |         this->version = version;
 | 
| 137 |     }
 | 
| 138 | 
 | 
| 139 |     std::string toString() const {
 | 
| 140 |         std::ostringstream output;
 | 
| 141 |         if (recursive) {
 | 
| 142 |             output << "{" << name << "," << version << ":";
 | 
| 143 |         } else {
 | 
| 144 |             output << "{" << name << ":";
 | 
| 145 |         }
 | 
| 146 |         output << "[" << getRuntime().count() << "," << numTuples << "]}";
 | 
| 147 |         return output.str();
 | 
| 148 |     }
 | 
| 149 | };
 | 
| 150 | 
 | 
| 151 | }  // namespace profile
 | 
| 152 | }  // namespace souffle
 |