Lazily load db of type DBM instance variable for DatabaseCache so the corresponding database file isn't created in the .use block for a DatabaseCache.

This commit is contained in:
Andrew R. McBurney 2018-05-18 16:37:01 -04:00
parent cd6f89ca76
commit e93e8f3266
6 changed files with 55 additions and 25 deletions

View File

@ -14,21 +14,51 @@ class DatabaseCache
def self.use(type) def self.use(type)
return_value = nil return_value = nil
DatabaseCache.new(type) { |db| return_value = yield(db) }
DatabaseCache.new(type) do |database_cache|
return_value = yield(database_cache)
end
return_value return_value
end end
# Lazily loaded database in read/write mode. If this method is called, a
# database file with be created in the `HOMEBREW_CACHE` with name
# corresponding to the `@type` instance variable
#
# @return [DBM] db
def db
# DBM::WRCREAT: Creates the database if it does not already exist
@db ||= DBM.open(cache_path, DATABASE_MODE, DBM::WRCREAT)
end
# Returns `true` if the cache is empty for the given `@type`
#
# @return [Boolean]
def empty?
!File.exist?(cache_path)
end
private private
# Opens and yields a database in read/write mode. Closes the database after use # Opens and yields the cache. Closes the database after use if it has been
# loaded
# #
# @yield [DBM] db # @param [Symbol] type
# @yield [DatabaseCache] self
# @return [nil] # @return [nil]
def initialize(name) def initialize(type)
# DBM::WRCREAT: Creates the database if it does not already exist @type = type
@db = DBM.open("#{HOMEBREW_CACHE}/#{name}.db", DATABASE_MODE, DBM::WRCREAT) yield(self)
yield(@db) @db&.close
@db.close end
# The path where the database resides in the `HOMEBREW_CACHE` for the given
# `@type`
#
# @return [String]
def cache_path
File.join(HOMEBREW_CACHE, "#{@type}.db")
end end
end end
@ -37,10 +67,10 @@ end
# storage mechanism # storage mechanism
# #
class CacheStore class CacheStore
# @param [DBM] database_cache # @param [DBM] db
# @return [nil] # @return [nil]
def initialize(database_cache) def initialize(db)
@database_cache = database_cache @db = db
end end
# Inserts new values or updates existing cached values to persistent storage # Inserts new values or updates existing cached values to persistent storage
@ -69,7 +99,7 @@ class CacheStore
protected protected
# @return [DBM] # @return [DBM]
attr_reader :database_cache attr_reader :db
# DBM stores ruby objects as a ruby `String`. Hence, when fetching the data, # DBM stores ruby objects as a ruby `String`. Hence, when fetching the data,
# to convert the ruby string back into a ruby `Hash`, the string is converted # to convert the ruby string back into a ruby `Hash`, the string is converted

View File

@ -25,7 +25,7 @@ module Homebrew
ohai "Checking #{keg.name} linkage" if ARGV.kegs.size > 1 ohai "Checking #{keg.name} linkage" if ARGV.kegs.size > 1
use_cache = ARGV.include?("--cached") || ENV["HOMEBREW_LINKAGE_CACHE"] use_cache = ARGV.include?("--cached") || ENV["HOMEBREW_LINKAGE_CACHE"]
result = LinkageChecker.new(keg, database_cache, use_cache) result = LinkageChecker.new(keg, database_cache.db, use_cache)
if ARGV.include?("--test") if ARGV.include?("--test")
result.display_test_output result.display_test_output

View File

@ -68,7 +68,7 @@ module FormulaCellarChecks
DatabaseCache.use(:linkage) do |database_cache| DatabaseCache.use(:linkage) do |database_cache|
use_cache = !ENV["HOMEBREW_LINKAGE_CACHE"].nil? use_cache = !ENV["HOMEBREW_LINKAGE_CACHE"].nil?
checker = LinkageChecker.new(keg, database_cache, use_cache, formula) checker = LinkageChecker.new(keg, database_cache.db, use_cache, formula)
next unless checker.broken_library_linkage? next unless checker.broken_library_linkage?
output = <<~EOS output = <<~EOS

