@@ -1401,7 +1401,7 @@ end
14011401# scenario plan and application plans remain immutable values; only their
14021402# runtime shell is reference-backed so passing it across a batch boundary does
14031403# not box and copy the complete typed scenario-plan tuple.
1404- mutable struct CompiledCompositeModel{SC,SP,AP,AI,OA,ABO,IB,CB,IBI,CBI,DBI,DCBI,MBC,DO,CO,AC,SVI,CE,CET,PA,AO}
1404+ mutable struct CompiledCompositeModel{SC,SP,AP,AI,OA,ABO,IB,CB,IBI,CBI,DBI,DCBI,MCBI, MBC,DO,CO,AC,SVI,CE,CET,PA,AO}
14051405 model:: SC
14061406 scenario_plan:: SP
14071407 applications:: AP
@@ -1414,6 +1414,7 @@ mutable struct CompiledCompositeModel{SC,SP,AP,AI,OA,ABO,IB,CB,IBI,CBI,DBI,DCBI,
14141414 call_bindings_by_target:: CBI
14151415 dynamic_input_binding_indices:: DBI
14161416 dynamic_call_binding_indices:: DCBI
1417+ manual_call_binding_indices_by_owner_application:: MCBI
14171418 many_input_binding_cache:: MBC
14181419 distributed_outputs:: DO
14191420 call_owners:: CO
@@ -1509,6 +1510,32 @@ function _index_dynamic_call_bindings(model::CompositeModel, bindings)
15091510 return index
15101511end
15111512
1513+ function _index_manual_call_binding_by_owner_application! (
1514+ index,
1515+ binding:: CompiledModelCallBinding ,
1516+ binding_index:: Int ,
1517+ )
1518+ _compiled_call_mode (binding) === :manual || return index
1519+ _compiled_call_membership_is_observed (binding) || return index
1520+ binding_indices = get! (index, binding. application_id) do
1521+ Int[]
1522+ end
1523+ push! (binding_indices, binding_index)
1524+ return index
1525+ end
1526+
1527+ function _index_manual_call_bindings_by_owner_application (bindings)
1528+ index = Dict {Symbol,Vector{Int}} ()
1529+ for (binding_index, binding) in pairs (bindings)
1530+ _index_manual_call_binding_by_owner_application! (
1531+ index,
1532+ binding,
1533+ binding_index,
1534+ )
1535+ end
1536+ return index
1537+ end
1538+
15121539function _index_model_bindings (bindings, application_field:: Symbol , object_field:: Symbol )
15131540 grouped = Dict {Tuple{Symbol,ObjectId},Vector{Any}} ()
15141541 for binding in bindings
@@ -1700,6 +1727,7 @@ function _compile_scene(
17001727 many_input_binding_cache,
17011728 ),
17021729 _index_dynamic_call_bindings (model, call_bindings),
1730+ _index_manual_call_bindings_by_owner_application (call_bindings),
17031731 many_input_binding_cache,
17041732 distributed_outputs,
17051733 call_owners,
@@ -2776,14 +2804,23 @@ function _propagate_changed_manual_call_owners!(
27762804 changed_target_ids,
27772805 changed_callee_target_ids,
27782806 call_bindings,
2807+ manual_call_binding_indices_by_owner_application,
27792808 call_owners,
2809+ performance= nothing ,
27802810)
27812811 frontier = Dict {Symbol,Vector{ObjectId}} ()
27822812 for (application_id, object_id) in changed_callee_target_ids
2783- push! (get! (frontier, application_id, ObjectId[]), object_id)
2813+ object_ids = get! (frontier, application_id) do
2814+ ObjectId[]
2815+ end
2816+ push! (object_ids, object_id)
27842817 end
27852818 seen_owner_keys = Set {Tuple{Symbol,ObjectId}} (changed_callee_target_ids)
27862819 while ! isempty (frontier)
2820+ _runtime_performance_count! (
2821+ performance,
2822+ :lifecycle_manual_call_owner_frontier_waves ,
2823+ )
27872824 owner_application_ids = Set {Symbol} ()
27882825 for application_id in keys (frontier)
27892826 hasproperty (call_owners, application_id) || continue
@@ -2794,39 +2831,52 @@ function _propagate_changed_manual_call_owners!(
27942831 end
27952832 isempty (owner_application_ids) && break
27962833 next_frontier = Dict {Symbol,Vector{ObjectId}} ()
2797- for binding in call_bindings
2798- binding. application_id in owner_application_ids || continue
2799- _compiled_call_mode (binding) === :manual || continue
2800- _compiled_call_membership_is_observed (binding) || continue
2801- affected = false
2802- for callee_application_id in binding. callee_application_ids
2803- object_ids = get (frontier, callee_application_id, nothing )
2804- isnothing (object_ids) && continue
2805- if any (object_ids) do object_id
2806- first (
2807- _sorted_object_id_position (
2808- binding. callee_object_ids,
2809- object_id,
2810- ),
2811- )
2812- end
2813- affected = true
2814- break
2834+ for owner_application_id in owner_application_ids
2835+ binding_indices = get (
2836+ manual_call_binding_indices_by_owner_application,
2837+ owner_application_id,
2838+ nothing ,
2839+ )
2840+ isnothing (binding_indices) && continue
2841+ for binding_index in binding_indices
2842+ _runtime_performance_count! (
2843+ performance,
2844+ :lifecycle_manual_call_owner_binding_candidates ,
2845+ )
2846+ binding = call_bindings[binding_index]
2847+ owner_key = (binding. application_id, binding. consumer_id)
2848+ owner_key in seen_owner_keys && continue
2849+ affected = false
2850+ for callee_application_id in binding. callee_application_ids
2851+ object_ids = get (frontier, callee_application_id, nothing )
2852+ isnothing (object_ids) && continue
2853+ if any (object_ids) do object_id
2854+ first (
2855+ _sorted_object_id_position (
2856+ binding. callee_object_ids,
2857+ object_id,
2858+ ),
2859+ )
2860+ end
2861+ affected = true
2862+ break
2863+ end
28152864 end
2816- end
2817- affected || continue
2818- owner_key = (binding . application_id, binding . consumer_id )
2819- owner_key in seen_owner_keys && continue
2820- push! (seen_owner_keys, owner_key)
2821- push! (changed_target_ids, owner_key)
2822- push! (
2823- get! (
2865+ affected || continue
2866+ push! (seen_owner_keys, owner_key)
2867+ push! (changed_target_ids, owner_key )
2868+ _runtime_performance_count! (
2869+ performance,
2870+ :lifecycle_manual_call_owner_targets_propagated ,
2871+ )
2872+ next_object_ids = get! (
28242873 next_frontier,
28252874 binding. application_id,
2826- ObjectId[],
2827- ),
2828- binding. consumer_id,
2829- )
2875+ ) do
2876+ ObjectId[]
2877+ end
2878+ push! (next_object_ids, binding. consumer_id)
2879+ end
28302880 end
28312881 frontier = next_frontier
28322882 end
@@ -2963,6 +3013,7 @@ function _prepare_structural_compiled_delta(
29633013 many_input_binding_cache,
29643014 ),
29653015 _index_dynamic_call_bindings (model, call_bindings),
3016+ _index_manual_call_bindings_by_owner_application (call_bindings),
29663017 many_input_binding_cache,
29673018 compiled. distributed_outputs,
29683019 compiled. call_owners,
@@ -3251,6 +3302,8 @@ function _extend_compiled_scene(
32513302 end
32523303 append! (call_bindings, new_call_bindings)
32533304 dynamic_call_binding_indices = compiled. dynamic_call_binding_indices
3305+ manual_call_binding_indices_by_owner_application =
3306+ compiled. manual_call_binding_indices_by_owner_application
32543307 first_new_call_binding = length (call_bindings) - length (new_call_bindings) + 1
32553308 for binding_index in first_new_call_binding: length (call_bindings)
32563309 _index_dynamic_call_binding! (
@@ -3259,6 +3312,11 @@ function _extend_compiled_scene(
32593312 call_bindings[binding_index],
32603313 binding_index,
32613314 )
3315+ _index_manual_call_binding_by_owner_application! (
3316+ manual_call_binding_indices_by_owner_application,
3317+ call_bindings[binding_index],
3318+ binding_index,
3319+ )
32623320 end
32633321 _validate_model_writers_for_objects! (
32643322 applications,
@@ -3662,7 +3720,9 @@ function _extend_compiled_scene(
36623720 changed_execution_target_ids,
36633721 changed_manual_target_ids,
36643722 call_bindings,
3723+ manual_call_binding_indices_by_owner_application,
36653724 call_owners,
3725+ performance,
36663726 )
36673727 changed_execution_application_ids = Set (
36683728 first (key) for key in changed_execution_target_ids
@@ -3685,6 +3745,7 @@ function _extend_compiled_scene(
36853745 call_bindings_by_target,
36863746 dynamic_input_binding_indices,
36873747 dynamic_call_binding_indices,
3748+ manual_call_binding_indices_by_owner_application,
36883749 many_binding_cache,
36893750 distributed_outputs,
36903751 call_owners,
@@ -7218,12 +7279,19 @@ function _observe_compiled_call_membership!(
72187279 candidate -> candidate === binding,
72197280 compiled. call_bindings,
72207281 )
7221- isnothing (binding_index) || _index_dynamic_call_binding! (
7222- compiled. dynamic_call_binding_indices,
7223- compiled. model,
7224- binding,
7225- binding_index,
7226- )
7282+ if ! isnothing (binding_index)
7283+ _index_dynamic_call_binding! (
7284+ compiled. dynamic_call_binding_indices,
7285+ compiled. model,
7286+ binding,
7287+ binding_index,
7288+ )
7289+ _index_manual_call_binding_by_owner_application! (
7290+ compiled. manual_call_binding_indices_by_owner_application,
7291+ binding,
7292+ binding_index,
7293+ )
7294+ end
72277295 return binding
72287296end
72297297
0 commit comments