Skip to content

Commit a39bc58

Browse files
author
Matthias Koefferlein
committed
Reusing libraries inside Library#library_from_file and Library#library:from_files for conservative reloading.
1 parent 62e45da commit a39bc58

3 files changed

Lines changed: 63 additions & 4 deletions

File tree

src/db/db/dbFileBasedLibrary.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,27 @@ FileBasedLibrary::merge_with_other_layout (const std::string &path)
5353
}
5454
}
5555

56+
bool
57+
FileBasedLibrary::is_for_path (const std::string &path)
58+
{
59+
return m_other_paths.empty () && m_path == path;
60+
}
61+
62+
bool
63+
FileBasedLibrary::is_for_paths (const std::vector<std::string> &paths)
64+
{
65+
if (paths.size () != m_other_paths.size () + 1) {
66+
return false;
67+
}
68+
69+
// this check is purely based on path strings
70+
std::set<std::string> p1 (paths.begin (), paths.end ());
71+
std::set<std::string> p2;
72+
p2.insert (m_path);
73+
p2.insert (m_other_paths.begin (), m_other_paths.end ());
74+
return p1 == p2;
75+
}
76+
5677
std::string
5778
FileBasedLibrary::load ()
5879
{

src/db/db/dbFileBasedLibrary.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ class DB_PUBLIC FileBasedLibrary
8989
m_other_paths = other_paths;
9090
}
9191

92+
/**
93+
* @brief Gets a value indicating whether the library is for the given path
94+
*/
95+
bool is_for_path (const std::string &path);
96+
97+
/**
98+
* @brief Gets a value indicating whether the library is for the given path
99+
*/
100+
bool is_for_paths (const std::vector<std::string> &paths);
101+
92102
private:
93103
std::string m_name;
94104
std::string m_path;

src/db/db/gsiDeclDbLibrary.cc

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,21 @@ static LibraryImpl *new_lib ()
157157
return new LibraryImpl ();
158158
}
159159

160-
static db::Library *library_from_file (const std::string &path, const std::string &name)
160+
static db::Library *library_from_file (const std::string &path, const std::string &name, const std::string &for_technology)
161161
{
162+
// Check if a library with this specification already is installed and reuse in that case.
163+
if (! name.empty ()) {
164+
165+
db::FileBasedLibrary *old_lib = dynamic_cast<db::FileBasedLibrary *> (library_by_name (name, for_technology));
166+
if (old_lib && old_lib->is_for_path (path)) {
167+
old_lib->load ();
168+
return old_lib;
169+
}
170+
171+
}
172+
162173
std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (path, name));
174+
lib->set_technology (for_technology);
163175

164176
std::string n = lib->load ();
165177
db::Library *ret = lib.get ();
@@ -168,17 +180,30 @@ static db::Library *library_from_file (const std::string &path, const std::strin
168180
return ret;
169181
}
170182

171-
static db::Library *library_from_files (const std::vector<std::string> &paths, const std::string &name)
183+
static db::Library *library_from_files (const std::vector<std::string> &paths, const std::string &name, const std::string &for_technology)
172184
{
173185
if (paths.empty ()) {
174186
throw tl::Exception (tl::to_string (tr ("At least one path must be given")));
175187
}
176188

189+
// Check if a library with this specification already is installed and reuse in that case.
190+
if (! name.empty ()) {
191+
192+
db::FileBasedLibrary *old_lib = dynamic_cast<db::FileBasedLibrary *> (library_by_name (name, for_technology));
193+
if (old_lib && old_lib->is_for_paths (paths)) {
194+
old_lib->load ();
195+
return old_lib;
196+
}
197+
198+
}
199+
177200
std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (paths.front (), name));
178201
for (auto i = paths.begin () + 1; i != paths.end (); ++i) {
179202
lib->merge_with_other_layout (*i);
180203
}
181204

205+
lib->set_technology (for_technology);
206+
182207
std::string n = lib->load ();
183208
db::Library *ret = lib.get ();
184209
register_lib (lib.release (), n);
@@ -191,7 +216,7 @@ static db::Library *library_from_files (const std::vector<std::string> &paths,
191216
*/
192217

193218
LibraryClass<db::Library> decl_Library ("db", "LibraryBase",
194-
gsi::method ("library_from_file", &library_from_file, gsi::arg ("path"), gsi::arg ("name", std::string (), "auto"),
219+
gsi::method ("library_from_file", &library_from_file, gsi::arg ("path"), gsi::arg ("name", std::string (), "auto"), gsi::arg ("for_technology", std::string (), "none"),
195220
"@brief Creates a library from a file\n"
196221
"@param path The path to the file from which to create the library from.\n"
197222
"@param name The name of the library. If empty, the name will be derived from the GDS LIBNAME or the file name.\n"
@@ -200,9 +225,12 @@ LibraryClass<db::Library> decl_Library ("db", "LibraryBase",
200225
"This method will create a \\Library object which is tied to a specific file. This object supports "
201226
"automatic reloading when the \\Library#refresh method is called.\n"
202227
"\n"
228+
"If a file-based library with the same name and path is registered already, this method will not reload again "
229+
"and return the library that was already registered.\n"
230+
"\n"
203231
"This convenience method has been added in version 0.30.8.\n"
204232
) +
205-
gsi::method ("library_from_files", &library_from_files, gsi::arg ("paths"), gsi::arg ("name", std::string (), "auto"),
233+
gsi::method ("library_from_files", &library_from_files, gsi::arg ("paths"), gsi::arg ("name", std::string (), "auto"), gsi::arg ("for_technology", std::string (), "none"),
206234
"@brief Creates a library from a set of files\n"
207235
"@param paths The paths to the files from which to create the library from. At least one file needs to be given.\n"
208236
"@param name The name of the library. If empty, the name will be derived from the GDS LIBNAME or the file name.\n"

0 commit comments

Comments
 (0)