updated Redistat::Summary to make it easier to plugin the buffer interception code

This commit is contained in:
2011-04-15 14:14:17 +01:00
parent a197a04ce8
commit 61231a8b57
3 changed files with 65 additions and 58 deletions

View File

@@ -2,66 +2,73 @@ module Redistat
class Summary
include Database
def self.default_options
{ :enable_grouping => true,
:label_indexing => true,
:connection_ref => nil }
end
def self.update_all(key, stats = {}, depth_limit = nil, opts = {})
stats ||= {}
return nil if stats.size == 0
class << self
options = default_options.merge((opts || {}).reject { |k,v| v.nil? })
def default_options
{ :enable_grouping => true,
:label_indexing => true,
:connection_ref => nil }
end
depth_limit ||= key.depth
def update_all(key, stats = {}, depth_limit = nil, opts = {})
stats ||= {}
return nil if stats.size == 0
options = default_options.merge((opts || {}).reject { |k,v| v.nil? })
depth_limit ||= key.depth
update(key, stats, depth_limit, options[:enable_grouping], options[:connection_ref], options)
end
if options[:enable_grouping]
stats = inject_group_summaries(stats)
key.groups.each do |k|
update_key(k, stats, depth_limit, options[:connection_ref])
k.update_index if options[:label_indexing]
private
def update(key, stats, depth_limit, enable_grouping, connection_ref, options)
if enable_grouping
stats = inject_group_summaries(stats)
key.groups.each do |k|
update_key(k, stats, depth_limit, connection_ref)
k.update_index if options[:label_indexing]
end
else
update_key(key, stats, depth_limit, connection_ref)
end
else
update_key(key, stats, depth_limit, options[:connection_ref])
end
end
private
def self.update_key(key, stats, depth_limit, connection_ref)
Date::DEPTHS.each do |depth|
update(key, stats, depth, connection_ref)
break if depth == depth_limit
def update_key(key, stats, depth_limit, connection_ref)
Date::DEPTHS.each do |depth|
update_fields(key, stats, depth, connection_ref)
break if depth == depth_limit
end
end
end
def self.update(key, stats, depth, connection_ref = nil)
stats.each do |field, value|
db(connection_ref).hincrby key.to_s(depth), field, value
def update_fields(key, stats, depth, connection_ref = nil)
stats.each do |field, value|
db(connection_ref).hincrby key.to_s(depth), field, value
end
end
end
def self.inject_group_summaries!(stats)
summaries = {}
stats.each do |key, value|
parts = key.to_s.split(GROUP_SEPARATOR)
parts.pop
if parts.size > 0
sum_parts = []
parts.each do |part|
sum_parts << part
sum_key = sum_parts.join(GROUP_SEPARATOR)
(summaries.has_key?(sum_key)) ? summaries[sum_key] += value : summaries[sum_key] = value
def inject_group_summaries!(stats)
summaries = {}
stats.each do |key, value|
parts = key.to_s.split(GROUP_SEPARATOR)
parts.pop
if parts.size > 0
sum_parts = []
parts.each do |part|
sum_parts << part
sum_key = sum_parts.join(GROUP_SEPARATOR)
(summaries.has_key?(sum_key)) ? summaries[sum_key] += value : summaries[sum_key] = value
end
end
end
stats.merge_and_incr!(summaries)
end
stats.merge_and_incr!(summaries)
def inject_group_summaries(stats)
inject_group_summaries!(stats.clone)
end
end
def self.inject_group_summaries(stats)
inject_group_summaries!(stats.clone)
end
end
end

View File

@@ -194,13 +194,13 @@ describe Redistat::Finder do
def create_example_stats
key = Redistat::Key.new(@scope, @label, (first = Time.parse("2010-05-14 13:43")))
Redistat::Summary.update(key, @stats, :hour)
Redistat::Summary.send(:update_fields, key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, Time.parse("2010-05-14 13:53"))
Redistat::Summary.update(key, @stats, :hour)
Redistat::Summary.send(:update_fields, key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, Time.parse("2010-05-14 14:52"))
Redistat::Summary.update(key, @stats, :hour)
Redistat::Summary.send(:update_fields, key, @stats, :hour)
key = Redistat::Key.new(@scope, @label, (last = Time.parse("2010-05-14 15:02")))
Redistat::Summary.update(key, @stats, :hour)
Redistat::Summary.send(:update_fields, key, @stats, :hour)
[first - 1.hour, last + 1.hour]
end

View File

@@ -13,19 +13,19 @@ describe Redistat::Summary do
end
it "should update a single summary properly" do
Redistat::Summary.update(@key, @stats, :hour)
Redistat::Summary.send(:update_fields, @key, @stats, :hour)
summary = db.hgetall(@key.to_s(:hour))
summary.should have(2).items
summary["views"].should == "3"
summary["visitors"].should == "2"
Redistat::Summary.update(@key, @stats, :hour)
Redistat::Summary.send(:update_fields, @key, @stats, :hour)
summary = db.hgetall(@key.to_s(:hour))
summary.should have(2).items
summary["views"].should == "6"
summary["visitors"].should == "4"
Redistat::Summary.update(@key, {"views" => -4, "visitors" => -3}, :hour)
Redistat::Summary.send(:update_fields, @key, {"views" => -4, "visitors" => -3}, :hour)
summary = db.hgetall(@key.to_s(:hour))
summary.should have(2).items
summary["views"].should == "2"
@@ -48,7 +48,7 @@ describe Redistat::Summary do
it "should update summaries even if no label is set" do
key = Redistat::Key.new(@scope, nil, @date, {:depth => :day})
Redistat::Summary.update(key, @stats, :hour)
Redistat::Summary.send(:update_fields, key, @stats, :hour)
summary = db.hgetall(key.to_s(:hour))
summary.should have(2).items
summary["views"].should == "3"