mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-22 05:57:41 +02:00
WIP: attempt to improve performance by using name match shortcuts
This commit is contained in:
+60
-10
@@ -167,6 +167,16 @@ public:
|
|||||||
return m_pattern.match (s, mp_eval->match_substrings ());
|
return m_pattern.match (s, mp_eval->match_substrings ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_catchall () const
|
||||||
|
{
|
||||||
|
return ! m_needs_eval && m_pattern.is_catchall ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_const () const
|
||||||
|
{
|
||||||
|
return ! m_needs_eval && m_pattern.is_const ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tl::GlobPattern m_pattern;
|
tl::GlobPattern m_pattern;
|
||||||
tl::Expression m_expression;
|
tl::Expression m_expression;
|
||||||
@@ -484,11 +494,30 @@ public:
|
|||||||
ChildCellFilterState (const FilterBase *filter, const NameFilterArgument &pattern, ChildCellFilterInstanceMode instance_mode, tl::Eval &eval, db::Layout *layout, bool reading, const ChildCellFilterPropertyIDs &pids)
|
ChildCellFilterState (const FilterBase *filter, const NameFilterArgument &pattern, ChildCellFilterInstanceMode instance_mode, tl::Eval &eval, db::Layout *layout, bool reading, const ChildCellFilterPropertyIDs &pids)
|
||||||
: FilterStateBase (filter, layout, eval),
|
: FilterStateBase (filter, layout, eval),
|
||||||
m_pattern (pattern, eval), m_instance_mode (instance_mode), mp_parent (0), m_pids (pids),
|
m_pattern (pattern, eval), m_instance_mode (instance_mode), mp_parent (0), m_pids (pids),
|
||||||
m_weight (0), m_references (0), m_weight_set (false), m_references_set (false), m_reading (reading)
|
m_weight (0), m_references (0), m_weight_set (false), m_references_set (false), m_reading (reading),
|
||||||
|
m_cell_index (std::numeric_limits<db::cell_index_type>::max ())
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cell_matches (db::cell_index_type ci)
|
||||||
|
{
|
||||||
|
if (m_pattern.is_catchall ()) {
|
||||||
|
return true;
|
||||||
|
} else if (m_cell_index != std::numeric_limits<db::cell_index_type>::max ()) {
|
||||||
|
return ci == db::cell_index_type (m_cell_index);
|
||||||
|
} else if (m_pattern.is_const ()) {
|
||||||
|
if (m_pattern.match (layout ()->cell (ci).get_qualified_name ())) {
|
||||||
|
m_cell_index = ci;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (m_pattern.match (layout ()->cell (ci).get_qualified_name ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void reset (FilterStateBase *previous)
|
virtual void reset (FilterStateBase *previous)
|
||||||
{
|
{
|
||||||
FilterStateBase::reset (previous);
|
FilterStateBase::reset (previous);
|
||||||
@@ -511,7 +540,7 @@ public:
|
|||||||
|
|
||||||
m_top_cell = layout ()->begin_top_down ();
|
m_top_cell = layout ()->begin_top_down ();
|
||||||
m_top_cell_end = layout ()->end_top_cells ();
|
m_top_cell_end = layout ()->end_top_cells ();
|
||||||
while (m_top_cell != m_top_cell_end && (!layout ()->is_valid_cell_index (*m_top_cell) || !m_pattern.match (layout ()->cell (*m_top_cell).get_qualified_name ()))) {
|
while (m_top_cell != m_top_cell_end && (!layout ()->is_valid_cell_index (*m_top_cell) || !cell_matches (*m_top_cell))) {
|
||||||
++m_top_cell;
|
++m_top_cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +553,7 @@ public:
|
|||||||
if (m_instance_mode == NoInstances) {
|
if (m_instance_mode == NoInstances) {
|
||||||
|
|
||||||
m_child_cell = mp_parent->begin_child_cells ();
|
m_child_cell = mp_parent->begin_child_cells ();
|
||||||
while (! m_child_cell.at_end () && (!layout ()->is_valid_cell_index (*m_child_cell) || !m_pattern.match (layout ()->cell (*m_child_cell).get_qualified_name ()))) {
|
while (! m_child_cell.at_end () && (!layout ()->is_valid_cell_index (*m_child_cell) || !cell_matches (*m_child_cell))) {
|
||||||
++m_child_cell;
|
++m_child_cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +565,7 @@ public:
|
|||||||
while (m_inst != m_inst_end) {
|
while (m_inst != m_inst_end) {
|
||||||
|
|
||||||
db::cell_index_type cid = (*m_inst)->object ().cell_index ();
|
db::cell_index_type cid = (*m_inst)->object ().cell_index ();
|
||||||
if (layout ()->is_valid_cell_index (cid) && m_pattern.match (layout ()->cell (cid).get_qualified_name ())) {
|
if (layout ()->is_valid_cell_index (cid) && cell_matches (cid)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,7 +605,7 @@ public:
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
++m_child_cell;
|
++m_child_cell;
|
||||||
} while (! m_child_cell.at_end () && (!layout ()->is_valid_cell_index (*m_child_cell) || !m_pattern.match (layout ()->cell (*m_child_cell).get_qualified_name ())));
|
} while (! m_child_cell.at_end () && (!layout ()->is_valid_cell_index (*m_child_cell) || !cell_matches (*m_child_cell)));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -600,7 +629,7 @@ public:
|
|||||||
while (m_inst != m_inst_end) {
|
while (m_inst != m_inst_end) {
|
||||||
|
|
||||||
cid = (*m_inst)->object ().cell_index ();
|
cid = (*m_inst)->object ().cell_index ();
|
||||||
if (layout ()->is_valid_cell_index (cid) && m_pattern.match (layout ()->cell (cid).get_qualified_name ())) {
|
if (layout ()->is_valid_cell_index (cid) && cell_matches (cid)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,7 +665,7 @@ public:
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
++m_top_cell;
|
++m_top_cell;
|
||||||
} while (m_top_cell != m_top_cell_end && (!layout ()->is_valid_cell_index (*m_top_cell) || !m_pattern.match (layout ()->cell (*m_top_cell).get_qualified_name ())));
|
} while (m_top_cell != m_top_cell_end && (!layout ()->is_valid_cell_index (*m_top_cell) || !cell_matches (*m_top_cell)));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1028,6 +1057,7 @@ private:
|
|||||||
bool m_reading;
|
bool m_reading;
|
||||||
std::set<db::Instance> m_ignored;
|
std::set<db::Instance> m_ignored;
|
||||||
db::Instance m_i;
|
db::Instance m_i;
|
||||||
|
db::cell_index_type m_cell_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DB_PUBLIC ChildCellFilter
|
class DB_PUBLIC ChildCellFilter
|
||||||
@@ -1126,11 +1156,30 @@ public:
|
|||||||
m_pids (pids),
|
m_pids (pids),
|
||||||
m_pattern (pattern, eval),
|
m_pattern (pattern, eval),
|
||||||
mp_parent (0),
|
mp_parent (0),
|
||||||
m_reading (reading)
|
m_reading (reading),
|
||||||
|
m_cell_index (std::numeric_limits<db::cell_index_type>::max ())
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cell_matches (db::cell_index_type ci)
|
||||||
|
{
|
||||||
|
if (m_pattern.is_catchall ()) {
|
||||||
|
return true;
|
||||||
|
} else if (m_cell_index != std::numeric_limits<db::cell_index_type>::max ()) {
|
||||||
|
return ci == db::cell_index_type (m_cell_index);
|
||||||
|
} else if (m_pattern.is_const ()) {
|
||||||
|
if (m_pattern.match (layout ()->cell (ci).get_qualified_name ())) {
|
||||||
|
m_cell_index = ci;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (m_pattern.match (layout ()->cell (ci).get_qualified_name ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void reset (FilterStateBase *previous)
|
virtual void reset (FilterStateBase *previous)
|
||||||
{
|
{
|
||||||
FilterStateBase::reset (previous);
|
FilterStateBase::reset (previous);
|
||||||
@@ -1140,7 +1189,7 @@ public:
|
|||||||
m_cell = layout ()->begin_top_down ();
|
m_cell = layout ()->begin_top_down ();
|
||||||
m_cell_end = layout ()->end_top_down ();
|
m_cell_end = layout ()->end_top_down ();
|
||||||
|
|
||||||
while (m_cell != m_cell_end && !m_pattern.match (layout ()->cell (*m_cell).get_qualified_name ())) {
|
while (m_cell != m_cell_end && !cell_matches (*m_cell)) {
|
||||||
++m_cell;
|
++m_cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1158,7 +1207,7 @@ public:
|
|||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
++m_cell;
|
++m_cell;
|
||||||
} while (m_cell != m_cell_end && !m_pattern.match (layout ()->cell (*m_cell).get_qualified_name ()));
|
} while (m_cell != m_cell_end && !cell_matches (*m_cell));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool at_end ()
|
virtual bool at_end ()
|
||||||
@@ -1275,6 +1324,7 @@ private:
|
|||||||
db::Layout::top_down_const_iterator m_cell, m_cell_end;
|
db::Layout::top_down_const_iterator m_cell, m_cell_end;
|
||||||
std::auto_ptr<db::CellCounter> m_cell_counter;
|
std::auto_ptr<db::CellCounter> m_cell_counter;
|
||||||
bool m_reading;
|
bool m_reading;
|
||||||
|
db::cell_index_type m_cell_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DB_PUBLIC CellFilter
|
class DB_PUBLIC CellFilter
|
||||||
|
|||||||
@@ -108,6 +108,16 @@ public:
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool is_const () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool is_catchall () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool match (const char *s, std::vector<std::string> *e) const
|
virtual bool match (const char *s, std::vector<std::string> *e) const
|
||||||
{
|
{
|
||||||
size_t n = e ? e->size () : 0;
|
size_t n = e ? e->size () : 0;
|
||||||
@@ -186,6 +196,11 @@ public:
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool is_const () const
|
||||||
|
{
|
||||||
|
return next () == 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool match (const char *s, std::vector<std::string> *e) const
|
virtual bool match (const char *s, std::vector<std::string> *e) const
|
||||||
{
|
{
|
||||||
if (! m_cs) {
|
if (! m_cs) {
|
||||||
@@ -240,6 +255,11 @@ public:
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool is_catchall () const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool match (const char *, std::vector<std::string> *) const
|
virtual bool match (const char *, std::vector<std::string> *) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -811,6 +831,16 @@ GlobPatternOp *GlobPattern::op () const
|
|||||||
return mp_op;
|
return mp_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GlobPattern::is_catchall () const
|
||||||
|
{
|
||||||
|
return op ()->is_catchall ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GlobPattern::is_const () const
|
||||||
|
{
|
||||||
|
return op ()->is_const ();
|
||||||
|
}
|
||||||
|
|
||||||
bool GlobPattern::match (const char *s) const
|
bool GlobPattern::match (const char *s) const
|
||||||
{
|
{
|
||||||
return op ()->match (s, 0);
|
return op ()->match (s, 0);
|
||||||
|
|||||||
@@ -106,6 +106,16 @@ public:
|
|||||||
return m_p;
|
return m_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the pattern is a catchall expression ("*")
|
||||||
|
*/
|
||||||
|
bool is_catchall () const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the pattern is a const string
|
||||||
|
*/
|
||||||
|
bool is_const () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Match the given string
|
* @brief Match the given string
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ TEST(1)
|
|||||||
tl::GlobPattern a ("*");
|
tl::GlobPattern a ("*");
|
||||||
tl::GlobPattern b ("a");
|
tl::GlobPattern b ("a");
|
||||||
|
|
||||||
|
EXPECT_EQ (a.is_catchall (), true);
|
||||||
|
EXPECT_EQ (a.is_const (), false);
|
||||||
|
EXPECT_EQ (tl::GlobPattern (a).is_catchall (), true);
|
||||||
|
EXPECT_EQ (tl::GlobPattern (a).is_const (), false);
|
||||||
|
EXPECT_EQ (b.is_catchall (), false);
|
||||||
|
EXPECT_EQ (b.is_const (), true);
|
||||||
|
EXPECT_EQ (tl::GlobPattern (b).is_catchall (), false);
|
||||||
|
EXPECT_EQ (tl::GlobPattern (b).is_const (), true);
|
||||||
|
|
||||||
EXPECT_EQ (a.match ("abc"), true);
|
EXPECT_EQ (a.match ("abc"), true);
|
||||||
EXPECT_EQ (a.match ("a"), true);
|
EXPECT_EQ (a.match ("a"), true);
|
||||||
EXPECT_EQ (a.match (""), true);
|
EXPECT_EQ (a.match (""), true);
|
||||||
@@ -44,6 +53,13 @@ TEST(2)
|
|||||||
tl::GlobPattern b ("*a?");
|
tl::GlobPattern b ("*a?");
|
||||||
tl::GlobPattern c ("*a\\?");
|
tl::GlobPattern c ("*a\\?");
|
||||||
|
|
||||||
|
EXPECT_EQ (a.is_catchall (), false);
|
||||||
|
EXPECT_EQ (a.is_const (), false);
|
||||||
|
EXPECT_EQ (b.is_catchall (), false);
|
||||||
|
EXPECT_EQ (b.is_const (), false);
|
||||||
|
EXPECT_EQ (c.is_catchall (), false);
|
||||||
|
EXPECT_EQ (c.is_const (), false);
|
||||||
|
|
||||||
EXPECT_EQ (a.match ("abc"), true);
|
EXPECT_EQ (a.match ("abc"), true);
|
||||||
EXPECT_EQ (a.match ("a"), true);
|
EXPECT_EQ (a.match ("a"), true);
|
||||||
EXPECT_EQ (a.match (""), false);
|
EXPECT_EQ (a.match (""), false);
|
||||||
@@ -15,7 +15,6 @@ SOURCES = \
|
|||||||
tlEvents.cc \
|
tlEvents.cc \
|
||||||
tlExpression.cc \
|
tlExpression.cc \
|
||||||
tlFileUtils.cc \
|
tlFileUtils.cc \
|
||||||
tlGlobPattern.cc \
|
|
||||||
tlIntervalMap.cc \
|
tlIntervalMap.cc \
|
||||||
tlIntervalSet.cc \
|
tlIntervalSet.cc \
|
||||||
tlKDTree.cc \
|
tlKDTree.cc \
|
||||||
@@ -38,7 +37,8 @@ SOURCES = \
|
|||||||
tlUniqueIdTests.cc \
|
tlUniqueIdTests.cc \
|
||||||
tlListTests.cc \
|
tlListTests.cc \
|
||||||
tlEquivalenceClustersTests.cc \
|
tlEquivalenceClustersTests.cc \
|
||||||
tlUniqueNameTests.cc
|
tlUniqueNameTests.cc \
|
||||||
|
tlGlobPatternTests.cc
|
||||||
|
|
||||||
!equals(HAVE_QT, "0") {
|
!equals(HAVE_QT, "0") {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user