almicube 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b5b3dee4cf2a4ca349f8b5d218fe23cbb6fbb7c
4
- data.tar.gz: d5423d3770485d8176bd9cb0ac306e0ed2e32ac0
3
+ metadata.gz: 948970158c93ec780b0cc67776325fc29a956c4c
4
+ data.tar.gz: 6c3099a7e13fd8342534eea3487aeadc74d1c787
5
5
  SHA512:
6
- metadata.gz: 86cc68a0f86730eb0d64e526dd49135265090574ac085ea3bbdf267940573cfd1f222abbf6b1eae7348b408684de7f204a0552b0927666850f0b61a0a2d29b04
7
- data.tar.gz: a3d2279edd141c513f93a6e34ae80ab77089d7e01f2c7c354af3fa5ee048ca22e2eea82fa630e850787c78e77b23266e298ecdf2d7395ee12245633a6b12e986
6
+ metadata.gz: ef17980b825c462379eb5e3cf3214b51ea058fe5fa07ef43b35856d1ac928fe548753bd7042496e4da2c61cd23bcacdb9d69c2ba3430ad5296e1ce9c476f373c
7
+ data.tar.gz: 0068d378bd9bbfa1ef7e60b973172e74307016346d7cb7df9640e9e4f1d2db5f9ad899c9964017d68db27002fbc730d0528d570f0098036deec7fefa943df0d9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- almicube (0.0.2)
4
+ almicube (0.0.3)
5
5
  activemodel (~> 4.0)
6
6
  activesupport (~> 4.0)
7
7
  redis (~> 3.0)
@@ -0,0 +1,16 @@
1
+ module Almicube
2
+ module Aggregator
3
+ class AvgAggregator
4
+ protected
5
+
6
+ def sub_aggregate(key)
7
+ keys = ranking.bundled_keys.select { |k| self.class.connection.zcard(k) > 0 }
8
+ keys << ranking.selector.interstore
9
+ weights = keys.map { 1/keys.length }
10
+ if keys.length
11
+ self.class.connection.zinterstore(key, keys, weights)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -20,6 +20,16 @@ module Almicube
20
20
  sub_aggregate self.ranking.key
21
21
  end
22
22
  end
23
+
24
+ protected
25
+
26
+ def data_aggregate(key)
27
+ ranking.records.each do |record|
28
+ value = record.send(ranking.attribute_name) if record.respond_to? ranking.attribute_name
29
+ value = ranking.default_score if value.nil?
30
+ self.class.connection.zadd(key, value, record.to_param)
31
+ end
32
+ end
23
33
  end
24
34
  end
25
35
  end
@@ -3,17 +3,9 @@ module Almicube
3
3
  class SumAggregator < Base
4
4
  protected
5
5
 
6
- def data_aggregate(key)
7
- ranking.records.each do |record|
8
- value = record.send(ranking.attribute_name) if record.respond_to? ranking.attribute_name
9
- value = ranking.default_score if value.nil?
10
- self.class.connection.zadd(key, value, record.to_param)
11
- end
12
- end
13
-
14
6
  def sub_aggregate(key)
15
7
  keys = ranking.bundled_keys.select { |k| self.class.connection.zcard(k) > 0 }
16
- keys << ranking.selector.interstore
8
+ keys << ranking.selector.interstore if ranking.selector.interstore
17
9
  if keys.length
18
10
  self.class.connection.zinterstore(key, keys)
19
11
  end
@@ -28,7 +28,7 @@ module Almicube
28
28
 
29
29
  def connection(env = :default)
30
30
  @connection ||= { default: nil }
31
- raise ArgumentError, "connection does not exist" unless @connection.has_key? env
31
+ raise ArgumentError, "connection does not exist" unless @connection.has_key? env.to_sym
32
32
  @redis ||= Redis.new @connection[env] unless @connection[env].nil?
33
33
  @redis ||= Redis.new
34
34
  end
data/lib/almicube/key.rb CHANGED
@@ -42,5 +42,6 @@ module Almicube
42
42
  end
43
43
 
44
44
  alias :to_s :to_str
45
+ alias :inspect :to_str
45
46
  end
46
47
  end
@@ -45,7 +45,7 @@ module Almicube
45
45
  end
46
46
 
47
47
  def data_key
