Google OR-Tools: ortools/constraint_solver/model_cache.cc Source File
26ABSL_FLAG(bool, cp_disable_cache, false, "Disable caching of model objects");
41bool IsEqual(const T& a1, const T& a2) {
46bool IsEqual(const std::vector<T*>& a1, const std::vector<T*>& a2) {
47 if (a1.size() != a2.size()) {
50 for (int i = 0; i < a1.size(); ++i) {
58template <class A1, class A2>
59uint64_t Hash2(const A1& a1, const A2& a2) {
60 uint64_t a = Hash1(a1);
61 uint64_t b = uint64_t{0xe08c1d668b756f82};
63 mix(a, b, c);
64 return c;
67template <class A1, class A2, class A3>
68uint64_t Hash3(const A1& a1, const A2& a2, const A3& a3) {
69 uint64_t a = Hash1(a1);
72 mix(a, b, c);
73 return c;
76template <class A1, class A2, class A3, class A4>
77uint64_t Hash4(const A1& a1, const A2& a2, const A3& a3, const A4& a4) {
78 uint64_t a = Hash1(a1);
80 uint64_t c = Hash2(a3, a4);
81 mix(a, b, c);
82 return c;
86void Double(C*** array_ptr, int* size_ptr) {
87 DCHECK(array_ptr != nullptr);
88 DCHECK(size_ptr != nullptr);
89 C** const old_cell_array = *array_ptr;
90 const int old_size = *size_ptr;
92 (*array_ptr) = new C*[(*size_ptr)];
93 memset(*array_ptr, 0, (*size_ptr) * sizeof(**array_ptr));
94 for (int i = 0; i < old_size; ++i) {
95 C* tmp = old_cell_array[i];
97 C* const to_reinsert = tmp;
99 const uint64_t position = to_reinsert->Hash() % (*size_ptr);
100 to_reinsert->set_next((*array_ptr)[position]);
101 (*array_ptr)[position] = to_reinsert;
104 delete[] (old_cell_array);
109template <class C, class A1>
113 : array_(new Cell*[absl::GetFlag(FLAGS_cache_initial_size)]),
114 size_(absl::GetFlag(FLAGS_cache_initial_size)),
116 memset(array_, 0, sizeof(*array_) * size_);
120 for (int i = 0; i < size_; ++i) {
121 Cell* tmp = array_[i];
123 Cell* const to_delete = tmp;
132 for (int i = 0; i < size_; ++i) {
133 Cell* tmp = array_[i];
135 Cell* const to_delete = tmp;
139 array_[i] = nullptr;
143 C* Find(const A1& a1) const {
144 uint64_t code = Hash1(a1) % size_;
147 C* const result = tmp->ReturnsIfEqual(a1);
156 void UnsafeInsert(const A1& a1, C* const c) {
157 const int position = Hash1(a1) % size_;
158 Cell* const cell = new Cell(a1, c, array_[position]);
160 if (++num_items_ > 2 * size_) {
168 Cell(const A1& a1, C* const container, Cell* const next)
169 : a1_(a1), container_(container), next_(next) {}
171 C* ReturnsIfEqual(const A1& a1) const {
178 uint64_t Hash() const { return Hash1(a1_); }
180 void set_next(Cell* const next) { next_ = next; }
182 Cell* next() const { return next_; }
197template <class C, class A1, class A2>
201 : array_(new Cell*[absl::GetFlag(FLAGS_cache_initial_size)]),
202 size_(absl::GetFlag(FLAGS_cache_initial_size)),
204 memset(array_, 0, sizeof(*array_) * size_);
208 for (int i = 0; i < size_; ++i) {
209 Cell* tmp = array_[i];
211 Cell* const to_delete = tmp;
220 for (int i = 0; i < size_; ++i) {
221 Cell* tmp = array_[i];
223 Cell* const to_delete = tmp;
227 array_[i] = nullptr;
231 C* Find(const A1& a1, const A2& a2) const {
232 uint64_t code = Hash2(a1, a2) % size_;
235 C* const result = tmp->ReturnsIfEqual(a1, a2);
244 void UnsafeInsert(const A1& a1, const A2& a2, C* const c) {
245 const int position = Hash2(a1, a2) % size_;
246 Cell* const cell = new Cell(a1, a2, c, array_[position]);
248 if (++num_items_ > 2 * size_) {
256 Cell(const A1& a1, const A2& a2, C* const container, Cell* const next)
257 : a1_(a1), a2_(a2), container_(container), next_(next) {}
259 C* ReturnsIfEqual(const A1& a1, const A2& a2) const {
260 if (IsEqual(a1_, a1) && IsEqual(a2_, a2)) {
266 uint64_t Hash() const { return Hash2(a1_, a2_); }
268 void set_next(Cell* const next) { next_ = next; }
270 Cell* next() const { return next_; }
286template <class C, class A1, class A2, class A3>
290 : array_(new Cell*[absl::GetFlag(FLAGS_cache_initial_size)]),
291 size_(absl::GetFlag(FLAGS_cache_initial_size)),
293 memset(array_, 0, sizeof(*array_) * size_);
297 for (int i = 0; i < size_; ++i) {
298 Cell* tmp = array_[i];
300 Cell* const to_delete = tmp;
309 for (int i = 0; i < size_; ++i) {
310 Cell* tmp = array_[i];
312 Cell* const to_delete = tmp;
316 array_[i] = nullptr;
320 C* Find(const A1& a1, const A2& a2, const A3& a3) const {
321 uint64_t code = Hash3(a1, a2, a3) % size_;
324 C* const result = tmp->ReturnsIfEqual(a1, a2, a3);
333 void UnsafeInsert(const A1& a1, const A2& a2, const A3& a3, C* const c) {
334 const int position = Hash3(a1, a2, a3) % size_;
335 Cell* const cell = new Cell(a1, a2, a3, c, array_[position]);
337 if (++num_items_ > 2 * size_) {
345 Cell(const A1& a1, const A2& a2, const A3& a3, C* const container,
347 : a1_(a1), a2_(a2), a3_(a3), container_(container), next_(next) {}
349 C* ReturnsIfEqual(const A1& a1, const A2& a2, const A3& a3) const {
350 if (IsEqual(a1_, a1) && IsEqual(a2_, a2) && IsEqual(a3_, a3)) {
356 uint64_t Hash() const { return Hash3(a1_, a2_, a3_); }
358 void set_next(Cell* const next) { next_ = next; }
360 Cell* next() const { return next_; }
377class NonReversibleCache : public ModelCache {
379 typedef Cache1<IntExpr, IntExpr*> ExprIntExprCache;
380 typedef Cache1<IntExpr, std::vector<IntVar*> > VarArrayIntExprCache;
382 typedef Cache2<Constraint, IntVar*, int64_t> VarConstantConstraintCache;
383 typedef Cache2<Constraint, IntExpr*, IntExpr*> ExprExprConstraintCache;
384 typedef Cache2<IntExpr, IntVar*, int64_t> VarConstantIntExprCache;
385 typedef Cache2<IntExpr, IntExpr*, int64_t> ExprConstantIntExprCache;
386 typedef Cache2<IntExpr, IntExpr*, IntExpr*> ExprExprIntExprCache;
387 typedef Cache2<IntExpr, IntVar*, const std::vector<int64_t>&>
388 VarConstantArrayIntExprCache;
389 typedef Cache2<IntExpr, std::vector<IntVar*>, const std::vector<int64_t>&>
390 VarArrayConstantArrayIntExprCache;
391 typedef Cache2<IntExpr, std::vector<IntVar*>, int64_t>
392 VarArrayConstantIntExprCache;
394 typedef Cache3<IntExpr, IntVar*, int64_t, int64_t>
395 VarConstantConstantIntExprCache;
396 typedef Cache3<Constraint, IntVar*, int64_t, int64_t>
397 VarConstantConstantConstraintCache;
398 typedef Cache3<IntExpr, IntExpr*, IntExpr*, int64_t>
399 ExprExprConstantIntExprCache;
401 explicit NonReversibleCache(Solver* const solver)
402 : ModelCache(solver), void_constraints_(VOID_CONSTRAINT_MAX, nullptr) {
403 for (int i = 0; i < VAR_CONSTANT_CONSTRAINT_MAX; ++i) {
404 var_constant_constraints_.push_back(new VarConstantConstraintCache);
406 for (int i = 0; i < EXPR_EXPR_CONSTRAINT_MAX; ++i) {
407 expr_expr_constraints_.push_back(new ExprExprConstraintCache);
409 for (int i = 0; i < VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX; ++i) {
410 var_constant_constant_constraints_.push_back(
411 new VarConstantConstantConstraintCache);
413 for (int i = 0; i < EXPR_EXPRESSION_MAX; ++i) {
414 expr_expressions_.push_back(new ExprIntExprCache);
416 for (int i = 0; i < EXPR_CONSTANT_EXPRESSION_MAX; ++i) {
417 expr_constant_expressions_.push_back(new ExprConstantIntExprCache);
419 for (int i = 0; i < EXPR_EXPR_EXPRESSION_MAX; ++i) {
420 expr_expr_expressions_.push_back(new ExprExprIntExprCache);
422 for (int i = 0; i < VAR_CONSTANT_CONSTANT_EXPRESSION_MAX; ++i) {
423 var_constant_constant_expressions_.push_back(
424 new VarConstantConstantIntExprCache);
426 for (int i = 0; i < VAR_CONSTANT_ARRAY_EXPRESSION_MAX; ++i) {
427 var_constant_array_expressions_.push_back(
428 new VarConstantArrayIntExprCache);
430 for (int i = 0; i < VAR_ARRAY_EXPRESSION_MAX; ++i) {
431 var_array_expressions_.push_back(new VarArrayIntExprCache);
433 for (int i = 0; i < VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX; ++i) {
434 var_array_constant_array_expressions_.push_back(
435 new VarArrayConstantArrayIntExprCache);
437 for (int i = 0; i < VAR_ARRAY_CONSTANT_EXPRESSION_MAX; ++i) {
438 var_array_constant_expressions_.push_back(
439 new VarArrayConstantIntExprCache);
441 for (int i = 0; i < EXPR_EXPR_CONSTANT_EXPRESSION_MAX; ++i) {
442 expr_expr_constant_expressions_.push_back(
443 new ExprExprConstantIntExprCache);
447 ~NonReversibleCache() override {
463 for (int i = 0; i < VAR_CONSTANT_CONSTRAINT_MAX; ++i) {
464 var_constant_constraints_[i]->Clear();
466 for (int i = 0; i < EXPR_EXPR_CONSTRAINT_MAX; ++i) {
467 expr_expr_constraints_[i]->Clear();
469 for (int i = 0; i < VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX; ++i) {
470 var_constant_constant_constraints_[i]->Clear();
472 for (int i = 0; i < EXPR_EXPRESSION_MAX; ++i) {
473 expr_expressions_[i]->Clear();
475 for (int i = 0; i < EXPR_CONSTANT_EXPRESSION_MAX; ++i) {
476 expr_constant_expressions_[i]->Clear();
478 for (int i = 0; i < EXPR_EXPR_EXPRESSION_MAX; ++i) {
479 expr_expr_expressions_[i]->Clear();
481 for (int i = 0; i < VAR_CONSTANT_CONSTANT_EXPRESSION_MAX; ++i) {
482 var_constant_constant_expressions_[i]->Clear();
484 for (int i = 0; i < VAR_CONSTANT_ARRAY_EXPRESSION_MAX; ++i) {
485 var_constant_array_expressions_[i]->Clear();
487 for (int i = 0; i < VAR_ARRAY_EXPRESSION_MAX; ++i) {
488 var_array_expressions_[i]->Clear();
490 for (int i = 0; i < VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX; ++i) {
491 var_array_constant_array_expressions_[i]->Clear();
493 for (int i = 0; i < VAR_ARRAY_CONSTANT_EXPRESSION_MAX; ++i) {
494 var_array_constant_expressions_[i]->Clear();
496 for (int i = 0; i < EXPR_EXPR_CONSTANT_EXPRESSION_MAX; ++i) {
497 expr_expr_constant_expressions_[i]->Clear();
503 Constraint* FindVoidConstraint(VoidConstraintType type) const override {
505 DCHECK_LT(type, VOID_CONSTRAINT_MAX);
506 return void_constraints_[type];
509 void InsertVoidConstraint(Constraint* const ct,
510 VoidConstraintType type) override {
512 DCHECK_LT(type, VOID_CONSTRAINT_MAX);
515 !absl::GetFlag(FLAGS_cp_disable_cache)) {
516 void_constraints_[type] = ct;
522 Constraint* FindVarConstantConstraint(
523 IntVar* const var, int64_t value,
524 VarConstantConstraintType type) const override {
527 DCHECK_LT(type, VAR_CONSTANT_CONSTRAINT_MAX);
528 return var_constant_constraints_[type]->Find(var, value);
531 void InsertVarConstantConstraint(Constraint* const ct, IntVar* const var,
533 VarConstantConstraintType type) override {
537 DCHECK_LT(type, VAR_CONSTANT_CONSTRAINT_MAX);
539 !absl::GetFlag(FLAGS_cp_disable_cache) &&
540 var_constant_constraints_[type]->Find(var, value) == nullptr) {
541 var_constant_constraints_[type]->UnsafeInsert(var, value, ct);
547 Constraint* FindVarConstantConstantConstraint(
548 IntVar* const var, int64_t value1, int64_t value2,
549 VarConstantConstantConstraintType type) const override {
552 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX);
553 return var_constant_constant_constraints_[type]->Find(var, value1, value2);
556 void InsertVarConstantConstantConstraint(
557 Constraint* const ct, IntVar* const var, int64_t value1, int64_t value2,
558 VarConstantConstantConstraintType type) override {
562 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_CONSTRAINT_MAX);
564 !absl::GetFlag(FLAGS_cp_disable_cache) &&
565 var_constant_constant_constraints_[type]->Find(var, value1, value2) ==
567 var_constant_constant_constraints_[type]->UnsafeInsert(var, value1,
574 Constraint* FindExprExprConstraint(
575 IntExpr* const var1, IntExpr* const var2,
576 ExprExprConstraintType type) const override {
580 DCHECK_LT(type, EXPR_EXPR_CONSTRAINT_MAX);
581 return expr_expr_constraints_[type]->Find(var1, var2);
584 void InsertExprExprConstraint(Constraint* const ct, IntExpr* const var1,
586 ExprExprConstraintType type) override {
591 DCHECK_LT(type, EXPR_EXPR_CONSTRAINT_MAX);
593 !absl::GetFlag(FLAGS_cp_disable_cache) &&
594 expr_expr_constraints_[type]->Find(var1, var2) == nullptr) {
595 expr_expr_constraints_[type]->UnsafeInsert(var1, var2, ct);
601 IntExpr* FindExprExpression(IntExpr* const expr,
602 ExprExpressionType type) const override {
605 DCHECK_LT(type, EXPR_EXPRESSION_MAX);
606 return expr_expressions_[type]->Find(expr);
609 void InsertExprExpression(IntExpr* const expression, IntExpr* const expr,
610 ExprExpressionType type) override {
611 DCHECK(expression != nullptr);
614 DCHECK_LT(type, EXPR_EXPRESSION_MAX);
616 !absl::GetFlag(FLAGS_cp_disable_cache) &&
617 expr_expressions_[type]->Find(expr) == nullptr) {
618 expr_expressions_[type]->UnsafeInsert(expr, expression);
624 IntExpr* FindExprConstantExpression(
625 IntExpr* const expr, int64_t value,
626 ExprConstantExpressionType type) const override {
629 DCHECK_LT(type, EXPR_CONSTANT_EXPRESSION_MAX);
630 return expr_constant_expressions_[type]->Find(expr, value);
633 void InsertExprConstantExpression(IntExpr* const expression,
634 IntExpr* const expr, int64_t value,
635 ExprConstantExpressionType type) override {
636 DCHECK(expression != nullptr);
639 DCHECK_LT(type, EXPR_CONSTANT_EXPRESSION_MAX);
641 !absl::GetFlag(FLAGS_cp_disable_cache) &&
642 expr_constant_expressions_[type]->Find(expr, value) == nullptr) {
643 expr_constant_expressions_[type]->UnsafeInsert(expr, value, expression);
649 IntExpr* FindExprExprExpression(IntExpr* const var1, IntExpr* const var2,
650 ExprExprExpressionType type) const override {
654 DCHECK_LT(type, EXPR_EXPR_EXPRESSION_MAX);
655 return expr_expr_expressions_[type]->Find(var1, var2);
658 void InsertExprExprExpression(IntExpr* const expression, IntExpr* const var1,
660 ExprExprExpressionType type) override {
661 DCHECK(expression != nullptr);
665 DCHECK_LT(type, EXPR_EXPR_EXPRESSION_MAX);
667 !absl::GetFlag(FLAGS_cp_disable_cache) &&
668 expr_expr_expressions_[type]->Find(var1, var2) == nullptr) {
669 expr_expr_expressions_[type]->UnsafeInsert(var1, var2, expression);
675 IntExpr* FindExprExprConstantExpression(
676 IntExpr* const var1, IntExpr* const var2, int64_t constant,
677 ExprExprConstantExpressionType type) const override {
681 DCHECK_LT(type, EXPR_EXPR_CONSTANT_EXPRESSION_MAX);
682 return expr_expr_constant_expressions_[type]->Find(var1, var2, constant);
685 void InsertExprExprConstantExpression(
686 IntExpr* const expression, IntExpr* const var1, IntExpr* const var2,
687 int64_t constant, ExprExprConstantExpressionType type) override {
688 DCHECK(expression != nullptr);
692 DCHECK_LT(type, EXPR_EXPR_CONSTANT_EXPRESSION_MAX);
694 !absl::GetFlag(FLAGS_cp_disable_cache) &&
695 expr_expr_constant_expressions_[type]->Find(var1, var2, constant) ==
697 expr_expr_constant_expressions_[type]->UnsafeInsert(var1, var2, constant,
704 IntExpr* FindVarConstantConstantExpression(
705 IntVar* const var, int64_t value1, int64_t value2,
706 VarConstantConstantExpressionType type) const override {
709 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_EXPRESSION_MAX);
710 return var_constant_constant_expressions_[type]->Find(var, value1, value2);
713 void InsertVarConstantConstantExpression(
714 IntExpr* const expression, IntVar* const var, int64_t value1,
715 int64_t value2, VarConstantConstantExpressionType type) override {
716 DCHECK(expression != nullptr);
719 DCHECK_LT(type, VAR_CONSTANT_CONSTANT_EXPRESSION_MAX);
721 !absl::GetFlag(FLAGS_cp_disable_cache) &&
722 var_constant_constant_expressions_[type]->Find(var, value1, value2) ==
724 var_constant_constant_expressions_[type]->UnsafeInsert(
725 var, value1, value2, expression);
731 IntExpr* FindVarConstantArrayExpression(
732 IntVar* const var, const std::vector<int64_t>& values,
733 VarConstantArrayExpressionType type) const override {
736 DCHECK_LT(type, VAR_CONSTANT_ARRAY_EXPRESSION_MAX);
737 return var_constant_array_expressions_[type]->Find(var, values);
740 void InsertVarConstantArrayExpression(
741 IntExpr* const expression, IntVar* const var,
742 const std::vector<int64_t>& values,
743 VarConstantArrayExpressionType type) override {
744 DCHECK(expression != nullptr);
747 DCHECK_LT(type, VAR_CONSTANT_ARRAY_EXPRESSION_MAX);
749 !absl::GetFlag(FLAGS_cp_disable_cache) &&
750 var_constant_array_expressions_[type]->Find(var, values) == nullptr) {
751 var_constant_array_expressions_[type]->UnsafeInsert(var, values,
758 IntExpr* FindVarArrayExpression(const std::vector<IntVar*>& vars,
759 VarArrayExpressionType type) const override {
761 DCHECK_LT(type, VAR_ARRAY_EXPRESSION_MAX);
762 return var_array_expressions_[type]->Find(vars);
765 void InsertVarArrayExpression(IntExpr* const expression,
766 const std::vector<IntVar*>& vars,
767 VarArrayExpressionType type) override {
768 DCHECK(expression != nullptr);
770 DCHECK_LT(type, VAR_ARRAY_EXPRESSION_MAX);
772 !absl::GetFlag(FLAGS_cp_disable_cache) &&
773 var_array_expressions_[type]->Find(vars) == nullptr) {
774 var_array_expressions_[type]->UnsafeInsert(vars, expression);
780 IntExpr* FindVarArrayConstantArrayExpression(
781 const std::vector<IntVar*>& vars, const std::vector<int64_t>& values,
782 VarArrayConstantArrayExpressionType type) const override {
784 DCHECK_LT(type, VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX);
785 return var_array_constant_array_expressions_[type]->Find(vars, values);
788 void InsertVarArrayConstantArrayExpression(
789 IntExpr* const expression, const std::vector<IntVar*>& vars,
790 const std::vector<int64_t>& values,
791 VarArrayConstantArrayExpressionType type) override {
792 DCHECK(expression != nullptr);
794 DCHECK_LT(type, VAR_ARRAY_CONSTANT_ARRAY_EXPRESSION_MAX);
796 var_array_constant_array_expressions_[type]->Find(vars, values) ==
798 var_array_constant_array_expressions_[type]->UnsafeInsert(vars, values,
805 IntExpr* FindVarArrayConstantExpression(
806 const std::vector<IntVar*>& vars, int64_t value,
807 VarArrayConstantExpressionType type) const override {
809 DCHECK_LT(type, VAR_ARRAY_CONSTANT_EXPRESSION_MAX);
810 return var_array_constant_expressions_[type]->Find(vars, value);
813 void InsertVarArrayConstantExpression(
814 IntExpr* const expression, const std::vector<IntVar*>& vars,
815 int64_t value, VarArrayConstantExpressionType type) override {
816 DCHECK(expression != nullptr);
818 DCHECK_LT(type, VAR_ARRAY_CONSTANT_EXPRESSION_MAX);
820 var_array_constant_expressions_[type]->Find(vars, value) == nullptr) {
821 var_array_constant_expressions_[type]->UnsafeInsert(vars, value,
827 std::vector<Constraint*> void_constraints_;
828 std::vector<VarConstantConstraintCache*> var_constant_constraints_;
829 std::vector<ExprExprConstraintCache*> expr_expr_constraints_;
830 std::vector<VarConstantConstantConstraintCache*>
831 var_constant_constant_constraints_;
832 std::vector<ExprIntExprCache*> expr_expressions_;
833 std::vector<ExprConstantIntExprCache*> expr_constant_expressions_;
834 std::vector<ExprExprIntExprCache*> expr_expr_expressions_;
835 std::vector<VarConstantConstantIntExprCache*>
836 var_constant_constant_expressions_;
837 std::vector<VarConstantArrayIntExprCache*> var_constant_array_expressions_;
838 std::vector<VarArrayIntExprCache*> var_array_expressions_;
839 std::vector<VarArrayConstantArrayIntExprCache*>
840 var_array_constant_array_expressions_;
841 std::vector<VarArrayConstantIntExprCache*> var_array_constant_expressions_;
842 std::vector<ExprExprConstantIntExprCache*> expr_expr_constant_expressions_;
virtual ~ModelCache()
Definition model_cache.cc:33
ModelCache(Solver *solver)
Definition model_cache.cc:31
Solver * solver() const
Definition model_cache.cc:35
@ IN_SEARCH
Executing the search code.
@ OUTSIDE_SEARCH
Before search, after search.
ABSL_DECLARE_FLAG(int, cache_initial_size)
ABSL_FLAG(bool, cp_disable_cache, false, "Disable caching of model objects")
void STLDeleteElements(T *container)
ModelCache * BuildModelCache(Solver *solver)
Definition model_cache.cc:846
static void mix(uint64_t &a, uint64_t &b, uint64_t &c)
uint64_t Hash1(uint64_t value)
Hash functions.
uint64_t Hash(uint64_t num, uint64_t c)