@@ -19,14 +19,14 @@ def self.build
1919 def initialize
2020 @sources = [ ]
2121 @cache = { }
22- @specs = Hash . new { | h , k | h [ k ] = { } }
22+ @specs = { }
2323 @duplicates = { }
2424 end
2525
2626 def initialize_copy ( o )
2727 @sources = o . sources . dup
2828 @cache = { }
29- @specs = Hash . new { | h , k | h [ k ] = { } }
29+ @specs = { }
3030 @duplicates = { }
3131
3232 o . specs . each do |name , hash |
@@ -46,14 +46,11 @@ def empty?
4646 true
4747 end
4848
49- def search_all ( name )
50- all_matches = specs_by_name ( name ) # always returns a new Array
51- dupes = @duplicates [ name ]
52- all_matches . concat ( dupes ) if dupes
53- @sources . each do |source |
54- all_matches . concat ( source . search_all ( name ) )
55- end
56- all_matches
49+ def search_all ( name , &blk )
50+ return enum_for ( :search_all , name ) unless blk
51+ specs_by_name ( name ) . each ( &blk )
52+ @duplicates [ name ] &.each ( &blk )
53+ @sources . each { |source | source . search_all ( name , &blk ) }
5754 end
5855
5956 # Search this index's specs, and any source indexes that this index knows
@@ -63,11 +60,14 @@ def search(query)
6360 return results unless @sources . any?
6461
6562 @sources . each do |source |
66- results . concat ( source . search ( query ) )
63+ results = safe_concat ( results , source . search ( query ) )
6764 end
68- results . uniq ( &:full_name )
65+ results . uniq! ( &:full_name ) unless results . empty? # avoid modifying frozen EMPTY_SEARCH
66+ results
6967 end
7068
69+ alias_method :[] , :search
70+
7171 def local_search ( query )
7272 case query
7373 when Gem ::Specification , RemoteSpecification , LazySpecification , EndpointSpecification then search_by_spec ( query )
@@ -78,11 +78,8 @@ def local_search(query)
7878 end
7979 end
8080
81- alias_method :[] , :search
82-
8381 def add ( spec )
84- @specs [ spec . name ] [ spec . full_name ] = spec
85- spec
82+ ( @specs [ spec . name ] ||= { } ) . store ( spec . full_name , spec )
8683 end
8784 alias_method :<< , :add
8885
@@ -170,16 +167,25 @@ def add_source(index)
170167
171168 private
172169
170+ def safe_concat ( a , b )
171+ return a if b . empty?
172+ return b if a . empty?
173+ a . concat ( b )
174+ end
175+
173176 def add_duplicate ( spec )
174177 ( @duplicates [ spec . name ] ||= [ ] ) << spec
175178 end
176179
177180 def specs_by_name_and_version ( name , version )
178- specs_by_name ( name ) . select { |spec | spec . version == version }
181+ results = @specs [ name ] &.values
182+ return EMPTY_SEARCH unless results
183+ results . select! { |spec | spec . version == version }
184+ results
179185 end
180186
181187 def specs_by_name ( name )
182- @specs [ name ] . values
188+ @specs [ name ] & .values || EMPTY_SEARCH
183189 end
184190
185191 EMPTY_SEARCH = [ ] . freeze
@@ -190,11 +196,11 @@ def search_by_spec(spec)
190196 end
191197
192198 def find_by_spec ( spec )
193- @specs [ spec . name ] [ spec . full_name ]
199+ @specs [ spec . name ] &. fetch ( spec . full_name , nil )
194200 end
195201
196202 def exist? ( spec )
197- @specs [ spec . name ] . key? ( spec . full_name )
203+ @specs [ spec . name ] & .key? ( spec . full_name )
198204 end
199205 end
200206end
0 commit comments