Reusing libraries inside Library#library_from_file and Library#library:from_files for conservative reloading.

This commit is contained in:
Matthias Koefferlein 2026-04-03 17:49:29 +02:00
parent 62e45daaea
commit a39bc587c1
3 changed files with 63 additions and 4 deletions

View File

@ -53,6 +53,27 @@ FileBasedLibrary::merge_with_other_layout (const std::string &path)
} }
} }
bool
FileBasedLibrary::is_for_path (const std::string &path)
{
return m_other_paths.empty () && m_path == path;
}
bool
FileBasedLibrary::is_for_paths (const std::vector<std::string> &paths)
{
if (paths.size () != m_other_paths.size () + 1) {
return false;
}
// this check is purely based on path strings
std::set<std::string> p1 (paths.begin (), paths.end ());
std::set<std::string> p2;
p2.insert (m_path);
p2.insert (m_other_paths.begin (), m_other_paths.end ());
return p1 == p2;
}
std::string std::string
FileBasedLibrary::load () FileBasedLibrary::load ()
{ {

View File

@ -89,6 +89,16 @@ public:
m_other_paths = other_paths; m_other_paths = other_paths;
} }
/**
* @brief Gets a value indicating whether the library is for the given path
*/
bool is_for_path (const std::string &path);
/**
* @brief Gets a value indicating whether the library is for the given path
*/
bool is_for_paths (const std::vector<std::string> &paths);
private: private:
std::string m_name; std::string m_name;
std::string m_path; std::string m_path;

View File

@ -157,9 +157,21 @@ static LibraryImpl *new_lib ()
return new LibraryImpl (); return new LibraryImpl ();
} }
static db::Library *library_from_file (const std::string &path, const std::string &name) static db::Library *library_from_file (const std::string &path, const std::string &name, const std::string &for_technology)
{ {
// Check if a library with this specification already is installed and reuse in that case.
if (! name.empty ()) {
db::FileBasedLibrary *old_lib = dynamic_cast<db::FileBasedLibrary *> (library_by_name (name, for_technology));
if (old_lib && old_lib->is_for_path (path)) {
old_lib->load ();
return old_lib;
}
}
std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (path, name)); std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (path, name));
lib->set_technology (for_technology);
std::string n = lib->load (); std::string n = lib->load ();
db::Library *ret = lib.get (); db::Library *ret = lib.get ();
@ -168,17 +180,30 @@ static db::Library *library_from_file (const std::string &path, const std::strin
return ret; return ret;
} }
static db::Library *library_from_files (const std::vector<std::string> &paths, const std::string &name) static db::Library *library_from_files (const std::vector<std::string> &paths, const std::string &name, const std::string &for_technology)
{ {
if (paths.empty ()) { if (paths.empty ()) {
throw tl::Exception (tl::to_string (tr ("At least one path must be given"))); throw tl::Exception (tl::to_string (tr ("At least one path must be given")));
} }
// Check if a library with this specification already is installed and reuse in that case.
if (! name.empty ()) {
db::FileBasedLibrary *old_lib = dynamic_cast<db::FileBasedLibrary *> (library_by_name (name, for_technology));
if (old_lib && old_lib->is_for_paths (paths)) {
old_lib->load ();
return old_lib;
}
}
std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (paths.front (), name)); std::unique_ptr<db::FileBasedLibrary> lib (new db::FileBasedLibrary (paths.front (), name));
for (auto i = paths.begin () + 1; i != paths.end (); ++i) { for (auto i = paths.begin () + 1; i != paths.end (); ++i) {
lib->merge_with_other_layout (*i); lib->merge_with_other_layout (*i);
} }
lib->set_technology (for_technology);
std::string n = lib->load (); std::string n = lib->load ();
db::Library *ret = lib.get (); db::Library *ret = lib.get ();
register_lib (lib.release (), n); register_lib (lib.release (), n);
@ -191,7 +216,7 @@ static db::Library *library_from_files (const std::vector<std::string> &paths,
*/ */
LibraryClass<db::Library> decl_Library ("db", "LibraryBase", LibraryClass<db::Library> decl_Library ("db", "LibraryBase",
gsi::method ("library_from_file", &library_from_file, gsi::arg ("path"), gsi::arg ("name", std::string (), "auto"), gsi::method ("library_from_file", &library_from_file, gsi::arg ("path"), gsi::arg ("name", std::string (), "auto"), gsi::arg ("for_technology", std::string (), "none"),
"@brief Creates a library from a file\n" "@brief Creates a library from a file\n"
"@param path The path to the file from which to create the library from.\n" "@param path The path to the file from which to create the library from.\n"
"@param name The name of the library. If empty, the name will be derived from the GDS LIBNAME or the file name.\n" "@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",
"This method will create a \\Library object which is tied to a specific file. This object supports " "This method will create a \\Library object which is tied to a specific file. This object supports "
"automatic reloading when the \\Library#refresh method is called.\n" "automatic reloading when the \\Library#refresh method is called.\n"
"\n" "\n"
"If a file-based library with the same name and path is registered already, this method will not reload again "
"and return the library that was already registered.\n"
"\n"
"This convenience method has been added in version 0.30.8.\n" "This convenience method has been added in version 0.30.8.\n"
) + ) +
gsi::method ("library_from_files", &library_from_files, gsi::arg ("paths"), gsi::arg ("name", std::string (), "auto"), gsi::method ("library_from_files", &library_from_files, gsi::arg ("paths"), gsi::arg ("name", std::string (), "auto"), gsi::arg ("for_technology", std::string (), "none"),
"@brief Creates a library from a set of files\n" "@brief Creates a library from a set of files\n"
"@param paths The paths to the files from which to create the library from. At least one file needs to be given.\n" "@param paths The paths to the files from which to create the library from. At least one file needs to be given.\n"
"@param name The name of the library. If empty, the name will be derived from the GDS LIBNAME or the file name.\n" "@param name The name of the library. If empty, the name will be derived from the GDS LIBNAME or the file name.\n"