almicube 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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