lib/db_memoize/model.rb in db_memoize-0.1.5 vs lib/db_memoize/model.rb in db_memoize-0.1.6
- old
+ new
@@ -10,36 +10,41 @@
value = nil
args_hash = ::Digest::MD5.hexdigest(Marshal.dump(args))
cached_value = find_memoized_value(method_name, args_hash)
if cached_value
- log(method_name, 'cache hit')
value = Marshal.load(cached_value.value)
+ Helpers.log(self, method_name, 'cache hit')
else
time = ::Benchmark.realtime do
value = send("#{method_name}_without_memoize", *args)
+ create_memoized_value(method_name, args_hash, value)
end
- # dear rubocop, we can't use `format` here, since some of our models have a
- # `format` method themselves.
- # rubocop:disable Style/FormatString
- log(method_name, "cache miss. took #{sprintf('%.2f', time * 1_000)}ms")
- # rubocop:enable Style/FormatString
- create_memoized_value(method_name, args_hash, value)
+ Helpers.log(self, method_name, "cache miss. took #{Kernel.format '%.2f msecs', time * 1_000}")
end
value
end
def unmemoize(method_name = :all)
if method_name != :all
- # FIXME: this works, but isn't immediately visible on the record
+ # FIXME: this works, but isn't immediately visible on the record.
+ # See also note in create_memoized_value.
memoized_values.where(method_name: method_name).delete_all
else
memoized_values.clear
end
end
+ #
+ # Used to set multiple memoized values in one go.
+ #
+ # Example:
+ #
+ # product.memoize_values full_title: "my full title",
+ # autocomplete_info: "my autocomplete_info"
+ #
def memoize_values(values, *args)
args_hash = ::Digest::MD5.hexdigest(Marshal.dump(args))
values.each do |name, value|
create_memoized_value(name, args_hash, value)
@@ -47,35 +52,38 @@
end
private
def create_memoized_value(method_name, args_hash, value)
+ # [TODO] - It would be nice to have an optimized, pg-based inserter
+ # here, for up to 10 times speed. However, the memoized_values
+ # array must then be properly reset.
memoized_values.create!(
entity_table_name: self.class.table_name,
method_name: method_name.to_s,
arguments_hash: args_hash,
value: Marshal.dump(value)
)
end
def find_memoized_value(method_name, args_hash)
+ method_name = method_name.to_s
+
memoized_values.detect do |rec|
- rec.method_name == method_name.to_s &&
+ rec.method_name == method_name &&
rec.arguments_hash == args_hash
end
end
- def log(method_name, msg)
- DbMemoize.logger.info "DbMemoize <#{self.class.name} id: #{id}>##{method_name} - #{msg}"
- end
-
module ClassMethods
def db_memoize(method_name)
@db_memoized_methods ||= []
@db_memoized_methods.push(method_name.to_sym)
- create_alias_method(method_name)
+ # [TODO] - should the create_memoized_** functions really be called
+ # when the method_name is in @db_memoized_methods already?
+ create_memoized_alias_method(method_name)
create_memoized_values_association
end
def db_memoized_methods
methods = @db_memoized_methods || []
@@ -83,20 +91,20 @@
end
def unmemoize(records_or_ids, method_name = :all)
conditions = {
entity_table_name: table_name,
- entity_id: find_ids(records_or_ids)
+ entity_id: Helpers.find_ids(records_or_ids)
}
conditions[:method_name] = method_name unless method_name == :all
DbMemoize::Value.where(conditions).delete_all
end
def memoize_values(records_or_ids, values, *args)
transaction do
- ids = find_ids(records_or_ids)
+ ids = Helpers.find_ids(records_or_ids)
args_hash = ::Digest::MD5.hexdigest(Marshal.dump(args))
ids.each do |id|
values.each do |name, value|
DbMemoize::Value.create!(
@@ -111,17 +119,10 @@
end
end
private
- def find_ids(records_or_ids)
- records_or_ids = Array(records_or_ids)
- return [] if records_or_ids.empty?
-
- records_or_ids.first.is_a?(ActiveRecord::Base) ? records_or_ids.map(&:id) : records_or_ids
- end
-
- def create_alias_method(method_name)
+ def create_memoized_alias_method(method_name)
define_method "#{method_name}_with_memoize" do |*args|
memoized_value(method_name, args)
end
alias_method_chain method_name, :memoize