Skip to content

Instantly share code, notes, and snippets.

@mrkvm
Created October 31, 2012 20:48
Show Gist options
  • Save mrkvm/3989770 to your computer and use it in GitHub Desktop.
Save mrkvm/3989770 to your computer and use it in GitHub Desktop.
A ridiculous Halloween-themed example of stats tracking using Redis bitwise operations
require 'redis'
class TrickOrTreatTracker
def initialize
@redis = Redis.new
end
def track_trick(user_id)
key = "trick-#{Time.now.hour}"
@redis.setbit key, user_id, 1
@redis.sadd "trick", key
end
def track_treat(user_id)
key = "treat-#{Time.now.hour}"
@redis.setbit key, user_id, 1
@redis.sadd "treat", key
end
def unique_tricks(hour=nil)
do_unique(:trick, hour)
end
def unique_treats(hour=nil)
do_unique(:treat, hour)
end
def unique_tricks_and_treats(hour=nil)
do_unique(:trick, hour) + do_unique(:treat, hour)
end
def check_user(user_id, hour=nil)
tricked = false
treated = false
if hour.nil?
tricked = @redis.smembers("trick").any? do |key|
@redis.getbit(key, user_id) == 1
end
treated = @redis.smembers("treat").any? do |key|
@redis.getbit(key, user_id) == 1
end
else
tricked = (@redis.getbit("#{trick}-#{hour}", user_id) == 1)
treated = (@redis.getbit("#{treat}-#{hour}", user_id) == 1)
end
puts "user #{user_id}: hour=#{hour.nil? ? 'all' : hour} tricked=#{tricked}, treated=#{treated}"
end
private
def do_unique(type, hour)
# if hour is nil, then do all tricks/treats
if hour.nil?
@redis.smembers("#{type}").inject(0) do |total, key|
total + @redis.bitcount(key)
end
else
@redis.bitcount "#{type}-#{hour}"
end
end
end
if __FILE__ == $0
Redis.new.flushall
tracker = TrickOrTreatTracker.new
rand(10).times do
tracker.track_trick(rand(20))
end
rand(10).times do
tracker.track_treat(rand(20))
end
puts "Total Unique Tricks: #{tracker.unique_tricks}"
puts "Total Unique Treats: #{tracker.unique_treats}"
puts "Combined Unique Tricks/Treats: #{tracker.unique_tricks_and_treats}"
(0...20).each do |user_id|
tracker.check_user user_id
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment