CARDLIST::find_: miss cache - gnucap.git - Gnu Circuit Analysis Package

index : gnucap.git
Gnu Circuit Analysis Package
summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix Salfelder <felix@salfelder.org>2025年11月19日 00:00:00 +0000
committerFelix Salfelder <felix@salfelder.org>2025年11月19日 00:00:00 +0000
commit16ed1aded66f2567e2b2869387029f206f989d3f (patch)
tree76d16648d1eedf79a3986b572fd9a14a29bc5e49
parent0db6ea70ec9c1a81e3d0e6c5636e803b15d7e31a (diff)
downloadgnucap-find_miss_cache.tar.gz
CARDLIST::find_: miss cachefind_miss_cache
keep track of misses, so we do not have to find again. parses 350000 items in a .subckt in <3 seconds.
Diffstat
-rw-r--r--include/e_cardlist.h 26
-rw-r--r--include/patchlev.h 2
-rw-r--r--lib/e_card.cc 5
-rw-r--r--lib/e_cardlist.cc 62
-rw-r--r--tests/==out/lang_verilog.dup.1.gc.out 2
5 files changed, 84 insertions, 13 deletions
diff --git a/include/e_cardlist.h b/include/e_cardlist.h
index fac46893..018a69f3 100644
--- a/include/e_cardlist.h
+++ b/include/e_cardlist.h
@@ -26,6 +26,7 @@
#define E_CARDLIST_H
#include "md.h"
#include "u_parameter.h"
+#include <set>
/*--------------------------------------------------------------------------*/
// defined here
class CARD_LIST;
@@ -39,14 +40,18 @@ struct TIME_PAIR;
/*--------------------------------------------------------------------------*/
class INTERFACE CARD_LIST {
public: // base types
- typedef std::list<CARD*> list;
+ typedef CARD value_type;
+ typedef std::list<value_type*> list;
typedef list::iterator iterator;
typedef list::const_iterator const_iterator;
typedef list::reverse_iterator reverse_iterator;
+ typedef list::const_reverse_iterator const_reverse_iterator;
+ typedef std::set<std::string> miss_cache_t;
private: // data members
const CARD_LIST* _parent;
mutable NODE_MAP* _nm;
mutable PARAM_LIST* _params;
+ mutable miss_cache_t* _misses{nullptr};
list _cl;
public: // more types
class fat_iterator {
@@ -89,8 +94,7 @@ public: // more types
iterator begin() {return _cl.begin();}
iterator end() {return _cl.end();}
iterator find_again(const std::string& short_name, iterator);
- iterator find_(const std::string& short_name)
- {return find_again(short_name, begin());}
+ iterator find_(const std::string& short_name);
reverse_iterator rbegin() { return _cl.rbegin();}
reverse_iterator rend() { return _cl.rend();}
@@ -100,14 +104,18 @@ public:
const_iterator begin()const {return _cl.begin();}
const_iterator end()const {return _cl.end();}
const_iterator find_again(const std::string& short_name, const_iterator)const;
- const_iterator find_(const std::string& short_name)const
- {return find_again(short_name, begin());}
+ const_iterator find_(const std::string& short_name) const
+ {return const_cast<CARD_LIST*>(this)->find_(short_name);}
+private: // cache implementation
+ void clear_find_cache();
+ void add_to_find_cache(CARD*);
+ void record_miss(std::string const&);
- // add to it
- CARD_LIST& push_front(CARD* c) {_cl.push_front(c); return *this;}
- CARD_LIST& push_back(CARD* c) {_cl.push_back(c); return *this;}
+public: // add to it
+ CARD_LIST& push_front(CARD* c) {clear_find_cache(); _cl.push_front(c); return *this;}
+ CARD_LIST& push_back(CARD* c) {add_to_find_cache(c); _cl.push_back(c); return *this;}
CARD_LIST& insert(CARD_LIST::iterator i, CARD* c)
- {_cl.insert(i, c); return *this;}
+ {clear_find_cache(); _cl.insert(i, c); return *this;}
// take things out
CARD_LIST& erase(iterator i);
diff --git a/include/patchlev.h b/include/patchlev.h
index e49e2f9d..40347c62 100644
--- a/include/patchlev.h
+++ b/include/patchlev.h
@@ -1 +1 @@
-#define PATCHLEVEL "parse_dump 2025年11月11日"
+#define PATCHLEVEL "find_miss_cache 2025年11月19日"
diff --git a/lib/e_card.cc b/lib/e_card.cc
index 0ca75d4d..d6a11a35 100644
--- a/lib/e_card.cc
+++ b/lib/e_card.cc
@@ -221,7 +221,7 @@ const CARD* CARD::find_in_parent_scope(const std::string& name)const
CARD_LIST::const_iterator j = i;
if (i == p_scope->end()) {
throw Exception_Cant_Find(long_label(), name);
- }else if(p_scope->find_again(name, ++j) != p_scope->end()){
+ }else if(p_scope->find_again(name, ++j) != p_scope->end()){ untested();
error(bWARNING, "duplicate match " + name + " in " + long_label() + "\n");
}else{
}
@@ -241,7 +241,8 @@ const CARD* CARD::find_looking_out(const std::string& name)const
return owner()->find_looking_out(name);
}else if (makes_own_scope()) {
// probably a subckt or "module"
- CARD_LIST::const_iterator i = CARD_LIST::card_list.find_(name);
+ // BUG? why not "find_again?"
+ auto i = CARD_LIST::card_list.find_(name);
if (i != CARD_LIST::card_list.end()) {
return *i;
}else{
diff --git a/lib/e_cardlist.cc b/lib/e_cardlist.cc
index 5275b4d9..304ddd6c 100644
--- a/lib/e_cardlist.cc
+++ b/lib/e_cardlist.cc
@@ -116,8 +116,47 @@ CARD_LIST::const_iterator CARD_LIST::find_again(const std::string& short_name,
return notstd::find_ptr(Begin, end(), short_name);
}
/*--------------------------------------------------------------------------*/
+CARD_LIST::iterator CARD_LIST::find_(const std::string& name)
+{
+ bool miss = false;
+
+ if(!_misses) {
+ }else if(_misses->count(name)) {
+ miss = true;
+ }else if(OPT::case_insensitive) {
+ std::string low = name;
+ notstd::to_lower(&low);
+ if(_misses->count(low)) {
+ miss = true;
+ }else{
+ }
+ }else{
+ }
+
+ if(miss){
+ return end();
+ }else{
+ CARD_LIST::iterator r = find_again(name, begin());
+ if(r == end()) {
+ record_miss(name);
+ }else{
+ }
+ return r;
+ }
+}
+/*--------------------------------------------------------------------------*/
+void CARD_LIST::record_miss(std::string const& name)
+{
+ if(_misses){
+ }else{
+ _misses = new std::set<std::string>;
+ }
+ _misses->insert(name);
+}
+/*--------------------------------------------------------------------------*/
CARD_LIST& CARD_LIST::erase(iterator ci)
{
+ clear_find_cache();
assert(ci != end());
if (*ci) {
(*ci)->purge();
@@ -131,6 +170,7 @@ CARD_LIST& CARD_LIST::erase(iterator ci)
CARD_LIST& CARD_LIST::erase(CARD* c)
{
if (c) {
+ clear_find_cache();
c->purge();
delete c;
_cl.remove(c);
@@ -144,6 +184,7 @@ CARD_LIST& CARD_LIST::erase(CARD* c)
*/
CARD_LIST& CARD_LIST::erase_all()
{
+ clear_find_cache();
while (!_cl.empty()) {
if (_cl.back()) {
_cl.back()->purge();
@@ -557,6 +598,7 @@ void CARD_LIST::shallow_copy(const CARD_LIST* p)
{
assert(p);
_parent = p;
+ clear_find_cache();
for (const_iterator ci = p->begin(); ci != p->end(); ++ci) {
trace_func_comp();
if ((**ci).is_device() || dynamic_cast<MODEL_CARD*>(*ci)) {
@@ -653,5 +695,25 @@ void CARD_LIST::set_verilog_math(bool m)
_params->set_verilog(m);
}
/*--------------------------------------------------------------------------*/
+void CARD_LIST::add_to_find_cache(CARD* c)
+{
+ assert(c);
+ if(_misses){ itested();
+ // this is really needed in repeat finds during sckt parse.
+ // (most calls are no-ops)
+ std::string name = c->short_label();
+ _misses->erase(name);
+ notstd::to_lower(&name);
+ _misses->erase(name);
+ }else{
+ }
+}
+/*--------------------------------------------------------------------------*/
+void CARD_LIST::clear_find_cache()
+{
+ delete _misses;
+ _misses = nullptr;
+}
+/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// vim:ts=8:sw=2:noet:
diff --git a/tests/==out/lang_verilog.dup.1.gc.out b/tests/==out/lang_verilog.dup.1.gc.out
index ca9eb95a..b4ceadf0 100644
--- a/tests/==out/lang_verilog.dup.1.gc.out
+++ b/tests/==out/lang_verilog.dup.1.gc.out
@@ -12,4 +12,4 @@ module aaa (.a(a),.b(b));
endmodule // aaa
# v(a)
- 0. 1.
+ 0. 2.
generated by cgit v1.2.3 (git 2.46.0) at 2025年11月24日 02:16:42 +0000

AltStyle によって変換されたページ (->オリジナル) /