View File

@ -1529,7 +1529,7 @@ class Formula
undeclared_deps = DatabaseCache.use(:linkage) do |database_cache| undeclared_deps = DatabaseCache.use(:linkage) do |database_cache|
use_cache = !ENV["HOMEBREW_LINKAGE_CACHE"].nil? use_cache = !ENV["HOMEBREW_LINKAGE_CACHE"].nil?
linkage_checker = LinkageChecker.new(keg, database_cache, use_cache, self) linkage_checker = LinkageChecker.new(keg, database_cache.db, use_cache, self)
linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } linkage_checker.undeclared_deps.map { |n| Dependency.new(n) }
end end

View File

@ -613,7 +613,7 @@ class FormulaInstaller
# Updates the cache for a particular formula after doing an install # Updates the cache for a particular formula after doing an install
DatabaseCache.use(:linkage) do |database_cache| DatabaseCache.use(:linkage) do |database_cache|
break if database_cache.empty? break if database_cache.empty?
LinkageChecker.new(keg, database_cache, false, formula) LinkageChecker.new(keg, database_cache.db, false, formula)
end end
# let's reset Utils.git_available? if we just installed git # let's reset Utils.git_available? if we just installed git

View File

@ -11,11 +11,11 @@ class LinkageStore < CacheStore
HASH_LINKAGE_TYPES = [:brewed_dylibs, :reverse_links, :broken_deps].freeze HASH_LINKAGE_TYPES = [:brewed_dylibs, :reverse_links, :broken_deps].freeze
# @param [String] keg_name # @param [String] keg_name
# @param [DBM] database_cache # @param [DBM] db
# @return [nil] # @return [nil]
def initialize(keg_name, database_cache) def initialize(keg_name, db)
@keg_name = keg_name @keg_name = keg_name
super(database_cache) super(db)
end end
# Inserts dylib-related information into the cache if it does not exist or # Inserts dylib-related information into the cache if it does not exist or
@ -40,7 +40,7 @@ class LinkageStore < CacheStore
end end
end end
database_cache[keg_name] = ruby_hash_to_json_string( db[keg_name] = ruby_hash_to_json_string(
array_values: format_array_values(array_values), array_values: format_array_values(array_values),
hash_values: format_hash_values(hash_values), hash_values: format_hash_values(hash_values),
) )
@ -64,7 +64,7 @@ class LinkageStore < CacheStore
# @return [nil] # @return [nil]
def flush_cache! def flush_cache!
database_cache.delete(keg_name) db.delete(keg_name)
end end
private private
@ -75,15 +75,15 @@ class LinkageStore < CacheStore
# @param [Symbol] the type to fetch from the `LinkageStore` # @param [Symbol] the type to fetch from the `LinkageStore`
# @return [Array] # @return [Array]
def fetch_array_values(type) def fetch_array_values(type)
return [] unless database_cache.key?(keg_name) return [] unless db.key?(keg_name)
json_string_to_ruby_hash(database_cache[keg_name])["array_values"][type.to_s] json_string_to_ruby_hash(db[keg_name])["array_values"][type.to_s]
end end
# @param [Symbol] type # @param [Symbol] type
# @return [Hash] # @return [Hash]
def fetch_hash_values(type) def fetch_hash_values(type)
return {} unless database_cache.key?(keg_name) return {} unless db.key?(keg_name)
json_string_to_ruby_hash(database_cache[keg_name])["hash_values"][type.to_s] json_string_to_ruby_hash(db[keg_name])["hash_values"][type.to_s]
end end
# Formats the linkage data for `array_values` into a kind which can be parsed # Formats the linkage data for `array_values` into a kind which can be parsed