diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 0d7d725de..bed425c3d 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -962,10 +962,31 @@ DeepRegion::xor_with (const Region &other, db::PropertyConstraint property_const // Implement XOR as (A-B)+(B-A) - only this implementation // is compatible with the local processor scheme - DeepLayer n1 (and_or_not_with (other_deep, false, property_constraint)); - DeepLayer n2 (other_deep->and_or_not_with (this, false, property_constraint)); + // Prepare a version of "other_deep" that is mapped into the hierarchy space + // of "this" + std::unique_ptr other_deep_mapped; + if (&other_deep->deep_layer ().layout () == &deep_layer ().layout ()) { + // shallow copy for reconfiguration (progress etc.) + other_deep_mapped.reset (new DeepRegion (other_deep->deep_layer ())); + } else { + // deep copy with mapped hierarchy + other_deep_mapped.reset (new DeepRegion (deep_layer ().derived ())); + other_deep_mapped->deep_layer ().add_from (other_deep->deep_layer ()); + } + + other_deep_mapped->set_strict_handling (strict_handling ()); + other_deep_mapped->set_base_verbosity (base_verbosity ()); + if (report_progress ()) { + other_deep_mapped->enable_progress (progress_desc () + tl::to_string (tr (" - reverse part"))); + } else { + other_deep_mapped->disable_progress (); + } + + DeepLayer n1 (and_or_not_with (other_deep_mapped.get (), false, property_constraint)); + DeepLayer n2 (other_deep_mapped->and_or_not_with (this, false, property_constraint)); n1.add_from (n2); + return new DeepRegion (n1); } diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index cf8bbfcb5..9987451e2 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1239,7 +1239,8 @@ private: void collect_instance_interactions (const db::CellInstArray *inst1, const db::CellInstArray *inst2) { - // TODO: this algorithm is not in particular effective for identical arrays + // TODO: this algorithm is not in particular effective for identical arrays or for arrays + // vs. single instances const db::Cell &cell1 = mp_subject_layout->cell (inst1->object ().cell_index ()); const db::Cell &cell2 = mp_intruder_layout->cell (inst2->object ().cell_index ()); diff --git a/src/db/unit_tests/dbHierProcessorTests.cc b/src/db/unit_tests/dbHierProcessorTests.cc index 7e9fe165f..504f36c2e 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -1278,3 +1278,9 @@ TEST(FlatOperation) run_test_bool22_flat (_this, "hlp17_flat.oas", TMAndNot, 100, 101); } +TEST(Arrays) +{ + // Large arrays, NOT + run_test_bool2 (_this, "hlp18.oas", TMNot, 100); +} + diff --git a/testdata/algo/hlp18.oas b/testdata/algo/hlp18.oas new file mode 100644 index 000000000..2c45f1226 Binary files /dev/null and b/testdata/algo/hlp18.oas differ