1 #ifndef _QUEUE_CIOGLQICV
2 #define _QUEUE_CIOGLQICV
3 
4 #include "triggering_events.hpp"
5 #include "constraints/abstract_constraint.hpp"
6 #include "tracer.hpp"
7 #include "abstract_queue.hpp"
8 #include "../rbase/rbase.hpp"
9 #include <set>
10 
11 
12 
13 class ConstraintQueue : public AbstractQueue
14 {
15     std::vector<AbstractConstraint*> constraint_fix_list;
16     std::vector<AbstractConstraint*> constraint_change_list;
17 
18     std::vector<AbstractConstraint*> constraint_rbase_finished_list;
19 
20     std::vector<int> to_invoke_fix;
21     std::vector<std::set<int> > to_invoke_change;
22 
23     TracerGenerator* tracer;
24 public:
ConstraintQueue(TracerGenerator * _tracer)25     ConstraintQueue(TracerGenerator* _tracer)
26     : tracer(_tracer)
27     { }
28 
addTrigger(AbstractConstraint * ac,TriggerType tt)29     void addTrigger(AbstractConstraint* ac, TriggerType tt)
30     {
31         switch(tt)
32         {
33             case Trigger_Fix:
34             {
35                 D_ASSERT(std::find(constraint_fix_list.begin(),
36                                    constraint_fix_list.end(), ac)
37                            == constraint_fix_list.end());
38                 constraint_fix_list.push_back(ac);
39                 to_invoke_fix.push_back(-1);
40             }
41             break;
42             case Trigger_Change:
43             {
44                 D_ASSERT(std::find(constraint_change_list.begin(),
45                                    constraint_change_list.end(), ac)
46                             == constraint_change_list.end());
47                 constraint_change_list.push_back(ac);
48                 to_invoke_change.push_back(std::set<int>());
49             }
50             break;
51             case Trigger_RBaseFinished:
52             {
53                 D_ASSERT(std::find(constraint_rbase_finished_list.begin(),
54                                    constraint_rbase_finished_list.end(), ac)
55                             == constraint_rbase_finished_list.end());
56                 constraint_rbase_finished_list.push_back(ac);
57             }
58             break;
59             default:
60               abort();
61         }
62     }
63 
triggerSplit(int oldcell,int newcell,int oldcellsize,int newcellsize)64     SplitState triggerSplit(int oldcell, int newcell, int oldcellsize, int newcellsize)
65     {
66         tracer->addEvent(BranchEvent(oldcell, newcell, oldcellsize, newcellsize));
67         if(oldcellsize == 1)
68             triggerFix(oldcell);
69         else if(newcellsize == 1)
70             triggerFix(newcell);
71 
72         triggerChange(oldcell,newcell);
73 
74         return SplitState(true);
75     }
76 
hasSortData()77     virtual bool hasSortData()
78     { return false; }
79 
getPartitionEvent()80     virtual PartitionEvent& getPartitionEvent()
81     { abort(); }
82 
addPartitionEvent(PartitionEvent se)83     virtual void addPartitionEvent(PartitionEvent se)
84     {
85         tracer->addPartitionEvent(std::move(se));
86     }
87 
88 private:
triggerChange(int oldcell,int newcell)89     void triggerChange(int oldcell, int newcell)
90     {
91         for(auto & i : to_invoke_change)
92         {
93             i.insert(oldcell);
94             i.insert(newcell);
95         }
96     }
97 
triggerFix(int fixedcell)98     void triggerFix(int fixedcell)
99     {
100         for(int & i : to_invoke_fix)
101             if(i == -1)
102                 i = fixedcell;
103     }
104 public:
invokeQueue()105     SplitState invokeQueue()
106     {
107         vec1<int> buffer;
108         bool triggered = true;
109         while(triggered)
110         {
111             triggered = false;
112             for(unsigned i = 0; i < to_invoke_change.size(); ++i)
113             {
114                 if(!to_invoke_change[i].empty())
115                 {
116                     tracer->beginConstraint(constraint_Change(constraint_change_list[i], to_invoke_change[i]));
117                     triggered = true;
118                     buffer.clear();
119                     buffer.assign(to_invoke_change[i].begin(), to_invoke_change[i].end());
120                     to_invoke_change[i].clear();
121                     info_out(2, "Executing: " << constraint_change_list[i]->full_name());
122                     if(constraint_change_list[i]->signal_changed_buildingRBase(buffer).hasFailed())
123                         return SplitState(false);
124                     info_out(2, "After splitting: " <<
125                                 constraint_change_list[i]->getPartitionStack()->dumpCurrentPartition());
126                     tracer->endConstraint();
127                 }
128             }
129 
130             for(unsigned i = 0; i < to_invoke_fix.size(); ++i)
131             {
132                 if(to_invoke_fix[i] != -1)
133                 {
134                     tracer->beginConstraint(constraint_Fix(constraint_fix_list[i]));
135                     triggered = true;
136                     to_invoke_fix[i] = -1;
137                     info_out(2, "Executing: " << constraint_fix_list[i]->full_name());
138                     if(constraint_fix_list[i]->signal_fix_buildingRBase().hasFailed())
139                         return SplitState(false);
140                     info_out(2, "After splitting: " <<
141                                 constraint_fix_list[i]->getPartitionStack()->dumpCurrentPartition());
142                     tracer->endConstraint();
143                 }
144             }
145         }
146         return SplitState(true);
147     }
148 
RBaseFinished(RBase * rb)149     void RBaseFinished(RBase* rb)
150     {
151         for(auto & i : constraint_rbase_finished_list)
152         {
153             i->signal_RBaseFinished(rb);
154         }
155     }
156 };
157 
158 #endif
159