@@ -83,15 +83,11 @@ def [](key)
8383 end
8484
8585 def []=( key , value )
86- @specs << value
87-
88- reset!
86+ add_spec ( value )
8987 end
9088
9189 def delete ( specs )
92- Array ( specs ) . each { |spec | @specs . delete ( spec ) }
93-
94- reset!
90+ Array ( specs ) . each { |spec | remove_spec ( spec ) }
9591 end
9692
9793 def sort!
@@ -168,8 +164,10 @@ def specs_with_additional_variants_from(other)
168164
169165 def delete_by_name ( name )
170166 @specs . reject! { |spec | spec . name == name }
167+ @sorted &.reject! { |spec | spec . name == name }
168+ return if @lookup . nil?
171169
172- reset!
170+ @lookup [ name ] = nil
173171 end
174172
175173 def version_for ( name )
@@ -248,11 +246,6 @@ def materialized_specs
248246 @materializations . filter_map ( &:materialized_spec )
249247 end
250248
251- def reset!
252- @sorted = nil
253- @lookup = nil
254- end
255-
256249 def complete_platform ( platform )
257250 new_specs = [ ]
258251
@@ -272,9 +265,7 @@ def complete_platform(platform)
272265 end
273266
274267 if valid_platform && new_specs . any?
275- @specs . concat ( new_specs )
276-
277- reset!
268+ new_specs . each { |spec | add_spec ( spec ) }
278269 end
279270
280271 valid_platform
@@ -311,8 +302,7 @@ def lookup
311302 @lookup ||= begin
312303 lookup = { }
313304 @specs . each do |s |
314- lookup [ s . name ] ||= [ ]
315- lookup [ s . name ] << s
305+ index_spec ( lookup , s . name , s )
316306 end
317307 lookup
318308 end
@@ -333,5 +323,36 @@ def tsort_each_child(s)
333323 specs_for_name . each { |s2 | yield s2 }
334324 end
335325 end
326+
327+ def add_spec ( spec )
328+ @specs << spec
329+
330+ name = spec . name
331+
332+ @sorted &.insert ( @sorted . bsearch_index { |s | s . name >= name } || @sorted . size , spec )
333+ return if @lookup . nil?
334+
335+ index_spec ( @lookup , name , spec )
336+ end
337+
338+ def remove_spec ( spec )
339+ @specs . delete ( spec )
340+ @sorted &.delete ( spec )
341+ return if @lookup . nil?
342+
343+ indexed_specs = @lookup [ spec . name ]
344+ return unless indexed_specs
345+
346+ if indexed_specs . size > 1
347+ @lookup [ spec . name ] . delete ( spec )
348+ else
349+ @lookup [ spec . name ] = nil
350+ end
351+ end
352+
353+ def index_spec ( hash , key , value )
354+ hash [ key ] ||= [ ]
355+ hash [ key ] << value
356+ end
336357 end
337358end
0 commit comments