From 1106a52688b22b1207379503cf96818423a31d97 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 14 Dec 2020 23:55:04 +0100 Subject: [PATCH] WIP: first draft of implementation --- src/db/db/dbStreamLayers.cc | 268 +++++++++++++++++++++++++++--------- src/db/db/dbStreamLayers.h | 69 ++++++++-- 2 files changed, 262 insertions(+), 75 deletions(-) diff --git a/src/db/db/dbStreamLayers.cc b/src/db/db/dbStreamLayers.cc index fb33f3ac7..f73d3dc11 100644 --- a/src/db/db/dbStreamLayers.cc +++ b/src/db/db/dbStreamLayers.cc @@ -40,10 +40,9 @@ namespace db /// A helper class to join two datatype map members struct LmapJoinOp1 { - void operator() (unsigned int &a, unsigned int b) + void operator() (std::set &a, const std::set &b) { - // TODO: could also do?: throw an exception .. - a = b; + a.insert (b.begin (), b.end ()); } }; @@ -58,7 +57,27 @@ struct LmapJoinOp2 } }; -/// Utility typedefs for the expression parser +/// A helper class to implement the unmap operation +struct LmapEraseDatatypeInterval +{ + LmapEraseDatatypeInterval (unsigned int dfrom, unsigned int dto) + : m_dfrom (dfrom), m_dto (dto) + { } + + void operator() (LayerMap::datatype_map &a, const LayerMap::datatype_map &) + { + if (is_static_ld (m_dfrom) && is_static_ld (m_dto)) { + a.erase (m_dfrom, m_dto); + } else { + a.clear (); + } + } + +private: + unsigned int m_dfrom, m_dto; +}; + +/// Utility typedefs for the expression parser typedef std::pair ld_interval; /// Utility typedefs for the expression parser @@ -71,70 +90,70 @@ LayerMap::LayerMap () // .. nothing yet .. } -std::pair +std::set LayerMap::logical (const LDPair &p) const { return logical_internal (p, false); } -std::pair +std::set LayerMap::logical (const std::string &n) const { return logical_internal (n, false); } -std::pair +std::set LayerMap::logical (const db::LayerProperties &p) const { return logical_internal (p, false); } -std::pair +std::set LayerMap::logical_internal (const LDPair &p, bool allow_placeholder) const { const datatype_map *dm = m_ld_map.mapped (p.layer); if (dm) { - const unsigned int *l = dm->mapped (p.datatype); + const std::set *l = dm->mapped (p.datatype); if (l && (allow_placeholder || ! is_placeholder (*l))) { - return std::make_pair (true, *l); + return *l; } } - return std::make_pair (false, 0); + return std::set (); } -std::pair +std::set LayerMap::logical_internal (const std::string &n, bool allow_placeholder) const { - std::map::const_iterator m = m_name_map.find (n); + std::map >::const_iterator m = m_name_map.find (n); if (m != m_name_map.end () && (allow_placeholder || ! is_placeholder (m->second))) { - return std::make_pair (true, m->second); + return m->second; } else { - return std::make_pair (false, 0); + return std::set (); } } -std::pair +std::set LayerMap::logical_internal (const db::LayerProperties &p, bool allow_placeholder) const { + std::set m; if (p.layer >= 0 && p.datatype >= 0) { - std::pair m = logical_internal (db::LDPair (p.layer, p.datatype), allow_placeholder); - if (m.first) { - return m; - } + m = logical_internal (db::LDPair (p.layer, p.datatype), allow_placeholder); } - if (! p.name.empty ()) { - std::pair m = logical_internal (p.name, allow_placeholder); - if (m.first) { - return m; - } + if (m.empty () && ! p.name.empty ()) { + m = logical_internal (p.name, allow_placeholder); } - return std::make_pair (false, 0); + return m; } bool -LayerMap::is_placeholder (unsigned int l) const +LayerMap::is_placeholder (const std::set &m) const { - return (m_placeholders.size () > std::numeric_limits::max () - l); + for (std::set::const_iterator i = m.begin (); i != m.end (); ++i) { + if (m_placeholders.size () > std::numeric_limits::max () - *i) { + return true; + } + } + return false; } const db::LayerProperties * @@ -148,39 +167,52 @@ LayerMap::target (unsigned int l) const } } -std::pair +std::set LayerMap::logical (const db::LayerProperties &p, db::Layout &layout) const { - std::pair l = logical_internal (p, true); - if (l.first && is_placeholder (l.second)) { - return const_cast (this)->substitute_placeholder (p, l.second, layout); + std::set l = logical_internal (p, true); + if (is_placeholder (l)) { + return const_cast (this)->substitute_placeholder (p, l, layout); } else { return l; } } -std::pair +std::set LayerMap::logical (const db::LDPair &p, db::Layout &layout) const { - std::pair l = logical_internal (p, true); - if (l.first && is_placeholder (l.second)) { - return const_cast (this)->substitute_placeholder (db::LayerProperties (p.layer, p.datatype), l.second, layout); + std::set l = logical_internal (p, true); + if (is_placeholder (l)) { + return const_cast (this)->substitute_placeholder (db::LayerProperties (p.layer, p.datatype), l, layout); } else { return l; } } -std::pair -LayerMap::substitute_placeholder (const db::LayerProperties &p, unsigned int ph, db::Layout &layout) +std::set +LayerMap::substitute_placeholder (const db::LayerProperties &p, const std::set &m, db::Layout &layout) { - const db::LayerProperties &lp_ph = m_placeholders [std::numeric_limits::max () - ph]; - db::LayerProperties lp_new = p; - lp_new.layer = db::ld_combine (p.layer, lp_ph.layer); - lp_new.datatype = db::ld_combine (p.datatype, lp_ph.datatype); + std::set res; + for (std::set::const_iterator i = m.begin (); i != m.end (); ++i) { - unsigned int l_new = layout.insert_layer (lp_new); - map (p, l_new, lp_new); - return std::make_pair (true, l_new); + if (m_placeholders.size () > std::numeric_limits::max () - *i) { + + const db::LayerProperties &lp_ph = m_placeholders [std::numeric_limits::max () - *i]; + db::LayerProperties lp_new = p; + lp_new.layer = db::ld_combine (p.layer, lp_ph.layer); + lp_new.datatype = db::ld_combine (p.datatype, lp_ph.datatype); + + unsigned int l_new = layout.insert_layer (lp_new); + map (p, l_new, lp_new); + res.insert (l_new); + + } else { + res.insert (*i); + } + + } + + return res; } static std::string format_interval (ld_type l1, ld_type l2) @@ -206,7 +238,7 @@ LayerMap::mapping_str (unsigned int ll) const bool f2 = true; for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) { - if (d->second == ll) { + if (d->second.find (ll) != d->second.end ()) { // create a string representation if (!f2) { @@ -232,8 +264,9 @@ LayerMap::mapping_str (unsigned int ll) const } - for (std::map ::const_iterator l = m_name_map.begin (); l != m_name_map.end (); ++l) { - if (l->second == ll) { + for (std::map >::const_iterator l = m_name_map.begin (); l != m_name_map.end (); ++l) { + + if (l->second.find (ll) != l->second.end ()) { if (!f1) { s += ";"; @@ -243,6 +276,7 @@ LayerMap::mapping_str (unsigned int ll) const s += tl::to_word_or_quoted_string (l->first); } + } std::map::const_iterator t = m_target_layers.find (ll); @@ -300,11 +334,19 @@ LayerMap::prepare (db::Layout &layout) // Now remap the indexes for (ld_map::iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) { for (datatype_map::iterator d = l->second.begin (); d != l->second.end (); ++d) { - d->second = real_layers [d->second]; + std::set dn; + for (std::set::const_iterator i = d->second.begin (); i != d->second.end (); ++i) { + dn.insert (real_layers [*i]); + } + d->second = dn; } } - for (std::map::iterator n = m_name_map.begin (); n != m_name_map.end (); ++n) { - n->second = real_layers [n->second]; + for (std::map >::iterator n = m_name_map.begin (); n != m_name_map.end (); ++n) { + std::set dn; + for (std::set::const_iterator i = n->second.begin (); i != n->second.end (); ++i) { + dn.insert (real_layers [*i]); + } + n->second = dn; } std::map old_target_layers; @@ -329,11 +371,11 @@ LayerMap::get_layers () const for (ld_map::const_iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) { for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) { - layers.insert (d->second); + layers.insert (d->second.begin (), d->second.end ()); } } for (const_iterator_names n = m_name_map.begin (); n != m_name_map.end (); ++n) { - layers.insert(n->second); + layers.insert(n->second.begin (), n->second.end ()); } return std::vector (layers.begin (), layers.end ()); @@ -358,7 +400,7 @@ LayerMap::mapping (unsigned int ll) const // no mapping is given. Use the lowest layer and datatype for (ld_map::const_iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) { for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) { - if (d->second == ll) { + if (d->second.find (ll) != d->second.end ()) { p.layer = l->first.first; p.datatype = d->first.first; break; @@ -373,7 +415,7 @@ LayerMap::mapping (unsigned int ll) const // no mapping is given. Use the lowest layer and datatype for (ld_map::const_iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) { for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) { - if (d->second == ll) { + if (d->second.find (ll) != d->second.end ()) { p.layer = l->first.first; p.datatype = d->first.first; break; @@ -384,8 +426,8 @@ LayerMap::mapping (unsigned int ll) const } if (p.name.empty ()) { - for (std::map ::const_iterator l = m_name_map.begin (); l != m_name_map.end (); ++l) { - if (l->second == ll) { + for (std::map >::const_iterator l = m_name_map.begin (); l != m_name_map.end (); ++l) { + if (l->second.find (ll) != l->second.end ()) { p.name = l->first; break; } @@ -515,7 +557,7 @@ LayerMap::map_expr (tl::Extractor &ex, unsigned int l) ld_type n; if (! ex.try_read (n) && ex.try_read_word_or_quoted (name)) { - m_name_map.insert (std::make_pair (name, l)); + m_name_map [name].insert (l); } else { @@ -533,7 +575,9 @@ LayerMap::map_expr (tl::Extractor &ex, unsigned int l) datatype_map dm; for (ld_interval_vector::const_iterator di = vd.begin (); di != vd.end (); ++di) { LmapJoinOp1 op1; - dm.add (di->first, di->second + 1, l, op1); + std::set single; + single.insert (l); + dm.add (di->first, di->second + 1, single, op1); } for (ld_interval_vector::const_iterator li = vl.begin (); li != vl.end (); ++li) { LmapJoinOp2 op2; @@ -566,7 +610,7 @@ LayerMap::insert (const std::string &name, unsigned int l, const LayerProperties m_target_layers[l] = *target; } - m_name_map.insert (std::make_pair (name, l)); + m_name_map [name].insert (l); if (l >= m_next_index) { m_next_index = l + 1; @@ -580,13 +624,16 @@ LayerMap::insert (const LDPair &p1, const LDPair &p2, unsigned int l, const Laye m_target_layers[l] = *target; } + std::set single; + single.insert (l); + // create a single-interval list for the datatype range LayerMap::datatype_map dt; LmapJoinOp1 op1; if (db::is_static_ld (p1.datatype) && db::is_static_ld (p2.datatype)) { - dt.add (p1.datatype, p2.datatype + 1, l, op1); + dt.add (p1.datatype, p2.datatype + 1, single, op1); } else { - dt.add (0, std::numeric_limits::max (), l, op1); + dt.add (0, std::numeric_limits::max (), single, op1); } // add this to the layers using the special join operator that @@ -603,6 +650,103 @@ LayerMap::insert (const LDPair &p1, const LDPair &p2, unsigned int l, const Laye } } +void +LayerMap::unmap (const LDPair &f) +{ + unmap (f, f); +} + +void +LayerMap::unmap (const std::string &name) +{ + m_name_map.erase (name); +} + +void +LayerMap::unmap (const LayerProperties &f) +{ + if (f.name.empty () || is_static_ld (f.layer) || is_static_ld (f.datatype)) { + unmap (db::LDPair (f.layer, f.datatype)); + } + if (! f.name.empty ()) { + unmap (f.name); + } +} + + + +void +LayerMap::unmap (const LDPair &p1, const LDPair &p2) +{ + if (m_ld_map.begin () == m_ld_map.end ()) { + return; + } + + LmapEraseDatatypeInterval op (p1.datatype, p2.datatype); + if (db::is_static_ld (p1.layer) && db::is_static_ld (p2.layer)) { + m_ld_map.add (p1.layer, p1.layer + 1, LayerMap::datatype_map (), op); + } else { + m_ld_map.add (m_ld_map.begin ()->first.first, m_ld_map.end ()->first.second, LayerMap::datatype_map (), op); + } +} + +void +LayerMap::unmap_expr (const std::string &expr) +{ + tl::Extractor ex (expr.c_str ()); + unmap_expr (ex); + ex.expect_end (); +} + +void +LayerMap::unmap_expr (tl::Extractor &ex) +{ + try { + + do { + + tl::Extractor ex_saved = ex; + + std::string name; + ld_type n; + if (! ex.try_read (n) && ex.try_read_word_or_quoted (name)) { + + m_name_map.erase (name); + + } else { + + ex = ex_saved; + ld_interval_vector vl, vd; + + parse_intervals (ex, vl); + + if (ex.test ("/")) { + parse_intervals (ex, vd); + } else { + vd.push_back (ld_interval (0, 0)); + } + + for (ld_interval_vector::const_iterator li = vl.begin (); li != vl.end (); ++li) { + for (ld_interval_vector::const_iterator di = vd.begin (); di != vd.end (); ++di) { + unmap (LDPair (li->first, di->first), LDPair (li->second, di->second)); + } + } + + } + + } while (ex.test (";") || ex.test (",")); + + if (ex.test (":")) { + // ignore target layers + LayerProperties lp; + lp.read (ex, true); + } + + } catch (...) { + throw LayerSpecFormatException (ex.skip ()); + } +} + void LayerMap::clear () { diff --git a/src/db/db/dbStreamLayers.h b/src/db/db/dbStreamLayers.h index b142d7d95..8ea0d78b5 100644 --- a/src/db/db/dbStreamLayers.h +++ b/src/db/db/dbStreamLayers.h @@ -35,6 +35,7 @@ #include #include +#include namespace db { @@ -161,6 +162,15 @@ struct DB_PUBLIC LDPair * and effectively rename a layer or add layer name information to * a GDS layer/datatype layer. * + * "Unmapping" can be used to create "holes" in ranges of layers. + * For example, by first mapping layers 1 to 100, datatype 0 and then + * unmapping layer 50, datatype 0, the layers 1 to 49 and 51 to 100, datatype 0 + * are mapped. + * + * The layer map supports multi-mapping. That is, one input layer is + * mapped to multiple target layers. It also supports merging but + * mapping different input layers to a single target layer. + * * A layer map object can be used as a standalone object or in * conjunction with a layout object. As a standalone object, the * logical layers (indexes) are simply consecutive numbers. @@ -178,11 +188,11 @@ class DB_PUBLIC LayerMap : public gsi::ObjectBase { public: - typedef tl::interval_map datatype_map; + typedef tl::interval_map > datatype_map; typedef tl::interval_map ld_map; typedef ld_map::const_iterator const_iterator_layers; typedef datatype_map::const_iterator const_iterator_datatypes; - typedef std::map::const_iterator const_iterator_names; + typedef std::map >::const_iterator const_iterator_names; /** * @brief The constructor for an empty map @@ -195,7 +205,7 @@ public: * @return A pair telling if the layer is mapped (first=true) and * the logical layer mapped (second) if this is the case. */ - std::pair logical (const LDPair &p) const; + std::set logical (const LDPair &p) const; /** * @brief Query a layer mapping from a name @@ -203,7 +213,7 @@ public: * @return A pair telling if the layer is mapped (first=true) and * the logical layer mapped (second) if this is the case. */ - std::pair logical (const std::string &name) const; + std::set logical (const std::string &name) const; /** * @brief Query a layer mapping from a name or LDPair @@ -213,7 +223,7 @@ public: * * @param p The layer that is looked for */ - std::pair logical (const db::LayerProperties &p) const; + std::set logical (const db::LayerProperties &p) const; /** * @brief Query or install a layer mapping from a name or LDPair @@ -227,14 +237,14 @@ public: * the logical layers are placeholder values which will be replaced by * true layers during this method if a new layer is requested. */ - std::pair logical (const db::LayerProperties &p, db::Layout &layout) const; + std::set logical (const db::LayerProperties &p, db::Layout &layout) const; /** * @brief Query or install a layer mapping from a LDPair * * See the version for LayerProperties about details. */ - std::pair logical (const db::LDPair &p, db::Layout &layout) const; + std::set logical (const db::LDPair &p, db::Layout &layout) const; /** * @brief Gets the target layer for a given logical layer @@ -371,6 +381,39 @@ public: */ void map_expr (tl::Extractor &ex, unsigned int l); + /** + * @brief Unmaps a LDPair + */ + void unmap (const LDPair &f); + + /** + * @brief Unmaps the layer with the given name + */ + void unmap (const std::string &name); + + /** + * @brief Unmaps a layer with the given layer properties + */ + void unmap (const LayerProperties &f); + + /** + * @brief Removes any mapping for a range of ldpair's + * + * The range is given by two pairs p1,p2. The layers + * between [p1.l,p2.l] and with datatypes between [p1.d,p2.d] are unmapped. + */ + void unmap (const LDPair &p1, const LDPair &p2); + + /** + * @brief Removes any mapping for the layers given by the expression + */ + void unmap_expr (const std::string &expr); + + /** + * @brief Removes any mapping for the layers given by the expression + */ + void unmap_expr (tl::Extractor &ex); + /** * @brief Prepares a layer mapping object for reading * @@ -454,7 +497,7 @@ public: private: ld_map m_ld_map; - std::map m_name_map; + std::map > m_name_map; std::map m_target_layers; std::vector m_placeholders; unsigned int m_next_index; @@ -462,12 +505,12 @@ private: void insert (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties *t); void insert (const std::string &name, unsigned int l, const LayerProperties *t); - std::pair logical_internal (const LDPair &p, bool allow_placeholder) const; - std::pair logical_internal (const std::string &name, bool allow_placeholder) const; - std::pair logical_internal (const db::LayerProperties &p, bool allow_placeholder) const; + std::set logical_internal (const LDPair &p, bool allow_placeholder) const; + std::set logical_internal (const std::string &name, bool allow_placeholder) const; + std::set logical_internal (const db::LayerProperties &p, bool allow_placeholder) const; - std::pair substitute_placeholder (const db::LayerProperties &p, unsigned int ph, db::Layout &layout); - bool is_placeholder (unsigned int l) const; + std::set substitute_placeholder (const db::LayerProperties &p, const std::set &ph, db::Layout &layout); + bool is_placeholder (const std::set &l) const; }; }