@@ -54,6 +54,9 @@ def freeze
5454 @cached_fields . default_proc = nil
5555 @cached_arguments . default_proc = nil
5656 @loadable_possible_types . default_proc = nil
57+ @cached_field_result . default_proc = nil
58+ @cached_field_result . each { |_ , h | h . default_proc = nil }
59+ @cached_type_result . default_proc = nil
5760 super
5861 end
5962
@@ -122,6 +125,14 @@ def initialize(name: nil, context:, schema:, visibility:)
122125 end . compare_by_identity
123126
124127 @loadable_possible_types = Hash . new { |h , union_type | h [ union_type ] = union_type . possible_types } . compare_by_identity
128+
129+ # Combined cache for field(owner, field_name) — avoids repeated kind check + parent lookup + visibility check
130+ @cached_field_result = Hash . new { |h , owner |
131+ h [ owner ] = Hash . new { |h2 , field_name | h2 [ field_name ] = compute_field ( owner , field_name ) }
132+ } . compare_by_identity
133+
134+ # Cache for type(type_name) — avoids repeated get_type + visibility + referenced? checks
135+ @cached_type_result = Hash . new { |h , type_name | h [ type_name ] = compute_type ( type_name ) }
125136 end
126137
127138 def field_on_visible_interface? ( field , owner )
@@ -149,58 +160,11 @@ def field_on_visible_interface?(field, owner)
149160 end
150161
151162 def type ( type_name )
152- t = @visibility . get_type ( type_name ) # rubocop:disable Development/ContextIsPassedCop
153- if t
154- if t . is_a? ( Array )
155- vis_t = nil
156- t . each do |t_defn |
157- if @cached_visible [ t_defn ] && referenced? ( t_defn )
158- if vis_t . nil?
159- vis_t = t_defn
160- else
161- raise_duplicate_definition ( vis_t , t_defn )
162- end
163- end
164- end
165- vis_t
166- else
167- if t && @cached_visible [ t ] && referenced? ( t )
168- t
169- else
170- nil
171- end
172- end
173- end
163+ @cached_type_result [ type_name ]
174164 end
175165
176166 def field ( owner , field_name )
177- f = if owner . kind . fields? && ( field = @cached_parent_fields [ owner ] [ field_name ] )
178- field
179- elsif owner == query_root && ( entry_point_field = @schema . introspection_system . entry_point ( name : field_name ) )
180- entry_point_field
181- elsif ( dynamic_field = @schema . introspection_system . dynamic_field ( name : field_name ) )
182- dynamic_field
183- else
184- nil
185- end
186- if f . is_a? ( Array )
187- visible_f = nil
188- f . each do |f_defn |
189- if @cached_visible_fields [ owner ] [ f_defn ]
190-
191- if visible_f . nil?
192- visible_f = f_defn
193- else
194- raise_duplicate_definition ( visible_f , f_defn )
195- end
196- end
197- end
198- visible_f &.ensure_loaded
199- elsif f && @cached_visible_fields [ owner ] [ f . ensure_loaded ]
200- f
201- else
202- nil
203- end
167+ @cached_field_result [ owner ] [ field_name ]
204168 end
205169
206170 def fields ( owner )
@@ -306,6 +270,7 @@ def visible_enum_value?(enum_value, _ctx = nil)
306270 def preload
307271 load_all_types
308272 @all_types . each do |type_name , type_defn |
273+ type ( type_name )
309274 if type_defn . kind . fields?
310275 fields ( type_defn ) . each do |f |
311276 field ( type_defn , f . graphql_name )
@@ -341,6 +306,60 @@ def preload
341306
342307 private
343308
309+ def compute_type ( type_name )
310+ t = @visibility . get_type ( type_name ) # rubocop:disable Development/ContextIsPassedCop
311+ if t
312+ if t . is_a? ( Array )
313+ vis_t = nil
314+ t . each do |t_defn |
315+ if @cached_visible [ t_defn ] && referenced? ( t_defn )
316+ if vis_t . nil?
317+ vis_t = t_defn
318+ else
319+ raise_duplicate_definition ( vis_t , t_defn )
320+ end
321+ end
322+ end
323+ vis_t
324+ else
325+ if t && @cached_visible [ t ] && referenced? ( t )
326+ t
327+ else
328+ nil
329+ end
330+ end
331+ end
332+ end
333+
334+ def compute_field ( owner , field_name )
335+ f = if owner . kind . fields? && ( field = @cached_parent_fields [ owner ] [ field_name ] )
336+ field
337+ elsif owner == query_root && ( entry_point_field = @schema . introspection_system . entry_point ( name : field_name ) )
338+ entry_point_field
339+ elsif ( dynamic_field = @schema . introspection_system . dynamic_field ( name : field_name ) )
340+ dynamic_field
341+ else
342+ nil
343+ end
344+ if f . is_a? ( Array )
345+ visible_f = nil
346+ f . each do |f_defn |
347+ if @cached_visible_fields [ owner ] [ f_defn ]
348+ if visible_f . nil?
349+ visible_f = f_defn
350+ else
351+ raise_duplicate_definition ( visible_f , f_defn )
352+ end
353+ end
354+ end
355+ visible_f &.ensure_loaded
356+ elsif f && @cached_visible_fields [ owner ] [ f . ensure_loaded ]
357+ f
358+ else
359+ nil
360+ end
361+ end
362+
344363 def non_duplicate_items ( definitions , visibility_cache )
345364 non_dups = [ ]
346365 names = Set . new
0 commit comments