From 7ceb4ed076fd993be85305066b5475ed10a0367f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 17 Dec 2018 20:31:24 +0100 Subject: [PATCH] Fixed an issue with the deep region: the layout pointer is not a good key for the backannotation cache. So we better use the unique ID - a concept introduced herein. --- src/db/db/dbDeepShapeStore.cc | 2 +- src/db/db/dbDeepShapeStore.h | 4 +- src/db/db/dbLayout.h | 4 +- src/tl/tl/tl.pro | 6 ++- src/tl/tl/tlUniqueId.cc | 43 +++++++++++++++ src/tl/tl/tlUniqueId.h | 81 ++++++++++++++++++++++++++++ src/tl/unit_tests/tlUniqueIdTests.cc | 51 ++++++++++++++++++ src/tl/unit_tests/unit_tests.pro | 1 + 8 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 src/tl/tl/tlUniqueId.cc create mode 100644 src/tl/tl/tlUniqueId.h create mode 100644 src/tl/unit_tests/tlUniqueIdTests.cc diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 2ff81f9e0..76ea5dfcb 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -320,7 +320,7 @@ DeepShapeStore::insert (const DeepLayer &deep_layer, db::Layout *into_layout, db // derive a cell mapping for source to target. We employ a - DeliveryMappingCacheKey key (deep_layer.layout_index (), into_layout, into_cell); + DeliveryMappingCacheKey key (deep_layer.layout_index (), tl::id_of (into_layout), into_cell); std::map::iterator cm = m_delivery_mapping_cache.find (key); if (cm == m_delivery_mapping_cache.end ()) { diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 31b18f472..10553c268 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -301,7 +301,7 @@ private: { // NOTE: we shouldn't keep pointers here as the layouts may get deleted and recreated with the same address. // But as we don't access these objects that's fairly safe. - DeliveryMappingCacheKey (unsigned int _from_index, db::Layout *_into_layout, db::cell_index_type _into_cell) + DeliveryMappingCacheKey (unsigned int _from_index, tl::id_type _into_layout, db::cell_index_type _into_cell) : from_index (_from_index), into_layout (_into_layout), into_cell (_into_cell) { // .. nothing yet .. @@ -319,7 +319,7 @@ private: } unsigned int from_index; - db::Layout *into_layout; + tl::id_type into_layout; db::cell_index_type into_cell; }; diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index eb48b7727..76ecb0a7c 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -40,6 +40,7 @@ #include "tlString.h" #include "tlThreads.h" #include "tlObject.h" +#include "tlUniqueId.h" #include "gsi.h" #include @@ -460,7 +461,8 @@ class DB_PUBLIC Layout : public db::Object, public db::LayoutStateModel, public gsi::ObjectBase, - public tl::Object + public tl::Object, + public tl::UniqueId { public: typedef db::Box box_type; diff --git a/src/tl/tl/tl.pro b/src/tl/tl/tl.pro index d5c002aea..3805807d8 100644 --- a/src/tl/tl/tl.pro +++ b/src/tl/tl/tl.pro @@ -41,7 +41,8 @@ SOURCES = \ tlThreads.cc \ tlDeferredExecution.cc \ tlUri.cc \ - tlLongInt.cc + tlLongInt.cc \ + tlUniqueId.cc HEADERS = \ tlAlgorithm.h \ @@ -92,7 +93,8 @@ HEADERS = \ tlThreads.h \ tlDeferredExecution.h \ tlUri.h \ - tlLongInt.h + tlLongInt.h \ + tlUniqueId.h equals(HAVE_CURL, "1") { diff --git a/src/tl/tl/tlUniqueId.cc b/src/tl/tl/tlUniqueId.cc new file mode 100644 index 000000000..888b5b2b6 --- /dev/null +++ b/src/tl/tl/tlUniqueId.cc @@ -0,0 +1,43 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#include "tlUniqueId.h" +#include "tlThreads.h" + +namespace tl +{ + +static tl::Mutex s_lock; +static id_type s_next_id = 0; + +UniqueId::UniqueId () +{ + tl::MutexLocker locker (&s_lock); + do { + m_id = ++s_next_id; + } while (m_id == 0); +} + +} // namespace tl + + diff --git a/src/tl/tl/tlUniqueId.h b/src/tl/tl/tlUniqueId.h new file mode 100644 index 000000000..61a73c003 --- /dev/null +++ b/src/tl/tl/tlUniqueId.h @@ -0,0 +1,81 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_tlUniqueId +#define HDR_tlUniqueId + +#include "tlCommon.h" +#include + +namespace tl +{ + +typedef uint64_t id_type; + +/** + * @brief An object delivering a unique ID per object + * + * This class is supposed to provide a solution for the non-uniqueness + * issue of addresses. Instead of using addresses as keys, use the unique + * ID. The advantage is to be reproducible and guaranteed to be different + * for each allocation of an object (apart from overflow wrapping at 64bit - + * this this is pretty unlikely event). + * + * To supply an ID, derive your class from tl::UniqueId. Use + * "tl::id_of (object *)" the get the ID from that object. + * A null-pointer will give an ID of 0 which is reserved for + * "nothing". + * + * The type of the ID is tl::id_type. + */ +class TL_PUBLIC UniqueId +{ +public: + /** + * @brief @brief Creates a new object with a new ID + */ + UniqueId (); + + UniqueId (const UniqueId &) { } + UniqueId &operator= (const UniqueId &) { return *this; } + +private: + friend id_type id_of (const UniqueId *); + + id_type m_id; +}; + +/** + * @brief Gets the ID of the object pointed to by o + * + * Returns 0 in a null pointer and only then. + */ +inline id_type id_of (const UniqueId *o) +{ + return o ? o->m_id : 0; +} + +} // namespace tl + +#endif + diff --git a/src/tl/unit_tests/tlUniqueIdTests.cc b/src/tl/unit_tests/tlUniqueIdTests.cc new file mode 100644 index 000000000..20d734939 --- /dev/null +++ b/src/tl/unit_tests/tlUniqueIdTests.cc @@ -0,0 +1,51 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "tlUniqueId.h" +#include "tlUnitTest.h" + +#include + +namespace { + class MyClass : public tl::UniqueId { + public: + MyClass () { } + }; +} + +// basic parsing ability +TEST(1) +{ + tl::id_type id, id0; + + id = tl::id_of (0); + EXPECT_EQ (id, tl::id_type (0)); + + std::auto_ptr ptr; + ptr.reset (new MyClass ()); + id0 = id = tl::id_of (ptr.get ()); + EXPECT_NE (id, tl::id_type (0)); + + ptr.reset (new MyClass ()); + id = tl::id_of (ptr.get ()); + EXPECT_EQ (id, id0 + 1); +} diff --git a/src/tl/unit_tests/unit_tests.pro b/src/tl/unit_tests/unit_tests.pro index 89d63ec6c..f10fc4e70 100644 --- a/src/tl/unit_tests/unit_tests.pro +++ b/src/tl/unit_tests/unit_tests.pro @@ -35,6 +35,7 @@ SOURCES = \ tlHttpStream.cc \ tlInt128Support.cc \ tlLongInt.cc \ + tlUniqueIdTests.cc !equals(HAVE_QT, "0") {