@@ -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 ] } #{ cgems [ 1 ] }  
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 ] } #{ cgems [ 1 ] }  
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