fast path for normal demons
This commit is contained in:
@@ -260,6 +260,22 @@ class Queue {
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessNormalDemon(Demon* const demon) {
|
||||
if (++solver_->demon_runs_[Solver::NORMAL_PRIORITY] % 10000 == 0) {
|
||||
solver_->TopPeriodicCheck();
|
||||
}
|
||||
demon->Run(solver_);
|
||||
}
|
||||
|
||||
void ProcessInstrumentedNormalDemon(Demon* const demon) {
|
||||
solver_->GetPropagationMonitor()->BeginDemonRun(demon);
|
||||
if (++solver_->demon_runs_[Solver::NORMAL_PRIORITY] % 10000 == 0) {
|
||||
solver_->TopPeriodicCheck();
|
||||
}
|
||||
demon->Run(solver_);
|
||||
solver_->GetPropagationMonitor()->EndDemonRun(demon);
|
||||
}
|
||||
|
||||
void Process() {
|
||||
if (!in_process_) {
|
||||
in_process_ = true;
|
||||
@@ -275,7 +291,11 @@ class Queue {
|
||||
void Execute(Demon* const demon) {
|
||||
if (demon->stamp() < stamp_) {
|
||||
if (demon->priority() == Solver::NORMAL_PRIORITY) {
|
||||
ProcessOneDemon(demon);
|
||||
if (!instruments_demons_) {
|
||||
ProcessNormalDemon(demon);
|
||||
} else {
|
||||
ProcessInstrumentedNormalDemon(demon);
|
||||
}
|
||||
} else {
|
||||
DCHECK_EQ(demon->priority(), Solver::DELAYED_PRIORITY);
|
||||
demon->set_stamp(stamp_);
|
||||
@@ -284,6 +304,29 @@ class Queue {
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
|
||||
if (!instruments_demons_) {
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&demons); it.ok(); ++it) {
|
||||
Demon* const demon = *it;
|
||||
if (demon->stamp() < stamp_) {
|
||||
DCHECK_EQ(demon->priority(), Solver::NORMAL_PRIORITY);
|
||||
if (++solver_->demon_runs_[Solver::NORMAL_PRIORITY] % 10000 == 0) {
|
||||
solver_->TopPeriodicCheck();
|
||||
}
|
||||
demon->Run(solver_);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&demons); it.ok(); ++it) {
|
||||
Demon* const demon = *it;
|
||||
if (demon->stamp() < stamp_) {
|
||||
DCHECK_EQ(demon->priority(), Solver::NORMAL_PRIORITY);
|
||||
ProcessInstrumentedNormalDemon(demon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnqueueVar(Demon* const demon) {
|
||||
DCHECK(demon->priority() == Solver::VAR_PRIORITY);
|
||||
if (demon->stamp() < stamp_) {
|
||||
@@ -1633,6 +1676,10 @@ void Solver::Execute(Demon* const d) {
|
||||
queue_->Execute(d);
|
||||
}
|
||||
|
||||
void Solver::ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
|
||||
queue_->ExecuteAll(demons);
|
||||
}
|
||||
|
||||
uint64 Solver::stamp() const {
|
||||
return queue_->stamp();
|
||||
}
|
||||
@@ -2558,6 +2605,10 @@ string PropagationBaseObject::BaseName() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
void PropagationBaseObject::ExecuteAll(const SimpleRevFIFO<Demon*>& demons) {
|
||||
solver_->ExecuteAll(demons);
|
||||
}
|
||||
|
||||
// ---------- Decision Builder ----------
|
||||
|
||||
string DecisionBuilder::DebugString() const {
|
||||
|
||||
@@ -2844,6 +2844,7 @@ class Solver {
|
||||
void EnqueueVar(Demon* const d);
|
||||
void EnqueueDelayedDemon(Demon* const d);
|
||||
void Execute(Demon* const d);
|
||||
void ExecuteAll(const SimpleRevFIFO<Demon*>& demons);
|
||||
void UnfreezeQueue();
|
||||
void set_queue_action_on_fail(Action* a);
|
||||
void set_queue_cleaner_on_fail(IntVar* const var);
|
||||
@@ -3031,6 +3032,7 @@ class PropagationBaseObject : public BaseObject {
|
||||
void EnqueueDelayedDemon(Demon* const d) { solver_->EnqueueDelayedDemon(d); }
|
||||
void EnqueueVar(Demon* const d) { solver_->EnqueueVar(d); }
|
||||
void Execute(Demon* const d) { solver_->Execute(d); }
|
||||
void ExecuteAll(const SimpleRevFIFO<Demon*>& demons);
|
||||
|
||||
// This method sets a callback that will be called if a failure
|
||||
// happens during the propagation of the queue.
|
||||
|
||||
@@ -753,17 +753,32 @@ class DomainIntVar : public IntVar {
|
||||
void CreateBits();
|
||||
virtual void WhenBound(Demon* d) {
|
||||
if (min_.Value() != max_.Value()) {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
if (d->priority() == Solver::DELAYED_PRIORITY) {
|
||||
delayed_bound_demons_.PushIfNotTop(solver(),
|
||||
solver()->RegisterDemon(d));
|
||||
} else {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WhenRange(Demon* d) {
|
||||
if (min_.Value() != max_.Value()) {
|
||||
range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
if (d->priority() == Solver::DELAYED_PRIORITY) {
|
||||
delayed_range_demons_.PushIfNotTop(solver(),
|
||||
solver()->RegisterDemon(d));
|
||||
} else {
|
||||
range_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WhenDomain(Demon* d) {
|
||||
if (min_.Value() != max_.Value()) {
|
||||
domain_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
if (d->priority() == Solver::DELAYED_PRIORITY) {
|
||||
delayed_domain_demons_.PushIfNotTop(solver(),
|
||||
solver()->RegisterDemon(d));
|
||||
} else {
|
||||
domain_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -952,6 +967,9 @@ class DomainIntVar : public IntVar {
|
||||
SimpleRevFIFO<Demon*> bound_demons_;
|
||||
SimpleRevFIFO<Demon*> range_demons_;
|
||||
SimpleRevFIFO<Demon*> domain_demons_;
|
||||
SimpleRevFIFO<Demon*> delayed_bound_demons_;
|
||||
SimpleRevFIFO<Demon*> delayed_range_demons_;
|
||||
SimpleRevFIFO<Demon*> delayed_domain_demons_;
|
||||
QueueHandler handler_;
|
||||
bool in_process_;
|
||||
BitSet* bits_;
|
||||
@@ -1801,17 +1819,26 @@ void DomainIntVar::Process() {
|
||||
new_min_ = min_.Value();
|
||||
new_max_ = max_.Value();
|
||||
if (min_.Value() == max_.Value()) {
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&bound_demons_); it.ok(); ++it) {
|
||||
Execute(*it);
|
||||
ExecuteAll(bound_demons_);
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_);
|
||||
it.ok();
|
||||
++it) {
|
||||
EnqueueDelayedDemon(*it);
|
||||
}
|
||||
}
|
||||
if (min_.Value() != OldMin() || max_.Value() != OldMax()) {
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&range_demons_); it.ok(); ++it) {
|
||||
Execute(*it);
|
||||
ExecuteAll(range_demons_);
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_range_demons_);
|
||||
it.ok();
|
||||
++it) {
|
||||
EnqueueDelayedDemon(*it);
|
||||
}
|
||||
}
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&domain_demons_); it.ok(); ++it) {
|
||||
Execute(*it);
|
||||
ExecuteAll(domain_demons_);
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_domain_demons_);
|
||||
it.ok();
|
||||
++it) {
|
||||
EnqueueDelayedDemon(*it);
|
||||
}
|
||||
clear_queue_action_on_fail();
|
||||
ClearInProcess();
|
||||
@@ -1915,18 +1942,19 @@ class BooleanVar : public IntVar {
|
||||
virtual void RemoveInterval(int64 l, int64 u);
|
||||
virtual void WhenBound(Demon* d) {
|
||||
if (value_ == kUnboundBooleanVarValue) {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
if (d->priority() == Solver::DELAYED_PRIORITY) {
|
||||
delayed_bound_demons_.PushIfNotTop(solver(),
|
||||
solver()->RegisterDemon(d));
|
||||
} else {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WhenRange(Demon* d) {
|
||||
if (value_ == kUnboundBooleanVarValue) {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
WhenRange(d);
|
||||
}
|
||||
virtual void WhenDomain(Demon* d) {
|
||||
if (value_ == kUnboundBooleanVarValue) {
|
||||
bound_demons_.PushIfNotTop(solver(), solver()->RegisterDemon(d));
|
||||
}
|
||||
WhenRange(d);
|
||||
}
|
||||
void Process();
|
||||
void Push() {
|
||||
@@ -2006,6 +2034,7 @@ class BooleanVar : public IntVar {
|
||||
private:
|
||||
int value_;
|
||||
SimpleRevFIFO<Demon*> bound_demons_;
|
||||
SimpleRevFIFO<Demon*> delayed_bound_demons_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
@@ -2077,8 +2106,11 @@ void BooleanVar::RemoveInterval(int64 l, int64 u) {
|
||||
|
||||
void BooleanVar::Process() {
|
||||
DCHECK_NE(value_, kUnboundBooleanVarValue);
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&bound_demons_); it.ok(); ++it) {
|
||||
Execute(*it);
|
||||
ExecuteAll(bound_demons_);
|
||||
for (SimpleRevFIFO<Demon*>::Iterator it(&delayed_bound_demons_);
|
||||
it.ok();
|
||||
++it) {
|
||||
EnqueueDelayedDemon(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user