diff --git a/lib/redistat/key.rb b/lib/redistat/key.rb index d253a5d..9e08cf2 100644 --- a/lib/redistat/key.rb +++ b/lib/redistat/key.rb @@ -39,10 +39,20 @@ module Redistat @label.hash end + def label_groups + @label.groups + end + def label=(input) @label = (input.instance_of?(Redistat::Label)) ? input : Label.create(input, @options) end + def groups + @groups ||= label_groups.map do |label_name| + self.class.new(@scope, label_name, self.date, @options) + end + end + def to_s(depth = nil) depth ||= @options[:depth] key = self.prefix diff --git a/lib/redistat/summary.rb b/lib/redistat/summary.rb index f1b50ce..ed03f99 100644 --- a/lib/redistat/summary.rb +++ b/lib/redistat/summary.rb @@ -4,18 +4,30 @@ module Redistat def self.update_all(key, stats = {}, depth_limit = nil, connection_ref = nil, enable_grouping = nil) stats ||= {} - enable_grouping = true if enable_grouping.nil? - stats = inject_group_summaries(stats) if enable_grouping - depth_limit ||= key.depth return nil if stats.size == 0 + + depth_limit ||= key.depth + enable_grouping = true if enable_grouping.nil? + + if enable_grouping + stats = inject_group_summaries(stats) + key.groups.each { |k| + update_key(k, stats, depth_limit, connection_ref) + } + else + update_key(key, stats, depth_limit, 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 end end - private - def self.update(key, stats, depth, connection_ref = nil) stats.each do |field, value| db(connection_ref).hincrby key.to_s(depth), field, value diff --git a/spec/key_spec.rb b/spec/key_spec.rb index 9d8bec4..cc48d08 100644 --- a/spec/key_spec.rb +++ b/spec/key_spec.rb @@ -14,6 +14,7 @@ describe Redistat::Key do @key.scope.should == @scope @key.label.should == @label @key.label_hash.should == @label_hash + @key.label_groups.should == @key.instance_variable_get("@label").groups @key.date.should be_instance_of(Redistat::Date) @key.date.to_time.to_s.should == @date.to_s end @@ -60,4 +61,16 @@ describe Redistat::Key do @key.label_hash == @label_hash end + it "should create a group of keys from label group" do + label = 'message/public/offensive' + result = [ "message/public/offensive", + "message/public", + "message" ] + + key = Redistat::Key.new(@scope, label, @date, {:depth => :hour}) + + key.label_groups.should == result + key.groups.map { |k| k.label }.should == result + end + end \ No newline at end of file diff --git a/spec/summary_spec.rb b/spec/summary_spec.rb index fb1db67..303c03f 100644 --- a/spec/summary_spec.rb +++ b/spec/summary_spec.rb @@ -52,8 +52,8 @@ describe Redistat::Summary do :"od/sugar" => 7, :"od/meth" => 8 } res = Redistat::Summary.send(:inject_group_summaries, hash) res.should == { "count" => 10, "count/hello" => 3, "count/world" => 7, - "death" => 7, "death/bomb" => 4, "death/unicorn" => 3, - "od" => 15, :"od/sugar" => 7, :"od/meth" => 8 } + "death" => 7, "death/bomb" => 4, "death/unicorn" => 3, + "od" => 15, :"od/sugar" => 7, :"od/meth" => 8 } end it "should properly store key group summaries" do @@ -77,4 +77,47 @@ describe Redistat::Summary do summary["visitors/us"].should == "4" end + it "should store label-based grouping enabled stats" do + stats = {"views" => 3, "visitors/eu" => 2, "visitors/us" => 4} + label = "views/about_us" + key = Redistat::Key.new(@scope, label, @date) + Redistat::Summary.update_all(key, stats, :hour) + + key.groups[0].label.should == "views/about_us" + key.groups[1].label.should == "views" + child1 = key.groups[0] + parent = key.groups[1] + + label = "views/contact" + key = Redistat::Key.new(@scope, label, @date) + Redistat::Summary.update_all(key, stats, :hour) + + key.groups[0].label.should == "views/contact" + key.groups[1].label.should == "views" + child2 = key.groups[0] + + summary = db.hgetall(child1.to_s(:hour)) + summary["views"].should == "3" + summary["visitors/eu"].should == "2" + summary["visitors/us"].should == "4" + + summary = db.hgetall(child2.to_s(:hour)) + summary["views"].should == "3" + summary["visitors/eu"].should == "2" + summary["visitors/us"].should == "4" + + summary = db.hgetall(parent.to_s(:hour)) + summary["views"].should == "6" + summary["visitors/eu"].should == "4" + summary["visitors/us"].should == "8" + end + end + + + + + + + +