@@ -10,6 +10,15 @@ class Planner
1010 SUPERGRAPH_LOCATIONS = [ Supergraph ::SUPERGRAPH_LOCATION ] . freeze
1111 ROOT_INDEX = 0
1212
13+ class ScopePartition
14+ attr_accessor :location , :selections
15+
16+ def initialize ( location :, selections :)
17+ @location = location
18+ @selections = selections
19+ end
20+ end
21+
1322 def initialize ( request )
1423 @request = request
1524 @supergraph = request . supergraph
@@ -102,19 +111,16 @@ def add_step(
102111 end
103112 end
104113
105- ScopePartition = Struct . new ( :location , :selections , keyword_init : true )
106-
107114 # A) Group all root selections by their preferred entrypoint locations.
108115 def build_root_entrypoints
109116 parent_type = @request . query . root_type_for_operation ( @request . operation . operation_type )
110117
111118 case @request . operation . operation_type
112119 when QUERY_OP
113120 # A.1) Group query fields by location for parallel execution.
114- selections_by_location = { }
121+ selections_by_location = Hash . new { | h , k | h [ k ] = [ ] }
115122 each_field_in_scope ( parent_type , @request . operation . selections ) do |node |
116123 locations = @supergraph . locations_by_type_and_field [ parent_type . graphql_name ] [ node . name ] || SUPERGRAPH_LOCATIONS
117- selections_by_location [ locations . first ] ||= [ ]
118124 selections_by_location [ locations . first ] << node
119125 end
120126
@@ -229,7 +235,8 @@ def extract_locale_selections(
229235
230236 # B.3) Collect all variable definitions used within the filtered selection.
231237 extract_node_variables ( node , locale_variables )
232- field_type = @supergraph . memoized_schema_fields ( parent_type . graphql_name ) [ node . name ] . type . unwrap
238+ schema_fields = @supergraph . memoized_schema_fields ( parent_type . graphql_name )
239+ field_type = schema_fields [ node . name ] . type . unwrap
233240
234241 if Util . is_leaf_type? ( field_type )
235242 locale_selections << node
@@ -377,9 +384,11 @@ def delegate_remote_selections(parent_type, remote_selections)
377384 end
378385
379386 # C.2) Distribute non-unique fields among locations that were added during C.1.
380- if selections_by_location . any? && remote_selections . any?
387+ if !selections_by_location . empty? && !remote_selections . empty?
388+ available_locations = Set . new ( selections_by_location . each_key )
389+
381390 remote_selections . reject! do |node |
382- used_location = possible_locations_by_field [ node . name ] . find { selections_by_location [ _1 ] }
391+ used_location = possible_locations_by_field [ node . name ] . find { available_locations . include? ( _1 ) }
383392 if used_location
384393 selections_by_location [ used_location ] << node
385394 true
@@ -388,29 +397,17 @@ def delegate_remote_selections(parent_type, remote_selections)
388397 end
389398
390399 # C.3) Distribute remaining fields among locations weighted by greatest availability.
391- if remote_selections . any?
392- field_count_by_location = remote_selections . each_with_object ( { } ) do |node , memo |
400+ if !remote_selections . empty?
401+ field_count_by_location = Hash . new ( 0 )
402+ remote_selections . each do |node |
393403 possible_locations_by_field [ node . name ] . each do |location |
394- memo [ location ] ||= 0
395- memo [ location ] += 1
404+ field_count_by_location [ location ] += 1
396405 end
397406 end
398407
399408 remote_selections . each do |node |
400409 possible_locations = possible_locations_by_field [ node . name ]
401- preferred_location = possible_locations . first
402-
403- possible_locations . reduce ( 0 ) do |max_availability , possible_location |
404- availability = field_count_by_location . fetch ( possible_location , 0 )
405-
406- if availability > max_availability
407- preferred_location = possible_location
408- availability
409- else
410- max_availability
411- end
412- end
413-
410+ preferred_location = possible_locations . max_by { field_count_by_location [ _1 ] } || possible_locations . first
414411 selections_by_location [ preferred_location ] ||= [ ]
415412 selections_by_location [ preferred_location ] << node
416413 end
0 commit comments