@@ -83,15 +83,13 @@ def [](key)
8383 end
8484
8585 def []=( key , value )
86- @specs << value
86+ delete_by_name ( key )
8787
88- reset!
88+ add_spec ( value )
8989 end
9090
9191 def delete ( specs )
92- Array ( specs ) . each { |spec | @specs . delete ( spec ) }
93-
94- reset!
92+ Array ( specs ) . each { |spec | remove_spec ( spec ) }
9593 end
9694
9795 def sort!
@@ -168,8 +166,10 @@ def specs_with_additional_variants_from(other)
168166
169167 def delete_by_name ( name )
170168 @specs . reject! { |spec | spec . name == name }
169+ @sorted &.reject! { |spec | spec . name == name }
170+ return if @lookup . nil?
171171
172- reset!
172+ @lookup [ name ] = nil
173173 end
174174
175175 def version_for ( name )
@@ -248,11 +248,6 @@ def materialized_specs
248248 @materializations . filter_map ( &:materialized_spec )
249249 end
250250
251- def reset!
252- @sorted = nil
253- @lookup = nil
254- end
255-
256251 def complete_platform ( platform )
257252 new_specs = [ ]
258253
@@ -272,9 +267,7 @@ def complete_platform(platform)
272267 end
273268
274269 if valid_platform && new_specs . any?
275- @specs . concat ( new_specs )
276-
277- reset!
270+ new_specs . each { |spec | add_spec ( spec ) }
278271 end
279272
280273 valid_platform
@@ -295,15 +288,12 @@ def valid_dependencies?(s)
295288 end
296289
297290 def sorted
298- rake = @specs . find { |s | s . name == "rake" }
299- begin
300- @sorted ||= ( [ rake ] + tsort ) . compact . uniq
301- rescue TSort ::Cyclic => error
302- cgems = extract_circular_gems ( error )
303- raise CyclicDependencyError , "Your bundle requires gems that depend" \
304- " on each other, creating an infinite loop. Please remove either" \
305- " gem '#{ cgems [ 0 ] } ' or gem '#{ cgems [ 1 ] } ' and try again."
306- end
291+ @sorted ||= ( [ @specs . find { |s | s . name == "rake" } ] + tsort ) . compact . uniq
292+ rescue TSort ::Cyclic => error
293+ cgems = extract_circular_gems ( error )
294+ raise CyclicDependencyError , "Your bundle requires gems that depend" \
295+ " on each other, creating an infinite loop. Please remove either" \
296+ " gem '#{ cgems [ 0 ] } ' or gem '#{ cgems [ 1 ] } ' and try again."
307297 end
308298
309299 def extract_circular_gems ( error )
@@ -314,8 +304,7 @@ def lookup
314304 @lookup ||= begin
315305 lookup = { }
316306 @specs . each do |s |
317- lookup [ s . name ] ||= [ ]
318- lookup [ s . name ] << s
307+ index_spec ( lookup , s . name , s )
319308 end
320309 lookup
321310 end
@@ -336,5 +325,36 @@ def tsort_each_child(s)
336325 specs_for_name . each { |s2 | yield s2 }
337326 end
338327 end
328+
329+ def add_spec ( spec )
330+ @specs << spec
331+
332+ name = spec . name
333+
334+ @sorted &.insert ( @sorted . bsearch_index { |s | s . name >= name } || @sorted . size , spec )
335+ return if @lookup . nil?
336+
337+ index_spec ( @lookup , name , spec )
338+ end
339+
340+ def remove_spec ( spec )
341+ @specs . delete ( spec )
342+ @sorted &.delete ( spec )
343+ return if @lookup . nil?
344+
345+ indexed_specs = @lookup [ spec . name ]
346+ return unless indexed_specs
347+
348+ if indexed_specs . size > 1
349+ @lookup [ spec . name ] . delete ( spec )
350+ else
351+ @lookup [ spec . name ] = nil
352+ end
353+ end
354+
355+ def index_spec ( hash , key , value )
356+ hash [ key ] ||= [ ]
357+ hash [ key ] << value
358+ end
339359 end
340360end
0 commit comments