48
- key_format(@options[:data_key], @options.merge({ type: :data }))
48
+ Almicube::Key.new self, @options.merge( type: :data )
49
49
  end
50
50
 
51
51
  def attribute_name
@@ -1,3 +1,3 @@
1
1
  module Almicube
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
data/lib/almicube.rb CHANGED
@@ -34,6 +34,7 @@ module Almicube
34
34
  module Aggregator
35
35
  autoload :Base, 'almicube/aggregator/base'
36
36
  autoload :SumAggregator, 'almicube/aggregator/sum_aggregator'
37
+ autoload :AvgAggregator, 'almicube/aggregator/avg_aggregator'
37
38
  end
38
39
 
39
40
  if defined? ActiveRecord
@@ -1,92 +1,38 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Almicube::Aggregator::SumAggregator do
4
- let(:size) { 1 }
5
- let(:size_d) { size * 10 }
6
-
7
4
  before(:all) { @connection = Redis.new }
8
- before { @connection.flushdb }
9
-
10
- it { expect(size).to be > 0 }
11
-
12
- shared_examples "correct aggregation" do
13
- before { aggregator.ranking = ranking }
14
-
15
- it "add new sorted set" do
16
- expect{ aggregator.aggregate }.to change{ @connection.dbsize }.by 1
17
- end
18
- it "has correct items" do
19
- expect(@connection.zcard(ranking.key)).to eq 0
20
- aggregator.aggregate
21
- expect(@connection.zcard(ranking.key)).to eq ranking.records.count
22
- end
5
+ before do
6
+ @connection.flushdb
7
+ Almicube::Config.config.stub(:connection) { @connection }
23
8
  end
24
9
 
25
- context "data ranking" do
26
- context "target attribute is score" do
27
- let(:ranking) { double( key: "sample:score", attribute_name: :score, data?: true ) }
28
- let(:aggregator) { described_class.new }
29
- before do
30
- ranking.stub(:records) { size_d.times.map { |i| double( to_param: i, score: i*10 ) } }
31
- end
32
- it_behaves_like "correct aggregation"
33
- end
10
+ describe "#aggregate" do
11
+ [10, 100, 300].each do |size|
12
+ describe "with #{size} records" do
13
+ let(:key) { "sample" }
14
+ let(:ranking) { double( records: records, selector: nil, data?: true, key: key, attribute_name: attribute ) }
15
+ let(:records) { size.times.map { |i| double( to_param: i+1, score: 100, access: (i + 2) * 12 ) } }
16
+ let(:aggregator) { described_class.new }
17
+ let(:attribute) { :score }
34
18
 
35
- context "target attribute is access" do
36
- let(:ranking) { double( key: "sample:access", attribute_name: :access, data?: true) }
37
- let(:aggregator) { described_class.new }
38
- before do
39
- ranking.stub(:records) { size_d.times.map { |i| double( to_param: i, access: 1000 ) } }
40
- end
41
- it_behaves_like "correct aggregation"
42
- end
43
- end
19
+ before { aggregator.ranking = ranking }
44
20
 
45
- context "sub ranking" do
46
- context "target attribute is score" do
47
- let(:ranking) { double( key: "sample:score", bundled_keys: ["sample:score:1", "sample:score:2"], attribute_name: :score, data?: false ) }
48
- let(:aggregator) { described_class.new }
49
- before do
50
- ranking.stub(:records) { size_d.times.map { |i| double( to_param: i, score: i*10 ) } }
51
- 2.times.each do |i|
52
- ranking.records.each do |record|
53
- @connection.zadd("sample:score:#{i+1}", 20, record.to_param )
54
- end
55
- end
56
- end
57
- it_behaves_like "correct aggregation"
58
- it "has ranking to set all score 40" do
59
- aggregator.ranking = ranking
60
- aggregator.aggregate
61
- @connection.zrange("sample:score", 0, -1).each do |id|
62
- expect(@connection.zscore("sample:score", id)).to eq 40
63
- end
64
- end
65
- end
21
+ it { expect(records.length).to eq size }
22
+ it { expect{ aggregator.aggregate }.not_to raise_error }
23
+ it { expect{ aggregator.aggregate }.to change{ @connection.zcard(key) }.by size }
66
24
 
