@@ -368,6 +368,38 @@ def calculate_subsystem_fragment_ids(ss):
368368 pi .name == "DataLogger" for pi in self .procinfos if pi .subsystem == ss
369369 )
370370
371+ # Pre-group procinfos by (subsystem, process_type) for O(1) lookup
372+ # instead of iterating all procinfos in create_sources_or_destinations_string
373+ _process_type_keys = ["BoardReader" , "EventBuilder" , "DataLogger" , "Dispatcher" , "RoutingManager" ]
374+
375+ def _get_type_key (name ):
376+ for tk in _process_type_keys :
377+ if tk in name :
378+ return tk
379+ return name
380+
381+ _procinfos_by_ss_type = {}
382+ for pi in procinfos_sorted_by_rank :
383+ key = (pi .subsystem , _get_type_key (pi .name ))
384+ _procinfos_by_ss_type .setdefault (key , []).append (pi )
385+
386+ # Pre-compute inter-subsystem EventBuilder connections:
387+ # For each subsystem, which other subsystems' EBs are sources/destinations
388+ _inter_ss_eb_destinations = {} # ss -> list of EBs in destination subsystem
389+ _inter_ss_eb_sources = {} # ss -> list of EBs in source subsystems
390+ for ss in self .subsystems :
391+ dest_ss = self .subsystems [ss ].destination
392+ if dest_ss :
393+ _inter_ss_eb_destinations [ss ] = _procinfos_by_ss_type .get ((dest_ss , "EventBuilder" ), [])
394+ else :
395+ _inter_ss_eb_destinations [ss ] = []
396+ # Sources: EBs from subsystems whose destination is ss
397+ source_ebs = []
398+ for other_ss in self .subsystems :
399+ if self .subsystems [other_ss ].destination == ss :
400+ source_ebs .extend (_procinfos_by_ss_type .get ((other_ss , "EventBuilder" ), []))
401+ _inter_ss_eb_sources [ss ] = sorted (source_ebs , key = lambda p : p .rank )
402+
371403 # This function will construct the sources or destinations table
372404 # for a given process. If we're performing advanced memory usage,
373405 # the max event size will need to be provided; this value is used
@@ -416,81 +448,43 @@ def create_sources_or_destinations_string(
416448 pass # Same comment for the advanced memory usage case above applies here
417449
418450 procinfo_subsystem_has_dataloggers = subsystem_has_dataloggers [procinfo .subsystem ]
451+ ss = procinfo .subsystem
452+ proc_type = _get_type_key (procinfo .name )
419453
454+ # Use pre-grouped lookup tables to select only relevant processes
420455 procinfos_for_string = []
421456
422- for procinfo_to_check in procinfos_sorted_by_rank :
423- add = False # As in, "add this process we're checking to the sources or destinations
424- # table"
425-
426- if (
427- procinfo_to_check .subsystem == procinfo .subsystem
428- and not inter_subsystem_transfer
429- ):
430- if "BoardReader" in procinfo .name :
431- if (
432- "EventBuilder" in procinfo_to_check .name
433- and nodetype == "destinations"
434- ):
435- add = True
436- elif "EventBuilder" in procinfo .name :
437- if (
438- "BoardReader" in procinfo_to_check .name
439- and nodetype == "sources"
440- ):
441- add = True
442- elif (
443- "DataLogger" in procinfo_to_check .name
444- and nodetype == "destinations"
445- ):
446- add = True
447- elif (
448- not procinfo_subsystem_has_dataloggers
449- and "Dispatcher" in procinfo_to_check .name
450- and nodetype == "destinations"
451- ):
452- add = True
453- elif "DataLogger" in procinfo .name :
454- if (
455- "EventBuilder" in procinfo_to_check .name
456- and nodetype == "sources"
457- ):
458- add = True
459- elif (
460- "Dispatcher" in procinfo_to_check .name
461- and nodetype == "destinations"
462- ):
463- add = True
464- elif "Dispatcher" in procinfo .name :
465- if "DataLogger" in procinfo_to_check .name and nodetype == "sources" :
466- add = True
467- elif (
468- not procinfo_subsystem_has_dataloggers
469- and "EventBuilder" in procinfo_to_check .name
470- and nodetype == "sources"
471- ):
472- add = True
473-
474- if procinfo_to_check .subsystem != procinfo .subsystem and (
475- inter_subsystem_transfer or nodetype == "sources"
476- ): # the two processes are in separate subsystems
477- if (
478- "EventBuilder" in procinfo .name
479- and "EventBuilder" in procinfo_to_check .name
480- ):
481- if (
482- nodetype == "destinations"
483- and self .subsystems [procinfo .subsystem ].destination
484- == procinfo_to_check .subsystem
485- ) or (
486- nodetype == "sources"
487- and self .subsystems [procinfo_to_check .subsystem ].destination
488- == procinfo .subsystem
489- ):
490- add = True
491-
492- if add :
493- procinfos_for_string .append (procinfo_to_check )
457+ if not inter_subsystem_transfer :
458+ if proc_type == "BoardReader" and nodetype == "destinations" :
459+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "EventBuilder" ), []))
460+ elif proc_type == "EventBuilder" :
461+ if nodetype == "sources" :
462+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "BoardReader" ), []))
463+ elif nodetype == "destinations" :
464+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "DataLogger" ), []))
465+ if not procinfo_subsystem_has_dataloggers :
466+ procinfos_for_string .extend (_procinfos_by_ss_type .get ((ss , "Dispatcher" ), []))
467+ procinfos_for_string .sort (key = lambda p : p .rank )
468+ elif proc_type == "DataLogger" :
469+ if nodetype == "sources" :
470+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "EventBuilder" ), []))
471+ elif nodetype == "destinations" :
472+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "Dispatcher" ), []))
473+ elif proc_type == "Dispatcher" :
474+ if nodetype == "sources" :
475+ procinfos_for_string = list (_procinfos_by_ss_type .get ((ss , "DataLogger" ), []))
476+ if not procinfo_subsystem_has_dataloggers :
477+ procinfos_for_string .extend (_procinfos_by_ss_type .get ((ss , "EventBuilder" ), []))
478+ procinfos_for_string .sort (key = lambda p : p .rank )
479+
480+ # Inter-subsystem EventBuilder connections
481+ if proc_type == "EventBuilder" and (inter_subsystem_transfer or nodetype == "sources" ):
482+ if nodetype == "destinations" :
483+ procinfos_for_string .extend (_inter_ss_eb_destinations .get (ss , []))
484+ if nodetype == "sources" :
485+ procinfos_for_string .extend (_inter_ss_eb_sources .get (ss , []))
486+ # Re-sort by rank to maintain original ordering
487+ procinfos_for_string .sort (key = lambda p : p .rank )
494488
495489 nodes = []
496490
0 commit comments