class Bundler::Checksum::Store

def empty?(spec)

def empty?(spec)
  return false unless spec.source.is_a?(Bundler::Source::Rubygems)
  @store[spec.lock_name].empty?
end

def fetch_checksum(lock_name, algo)

def fetch_checksum(lock_name, algo)
  @store[lock_name]&.fetch(algo, nil)
end

def init_checksum(lock_name)

def init_checksum(lock_name)
  @store[lock_name] ||= {}
end

def initialize

def initialize
  @store = {}
  @store_mutex = Mutex.new
end

def inspect

def inspect
  "#<#{self.class}:#{object_id} size=#{store.size}>"
end

def merge!(other)

def merge!(other)
  other.store.each do |lock_name, checksums|
    checksums.each do |_algo, checksum|
      register_checksum(lock_name, checksum)
    end
  end
end

def merge_checksum(lock_name, checksum, existing)

def merge_checksum(lock_name, checksum, existing)
  existing.merge!(checksum) || raise(ChecksumMismatchError.new(lock_name, existing, checksum))
end

def missing?(spec)

def missing?(spec)
  @store[spec.lock_name].nil?
end

def register(spec, checksum)

def register(spec, checksum)
  register_checksum(spec.lock_name, checksum)
end

def register_checksum(lock_name, checksum)

def register_checksum(lock_name, checksum)
  @store_mutex.synchronize do
    if checksum
      existing = fetch_checksum(lock_name, checksum.algo)
      if existing
        merge_checksum(lock_name, checksum, existing)
      else
        store_checksum(lock_name, checksum)
      end
    else
      init_checksum(lock_name)
    end
  end
end

def replace(spec, checksum)

that contain the same gem with different checksums.
This ensures a mismatch error where there are multiple top level sources
However, if the new checksum is from a different source, we register like normal.

In the Index, the later gem replaces the former, so we do that here.
"darwin20" and "darwin-20", both of which resolve to darwin-20.
In particular, this is when 2 gems have two similar platforms, e.g.

duplicates of the same gem (according to full_name) in the index.
The primary purpose is registering checksums from gems where there are
Replace when the new checksum is from the same source.
def replace(spec, checksum)
  return unless checksum
  lock_name = spec.lock_name
  @store_mutex.synchronize do
    existing = fetch_checksum(lock_name, checksum.algo)
    if !existing || existing.same_source?(checksum)
      store_checksum(lock_name, checksum)
    else
      merge_checksum(lock_name, checksum, existing)
    end
  end
end

def store_checksum(lock_name, checksum)

def store_checksum(lock_name, checksum)
  init_checksum(lock_name)[checksum.algo] = checksum
end

def to_lock(spec)

def to_lock(spec)
  lock_name = spec.lock_name
  checksums = @store[lock_name]
  if checksums&.any?
    "#{lock_name} #{checksums.values.map(&:to_lock).sort.join(",")}"
  else
    lock_name
  end
end