Perf: O(n²) Baumtraversierung bei Dateinamen-Konfliktprüfung behoben

_is_filename_used_in_project wurde bei jedem while-Schleifen-Durchlauf
aufgerufen und traversierte den kompletten Baum neu. Ersetzt durch
_collect_project_filenames(), die einmalig ein Set aufbaut → O(1) Lookups.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 20:09:10 +01:00
parent b954106a0d
commit edfe424a6a
+12 -12
View File
@@ -247,10 +247,13 @@ class XmlBatchProcessingThread(QThread):
# Bestimme Ziel-Pfad # Bestimme Ziel-Pfad
target_xml_path = xml_dir / xml_file_path.name target_xml_path = xml_dir / xml_file_path.name
# Set aller bereits im Projekt verwendeten Dateinamen — einmalig aufbauen
used_filenames = self._collect_project_filenames()
# Prüfe auf Namenskonflikte und generiere ggf. alternativen Namen # Prüfe auf Namenskonflikte und generiere ggf. alternativen Namen
original_name = xml_file_path.name original_name = xml_file_path.name
counter = 1 counter = 1
while target_xml_path.exists() or self._is_filename_used_in_project(Path("xml") / target_xml_path.name): while target_xml_path.exists() or (Path("xml") / target_xml_path.name) in used_filenames:
# Generiere alternativen Namen # Generiere alternativen Namen
stem = xml_file_path.stem stem = xml_file_path.stem
suffix = xml_file_path.suffix suffix = xml_file_path.suffix
@@ -290,23 +293,20 @@ class XmlBatchProcessingThread(QThread):
except Exception as e: except Exception as e:
return {"status": "error", "error_msg": str(e)} return {"status": "error", "error_msg": str(e)}
def _is_filename_used_in_project(self, filename: Path) -> bool: def _collect_project_filenames(self) -> set[Path]:
"""Prüft ob ein Dateiname bereits im Projekt verwendet wird.""" """Gibt ein Set aller im Projekt verwendeten XML-Dateipfade zurück."""
if not self.pdf_project.nodes: result: set[Path] = set()
return False
def search_recursive(nodes): def collect(nodes):
for node in nodes: for node in nodes:
if isinstance(node, XslFile) and node.xmls: if isinstance(node, XslFile) and node.xmls:
for xml_file in node.xmls: for xml_file in node.xmls:
if xml_file.xml == filename: result.add(xml_file.xml)
return True
elif isinstance(node, TreeNode) and node.children: elif isinstance(node, TreeNode) and node.children:
if search_recursive(node.children): collect(node.children)
return True
return False
return search_recursive(self.pdf_project.nodes) collect(self.pdf_project.nodes or [])
return result
def _update_stats(self, result: dict): def _update_stats(self, result: dict):
"""Aktualisiert die Statistiken.""" """Aktualisiert die Statistiken."""