67
- context "target attribute is access" do
68
- let(:key) { "sample:access" }
69
- let(:bundled_keys) { ["#{key}:1", "#{key}:2"] }
70
- let(:ranking) { double( key: key, bundled_keys: bundled_keys, attribute_name: :access, data?: false ) }
71
- let(:aggregator) { described_class.new }
72
- before do
73
- ranking.stub(:records) { size_d.times.map { |i| double( to_param: i, access: 1000 ) } }
74
- 2.times.each do |i|
75
- ranking.records.each { |record| @connection.zadd("#{key}:#{i+1}", 1000, record.to_param ) }
25
+ describe "for score" do
26
+ before { aggregator.aggregate }
27
+ it { records.each { |record| expect(@connection.zscore(key, record.to_param)).to eq 100 } }
76
28
  end
77
- end
78
- it_behaves_like "correct aggregation"
79
- it "has ranking to set all score 2000" do
80
- aggregator.ranking = ranking
81
- aggregator.aggregate
82
- @connection.zrange("sample:access", 0, -1).each do |id|
83
- expect(@connection.zscore("sample:access", id)).to eq 2000
29
+
30
+ describe "for access" do
31
+ let(:attribute) { :access }
32
+ before { aggregator.aggregate }
33
+ it { records.each { |record| expect(@connection.zscore(key, record.to_param)).to eq (record.to_param+1)*12} }
84
34
  end
85
35
  end
86
36
  end
87
37
  end
88
-
89
- it_behaves_like "ranking cog" do
90
- let(:target) { described_class.new }
91
- end
92
38
  end
@@ -20,12 +20,12 @@ describe Almicube::Config do
20
20
  end
21
21
 
22
22
  context "with default connection" do
23
- before { Redis.should_receive(:new).with( default_param ) }
23
+ before { Redis.should_receive(:new).with( default_param ) { true } }
24
24
  it { described_class.config.connection }
25
25
  end
26
26
 
27
27
  context "with actual connection" do
28
- before { Redis.should_receive(:new).with( development_param ) }
28
+ before { Redis.should_receive(:new).with( development_param ) { true } }
29
29
  it { described_class.config.connection :development }
30
30
  end
31
31
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Almicube::Ranking::Base do
4
4
  describe "#bundled_keys" do
5
- let(:bundler) { double( keys: ["1", "2"] ) }
5
+ let(:bundler) { double( keys: ["1", "2"], :"ranking=" => nil ) }
6
6
  let(:ranking) { described_class.new bundler: bundler }
7
7
  it { expect(ranking.bundled_keys).to eq ["1", "2"] }
8
8
  end
@@ -6,7 +6,7 @@ describe Almicube::Ranking::SubRanking do
6
6
 
7
7
  describe "#key" do
8
8
  let(:ranking) { described_class.new(data_ranking, bundler: bundler) }
9
- let(:bundler) { double( bundle: :bundled ) }
9
+ let(:bundler) { double( bundle: :bundled, :"ranking=" => nil ) }
10
10
 
11
11
  it { expect(ranking.key).not_to match /:data:/ }
12
12
  it { expect(ranking.key).to match /:built:/ }
@@ -15,7 +15,7 @@ describe Almicube::Ranking::SubRanking do
15
15
 
16
16
  describe "#selector" do
17
17
  context "uses optional selector" do
18
- let(:selector) { double( records: [] ) }
18
+ let(:selector) { double( records: [], :"ranking=" => nil ) }
19
19
  let(:ranking) { described_class.new(data_ranking, selector: selector) }
20
20
  it { expect(ranking.selector).to eq selector }
21
21
  end
@@ -27,7 +27,7 @@ describe Almicube::Ranking::SubRanking do
27
27
  end
28
28
 
29
29
  describe "#records" do
30
- let(:selector) { double( records: ["a", "b"] ) }
30
+ let(:selector) { double( records: ["a", "b"], :"ranking=" => nil ) }
31
31
  let(:ranking) { described_class.new(data_ranking, selector: selector) }
32
32
  it { expect(ranking.records).to eq selector.records }
33
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: almicube
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - niaeashes
@@ -82,6 +82,7 @@ files:
82
82
  - Rakefile
83
83
  - almicube.gemspec
84
84
  - lib/almicube.rb
85
+ - lib/almicube/aggregator/avg_aggregator.rb
85
86
  - lib/almicube/aggregator/base.rb
86
87
  - lib/almicube/aggregator/sum_aggregator.rb
87
88
  - lib/almicube/builder.rb