lib/picky/backends/redis.rb in picky-3.6.2 vs lib/picky/backends/redis.rb in picky-3.6.3

- old
+ new

@@ -86,30 +86,48 @@ # routines, can do so analogue to this in their own # backend implementations. # # Note: We use the amount and offset hints to speed Redis up. # -# def ids combinations, amount, offset -# if redis_with_scripting? -# @@script = <<-SCRIPT -# redis.call('zinterstore', KEYS[1], ARGV[1]); -# local result = redis.call('zrange', KEYS[1], ARGV[2], ARGV[3]) -# redis.call('del', KEYS[1]) -# return result -# SCRIPT -# # Scripting version of #ids. -# # -# def ids combinations, amount, offset -# identifiers = combinations.inject([]) do |identifiers, combination| -# identifiers << "#{combination.identifier}" -# end -# -# # Assume it's using EVALSHA. -# # -# client.eval @@script, generate_intermediate_result_id, identifiers, offset, (offset + amount) -# end -# else + def ids combinations, amount, offset + # Just checked once on the first call. + # + if redis_with_scripting? + @@script = "local intersected = redis.call('zinterstore', ARGV[1], #(KEYS), unpack(KEYS)); if intersected == 0 then redis.call('del', ARGV[1]); return {}; end local results = redis.call('zrange', ARGV[1], tonumber(ARGV[2]), tonumber(ARGV[3])); redis.call('del', ARGV[1]); return results;" + + require 'digest/sha1' + @@sent_once = nil + + # Scripting version of #ids. + # + def ids combinations, amount, offset + identifiers = combinations.inject([]) do |identifiers, combination| + identifiers << "#{combination.identifier}" + end + + # Assume it's using EVALSHA. + # + begin + client.evalsha @@sent_once, + identifiers.size, + *identifiers, + generate_intermediate_result_id, + offset, + (offset + amount) + rescue RuntimeError => e + # Make the server have a SHA-1 for the script. + # + @@sent_once = Digest::SHA1.hexdigest @@script + client.eval @@script, + identifiers.size, + *identifiers, + generate_intermediate_result_id, + offset, + (offset + amount) + end + end + else # Non-Scripting version of #ids. # def ids combinations, amount, offset identifiers = combinations.inject([]) do |identifiers, combination| identifiers << "#{combination.identifier}" @@ -117,25 +135,37 @@ result_id = generate_intermediate_result_id # Intersect and store. # - client.zinterstore result_id, identifiers + intersected = client.zinterstore result_id, identifiers + # Return clean and early if there has been no intersection. + # + if intersected.zero? + client.del result_id + return [] + end + # Get the stored result. # results = client.zrange result_id, offset, (offset + amount) # Delete the stored result as it was only for temporary purposes. # - # Note: I could also not delete it, but that would not be clean at all. + # Note: I could also not delete it, but that + # would not be clean at all. # client.del result_id results end - # end - # end + end + + # Call the newly installed version. + # + ids combinations, amount, offset + end # Generate a multiple host/process safe result id. # # Note: Generated when this class loads. # \ No newline at end of file