diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index f2d4dd92e..41f876b79 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1406,8 +1406,8 @@ private: struct InteractionKeyForClustersType : public InstanceToInstanceInteraction { - InteractionKeyForClustersType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21, const box_type &_box) - : InstanceToInstanceInteraction (_ci1, 0, _ci2, 0, _t21), box (_box) + InteractionKeyForClustersType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t1, const db::ICplxTrans &_t21, const box_type &_box) + : InstanceToInstanceInteraction (_ci1, 0, _ci2, 0, _t1, _t21), box (_box) { } bool operator== (const InteractionKeyForClustersType &other) const @@ -1482,18 +1482,22 @@ private: InstanceToInstanceInteraction ii_key; db::ICplxTrans i1t, i2t; + bool fill_cache = false; + + // Cache is only used for single instances, non-iterated, simple or regular arrays. + if ((! i1element.at_end () || i1.size () == 1 || ! i1.is_iterated_array ()) && + (! i2element.at_end () || i2.size () == 1 || ! i2.is_iterated_array ())) { - { i1t = i1element.at_end () ? i1.complex_trans () : i1.complex_trans (*i1element); db::ICplxTrans tt1 = t1 * i1t; i2t = i2element.at_end () ? i2.complex_trans () : i2.complex_trans (*i2element); db::ICplxTrans tt2 = t2 * i2t; - db::ICplxTrans tt21 = tt1.inverted () * tt2; + db::ICplxTrans cache_norm = tt1.inverted (); ii_key = InstanceToInstanceInteraction (i1.cell_index (), (! i1element.at_end () || i1.size () == 1) ? 0 : i1.cell_inst ().delegate (), i2.cell_index (), (! i2element.at_end () || i2.size () == 1) ? 0 : i2.cell_inst ().delegate (), - tt21); + cache_norm, cache_norm * tt2); instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key); if (ii != mp_instance_interaction_cache->end ()) { @@ -1511,6 +1515,9 @@ private: return; } + + fill_cache = true; + } // array interactions @@ -1611,15 +1618,19 @@ private: // return the list of unique interactions interacting_clusters.insert (interacting_clusters.end (), sorted_interactions.begin (), sorted_interactions.end ()); - // normalize transformations in cache - db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted (); - for (std::vector >::iterator i = sorted_interactions.begin (); i != sorted_interactions.end (); ++i) { - i->first.transform (i1ti); - i->second.transform (i2ti); - } + if (fill_cache) { - cluster_instance_pair_list_type &cached = (*mp_instance_interaction_cache) [ii_key]; - cached.insert (cached.end (), sorted_interactions.begin (), sorted_interactions.end ()); + // normalize transformations for cache + db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted (); + for (std::vector >::iterator i = sorted_interactions.begin (); i != sorted_interactions.end (); ++i) { + i->first.transform (i1ti); + i->second.transform (i2ti); + } + + cluster_instance_pair_list_type &cached = (*mp_instance_interaction_cache) [ii_key]; + cached.insert (cached.end (), sorted_interactions.begin (), sorted_interactions.end ()); + + } } /** @@ -1641,7 +1652,7 @@ private: box_type common2 = common.transformed (t2i); - InteractionKeyForClustersType ikey (ci1, ci2, t21, common2); + InteractionKeyForClustersType ikey (ci1, ci2, t1i, t21, common2); typename std::map > >::const_iterator ici = m_interaction_cache_for_clusters.find (ikey); if (ici != m_interaction_cache_for_clusters.end ()) { diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 625a972b8..be84db6da 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -762,13 +762,71 @@ inline bool less_array_delegates (const db::ArrayBase *a, const db::ArrayBase *b */ struct InstanceToInstanceInteraction { - InstanceToInstanceInteraction (db::cell_index_type _ci1, const db::ArrayBase *_array1, db::cell_index_type _ci2, const db::ArrayBase *_array2, const db::ICplxTrans &_t21) - : ci1 (_ci1), ci2 (_ci2), array1 (_array1), array2 (_array2), t21 (_t21) - { } + InstanceToInstanceInteraction (db::cell_index_type _ci1, const db::ArrayBase *_array1, db::cell_index_type _ci2, const db::ArrayBase *_array2, const db::ICplxTrans &_tn, const db::ICplxTrans &_t21) + : ci1 (_ci1), ci2 (_ci2), array1 (0), array2 (0), t21 (_t21) + { + if (_array1) { + array1 = _array1->basic_clone (); + static_cast *> (array1)->transform (_tn); + } + + if (_array2) { + array2 = _array2->basic_clone (); + static_cast *> (array2)->transform (_tn); + } + } InstanceToInstanceInteraction () : ci1 (0), ci2 (0), array1 (0), array2 (0) - { } + { + // .. nothing yet .. + } + + InstanceToInstanceInteraction (const InstanceToInstanceInteraction &other) + : ci1 (other.ci1), ci2 (other.ci2), + array1 (other.array1 ? other.array1->basic_clone () : 0), + array2 (other.array2 ? other.array2->basic_clone () : 0), + t21 (other.t21) + { + // .. nothing yet .. + } + + InstanceToInstanceInteraction &operator= (const InstanceToInstanceInteraction &other) + { + if (this != &other) { + + ci1 = other.ci1; + ci2 = other.ci2; + + if (array1) { + delete array1; + } + array1 = other.array1 ? other.array1->basic_clone () : 0; + + if (array2) { + delete array2; + } + array2 = other.array2 ? other.array2->basic_clone () : 0; + + t21 = other.t21; + + } + + return *this; + } + + ~InstanceToInstanceInteraction () + { + if (array1) { + delete array1; + } + array1 = 0; + + if (array2) { + delete array2; + } + array2 = 0; + } bool operator== (const InstanceToInstanceInteraction &other) const { @@ -797,7 +855,7 @@ struct InstanceToInstanceInteraction } db::cell_index_type ci1, ci2; - const db::ArrayBase *array1, *array2; + db::ArrayBase *array1, *array2; db::ICplxTrans t21; };