1 #pragma once
2 
3 #include <QReadWriteLock>
4 #include <unordered_map>
5 
6 #include "core.hh"
7 
8 #include "solver_id.hh"
9 
10 namespace cpprofiler
11 {
12 
13 class NameMap;
14 
15 class IdMap
16 {
17 
18     mutable QReadWriteLock m_lock;
19 
20     std::unordered_map<SolverID, NodeID> uid2id_;
21 
22     std::unordered_map<NodeID, SolverID> nid2uid_;
23 
24   public:
25     void addPair(SolverID, NodeID);
26 
27     NodeID get(SolverID) const;
28 
getUID(NodeID nid) const29     SolverID getUID(NodeID nid) const
30     {
31         auto it = nid2uid_.find(nid);
32 
33         if (it != nid2uid_.end())
34         {
35             return nid2uid_.at(nid);
36         }
37         else
38         {
39             return {-1, -1, -1};
40         }
41     }
42 };
43 
44 class SolverData
45 {
46 
47     /// TODO:save/load id map to/from DB
48     IdMap m_id_map;
49 
50     std::unordered_map<NodeID, Info> info_map_;
51 
52     std::unordered_map<NodeID, Nogood> nogood_map_;
53 
54     /// Constraints contributing to a no-good at NodeID
55     std::unordered_map<NodeID, std::vector<int>> contrib_cs_;
56 
57     /// Nogoods contributing to the failure at node NodeID
58     std::unordered_map<NodeID, std::vector<NodeID>> contrib_ngs_;
59 
60     /// Time since the beginning of solving process;
61     std::unordered_map<NodeID, int> node_time_;
62 
63   public:
getNodeId(SolverID sid) const64     NodeID getNodeId(SolverID sid) const
65     {
66         return m_id_map.get(sid);
67     }
68 
setNodeId(SolverID sid,NodeID nid)69     void setNodeId(SolverID sid, NodeID nid)
70     {
71         m_id_map.addPair(sid, nid);
72     }
73 
getSolverID(NodeID nid) const74     SolverID getSolverID(NodeID nid) const
75     {
76         return m_id_map.getUID(nid);
77     }
78 
79     /// Get the reasons (constraint ids) for the nogood at node `nid`
getContribConstraints(NodeID nid) const80     const std::vector<int> *getContribConstraints(NodeID nid) const
81     {
82         const auto it = contrib_cs_.find(nid);
83 
84         if (it == contrib_cs_.end())
85             return nullptr;
86         return &(it->second);
87     }
88 
89     /// Get nogoods (identified by the NodeID where they were created)
90     /// that contribute to the failure at `nid`;
getContribNogoods(NodeID nid) const91     const std::vector<NodeID> *getContribNogoods(NodeID nid) const
92     {
93         const auto it = contrib_ngs_.find(nid);
94 
95         if (it == contrib_ngs_.end())
96             return nullptr;
97         return &(it->second);
98     }
99 
100     /// Associate nogood `ng` with node `nid`
setNogood(NodeID nid,const std::string & orig,const std::string & renamed)101     void setNogood(NodeID nid, const std::string &orig, const std::string &renamed)
102     {
103         nogood_map_.insert({nid, Nogood(orig, renamed)});
104     }
105 
setNogood(NodeID nid,const std::string & orig)106     void setNogood(NodeID nid, const std::string &orig)
107     {
108         nogood_map_.insert({nid, Nogood(orig)});
109     }
110 
getNogood(NodeID nid) const111     const Nogood &getNogood(NodeID nid) const
112     {
113         auto it = nogood_map_.find(nid);
114         if (it != nogood_map_.end())
115         {
116             return it->second;
117         }
118         else
119         {
120             return Nogood::empty;
121         }
122     }
123 
setInfo(NodeID nid,const std::string & orig)124     void setInfo(NodeID nid, const std::string &orig)
125     {
126         info_map_.insert({nid, Info(orig)});
127     }
128 
getInfo(NodeID nid) const129     Info getInfo(NodeID nid) const
130     {
131         auto it = info_map_.find(nid);
132         if (it != info_map_.end())
133         {
134             return it->second;
135         }
136         else
137         {
138             return Info("");
139         }
140     }
141 
142     /// Process node info looking for reasons, contributing nogoods for failed nodes etc.
143     void processInfo(NodeID nid, const std::string &info_str);
144 
145     /// Whether the data stores at least one no-good
hasNogoods() const146     bool hasNogoods() const
147     {
148         return !nogood_map_.empty();
149     }
150 
151     /// Whether the data stores at least one no-good
hasInfo() const152     bool hasInfo() const
153     {
154         return !info_map_.empty();
155     }
156 };
157 
158 } // namespace cpprofiler
159