aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bundler/index.rb
diff options
context:
space:
mode:
authorMartin Emde <martin.emde@gmail.com>2023-09-14 19:33:22 -0700
committergit <svn-admin@ruby-lang.org>2023-09-15 22:01:11 +0000
commit010017d86d5ba6403e3406cae5986348ed08a678 (patch)
treed1e2650822ecc6d2b20bde78a5af4cc679347966 /lib/bundler/index.rb
parent2cf5fe58fbe8053f661552786a93d8cad7c307e0 (diff)
downloadruby-010017d86d5ba6403e3406cae5986348ed08a678.tar.gz
[rubygems/rubygems] Reduce array allocations and concatenations in Index
Remove the default nested hash in Index entirely Index#search_all now yields or returns enum since that's what caller needs. https://github.com/rubygems/rubygems/commit/c45ea3bbe2
Diffstat (limited to 'lib/bundler/index.rb')
-rw-r--r--lib/bundler/index.rb49
1 files changed, 26 insertions, 23 deletions
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 1b2d3b5333..6a17d45eaf 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -19,14 +19,14 @@ module Bundler
def initialize
@sources = []
@cache = {}
- @specs = Hash.new {|h, k| h[k] = {} }
+ @specs = {}
@duplicates = {}
end
def initialize_copy(o)
@sources = o.sources.dup
@cache = {}
- @specs = Hash.new {|h, k| h[k] = {} }
+ @specs = {}
@duplicates = {}
o.specs.each do |name, hash|
@@ -46,14 +46,11 @@ module Bundler
true
end
- def search_all(name)
- all_matches = specs_by_name(name) # always returns a new Array
- dupes = @duplicates[name]
- all_matches.concat(dupes) if dupes
- @sources.each do |source|
- all_matches.concat(source.search_all(name))
- end
- all_matches
+ def search_all(name, &blk)
+ return enum_for(:search_all, name) unless blk
+ specs_by_name(name).each(&blk)
+ @duplicates[name]&.each(&blk)
+ @sources.each {|source| source.search_all(name, &blk) }
end
# Search this index's specs, and any source indexes that this index knows
@@ -63,11 +60,14 @@ module Bundler
return results unless @sources.any?
@sources.each do |source|
- results.concat(source.search(query))
+ results = safe_concat(results, source.search(query))
end
- results.uniq(&:full_name)
+ results.uniq!(&:full_name) unless results.empty? # avoid modifying frozen EMPTY_SEARCH
+ results
end
+ alias_method :[], :search
+
def local_search(query)
case query
when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
@@ -78,11 +78,8 @@ module Bundler
end
end
- alias_method :[], :search
-
def add(spec)
- @specs[spec.name][spec.full_name] = spec
- spec
+ (@specs[spec.name] ||= {}).store(spec.full_name, spec)
end
alias_method :<<, :add
@@ -170,17 +167,25 @@ module Bundler
private
+ def safe_concat(a, b)
+ return a if b.empty?
+ return b if a.empty?
+ a.concat(b)
+ end
+
def add_duplicate(spec)
(@duplicates[spec.name] ||= []) << spec
end
def specs_by_name_and_version(name, version)
- specs_by_name(name).select {|spec| spec.version == version }
+ results = @specs[name]&.values
+ return EMPTY_SEARCH unless results
+ results.select! {|spec| spec.version == version }
+ results
end
def specs_by_name(name)
- return EMPTY_SEARCH unless specs = @specs.fetch(name, nil)
- specs.values
+ @specs[name]&.values || EMPTY_SEARCH
end
EMPTY_SEARCH = [].freeze
@@ -191,13 +196,11 @@ module Bundler
end
def find_by_spec(spec)
- return unless specs = @specs.fetch(spec.name, nil)
- specs[spec.full_name]
+ @specs[spec.name]&.fetch(spec.full_name, nil)
end
def exist?(spec)
- return unless specs = @specs.fetch(spec.name, nil)
- specs.key?(spec.full_name)
+ @specs[spec.name]&.key?(spec.full_name)
end
end
end