riak-record 0.6.2 → 0.7.0

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: 8285191a3c74c9168e390e57fad2f962d955b000
4
- data.tar.gz: ee1a2c6137828311072a5d7935f8a72765951709
3
+ metadata.gz: 2b0421363c8c40b73b226f4df90f9e45edb430ee
4
+ data.tar.gz: c17740eb834798087876bfbae9002ecf047c5f82
5
5
  SHA512:
6
- metadata.gz: 3e73ef5633ff909a9751fe768bdf0b5732284e1b7180c13b58f46463245d4cb6b3cb321e3e15a0a60452e5cd4f8482b954762b43b075a389350e0c5d61551b8c
7
- data.tar.gz: 8b350e7afbc082ea3941ceaf1cc7b8c6be282448fa845e77519e2d1dac29cb06d81ff64ae193e1064c98dcc99b8d5e44133e7837f93d2244c2118bf97ca34e99
6
+ metadata.gz: c1fe0f01dd8bc344ff488db29d5ed3348b0720633517cdbad944be68cbc15f8d7912419351a9902e11f29353349f579a6559220286167a0d9bef465145f42637
7
+ data.tar.gz: 7057ecd22fd9bae185c3d013b37c2a3ecbb469e0765009edfb6ed9f06add77148d9ea3a721f800b74936300b6faea2998fb510cf988aee73255c4f3bfc2761bd
data/Guardfile CHANGED
@@ -6,6 +6,7 @@ end
6
6
 
7
7
  guard :rspec, cmd: 'bundle exec rspec' do
8
8
  watch(%r{^spec/.+_spec\.rb$})
9
+ watch(%r{^lib/riak_record/finder/.*$}) { "spec/riak_record/finder_spec.rb"}
9
10
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
11
  watch('spec/spec_helper.rb') { "spec" }
11
12
  end
data/README.md CHANGED
@@ -145,6 +145,15 @@ User.find(1).posts #> create RiakRecord::Finder(Post, :user_id => 1)
145
145
  User.find(1).author #> Author.find(self.author_id)
146
146
  ```
147
147
 
148
+ ## Speeding up count, pluck and count_by methods using erlang map reduce functions
149
+
150
+ Compile riak_record_kv_mapreduce.erl and [install it into your riak nodes](http://docs.basho.com/riak/latest/ops/advanced/install-custom-code/).
151
+
152
+ ```ruby
153
+ RiakRecord::Base.finder_class = RiakRecord::Finder::ErlangEnhanced
154
+ ```
155
+
156
+
148
157
  ## Contributing to riak-record
149
158
 
150
159
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.2
1
+ 0.7.0
@@ -108,8 +108,16 @@ module RiakRecord
108
108
  @bucket ||= client.bucket(bucket_name)
109
109
  end
110
110
 
111
+ def self.finder_class=(klass)
112
+ @@finder_class = klass
113
+ end
114
+
115
+ def self.finder_class
116
+ @@finder_class ||= RiakRecord::Finder::Basic
117
+ end
118
+
111
119
  def self.finder
112
- RiakRecord::Finder.new(self, :bucket => bucket_name)
120
+ finder_class.new(self, :bucket => bucket_name)
113
121
  end
114
122
 
115
123
  def self.all
@@ -124,6 +132,7 @@ module RiakRecord
124
132
  finder.first(n)
125
133
  end
126
134
 
135
+ # TODO: this is broke
127
136
  def self.page(page_number = 1, page_size = 100)
128
137
  finder.page(page_number, page_size)
129
138
  end
@@ -173,7 +182,7 @@ module RiakRecord
173
182
  end
174
183
 
175
184
  def self.where(options)
176
- RiakRecord::Finder.new(self, options)
185
+ RiakRecord::Finder::Basic.new(self, options)
177
186
  end
178
187
 
179
188
  def self.find(key_or_keys)
@@ -1,5 +1,6 @@
1
1
  module RiakRecord
2
- class Finder
2
+ module Finder
3
+ class Basic
3
4
  include Enumerable
4
5
 
5
6
  def initialize(finder_class, conditions)
@@ -127,7 +128,7 @@ module RiakRecord
127
128
  Riak::MapReduce.new(@finder_class.client).
128
129
  index(@bucket, @index, @value).
129
130
  map("function(v){ return [1] }", :keep => false).
130
- reduce("Riak.reduceSum", :keep => true).run.first
131
+ reduce(['riak_kv_mapreduce','reduce_sum'], :keep => true).run.first
131
132
  end
132
133
 
133
134
  def load_next_page(page_size = @page_size)
@@ -145,3 +146,4 @@ module RiakRecord
145
146
 
146
147
  end
147
148
  end
149
+ end
@@ -0,0 +1,38 @@
1
+ module RiakRecord
2
+ class Finder::ErlangEnhanced < Finder::Basic
3
+
4
+ def pluck_by_map_reduce(attribute, timeout = nil)
5
+ map_method, map_arg = map_method_for_attribute(attribute, "map_pluck_index", "map_pluck_value")
6
+ mr = Riak::MapReduce.new(@finder_class.client).
7
+ index(@bucket, @index, @value).
8
+ map(['riak_record_kv_mapreduce', map_method], :keep => true, :arg => [map_arg])
9
+ mr.timeout = timeout if timeout.present?
10
+ mr.run
11
+ end
12
+
13
+ private
14
+
15
+ def map_method_for_attribute(attribute, index_method, value_method)
16
+ count_by_index = @finder_class.index_names[attribute.to_sym].present?
17
+ map_method = count_by_index ? index_method : value_method
18
+ map_arg = count_by_index ? @finder_class.index_names[attribute.to_sym] : attribute
19
+ [map_method, map_arg]
20
+ end
21
+
22
+ def count_by_map_reduce(attribute)
23
+ map_method, map_arg = map_method_for_attribute(attribute, "map_count_by_index", "map_count_by_value")
24
+ Riak::MapReduce.new(@finder_class.client).
25
+ index(@bucket, @index, @value).
26
+ map(['riak_record_kv_mapreduce', map_method], :keep => false, :arg => [map_arg]).
27
+ reduce(['riak_record_kv_mapreduce', 'reduce_count_by'], :keep => true).run.first
28
+ end
29
+ end
30
+
31
+ def count_map_reduce
32
+ Riak::MapReduce.new(@finder_class.client).
33
+ index(@bucket, @index, @value).
34
+ map(['riak_record_kv_mapreduce', 'map_count_found'], :keep => false).
35
+ reduce(['riak_kv_mapreduce','reduce_sum'], :keep => true).run.first
36
+ end
37
+
38
+ end
data/lib/riak_record.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'riak_record/callbacks'
2
2
  require 'riak_record/associations'
3
- require 'riak_record/finder'
3
+ require 'riak_record/finder/basic'
4
+ require 'riak_record/finder/erlang_enhanced'
4
5
  require 'riak_record/base'
5
6
 
6
7
  module RiakRecord
@@ -0,0 +1,63 @@
1
+ %% @doc Riak Record's map/reduce phases
2
+ -module(riak_record_kv_mapreduce).
3
+
4
+ -export([map_count_found/3,
5
+ map_pluck_value/3,
6
+ map_pluck_index/3,
7
+ map_count_by_value/3,
8
+ map_count_by_index/3,
9
+ reduce_count_by/2]).
10
+
11
+
12
+
13
+ %% @doc map phase function that returns the count of objects.
14
+ map_count_found({error, notfound}, _, _) ->
15
+ [0];
16
+ map_count_found(_, _, _) ->
17
+ [1].
18
+
19
+ %% @doc map phase function plucks value specified by Arg from the
20
+ %% JSON encoded RiakObject's value.
21
+ map_pluck_value({error, notfound}, _, _) ->
22
+ [];
23
+ map_pluck_value(RiakObject, _Props, Arg) ->
24
+ RiakValue = riak_object:get_value(RiakObject),
25
+ {struct, JsonData} = mochijson2:decode(RiakValue),
26
+ Value = proplists:get_value(list_to_binary(Arg), JsonData),
27
+ [Value].
28
+
29
+ %% @doc map phase function plucks values from the indexes speicied
30
+ %% by Arg from the RiakObject's metadata.
31
+ map_pluck_index({error, notfound}, _, _) ->
32
+ [];
33
+ map_pluck_index(RiakObject, _Props, Arg) ->
34
+ Meta = riak_object:get_metadata(RiakObject),
35
+ Indexes = dict:fetch(<<"index">>, Meta),
36
+ proplists:get_all_values(list_to_binary(Arg), Indexes).
37
+
38
+
39
+ %% dry it up!
40
+ map_count_by_value({error, notfound}, _, _) ->
41
+ [{struct, []}];
42
+ map_count_by_value(RiakObject, _Props, Arg) ->
43
+ RiakValue = riak_object:get_value(RiakObject),
44
+ {struct, JsonData} = mochijson2:decode(RiakValue),
45
+ Value = proplists:get_value(list_to_binary(Arg), JsonData),
46
+ [{struct, [{Value,1}]}].
47
+
48
+ map_count_by_index({error, notfound}, _, _) ->
49
+ [{struct, []}];
50
+ map_count_by_index(RiakObject, _Props, Arg) ->
51
+ Meta = riak_object:get_metadata(RiakObject),
52
+ Indexes = dict:fetch(<<"index">>, Meta),
53
+ IndexValues = proplists:get_all_values(list_to_binary(Arg), Indexes),
54
+ ToTuple = fun(V) -> {V, 1} end,
55
+ [{struct, lists:map(ToTuple, IndexValues)}].
56
+
57
+ reduce_count_by(Values, _Arg) ->
58
+ Sum = fun(_,V1,V2) -> V1 + V2 end,
59
+ Merge = fun(D1,D2) -> orddict:merge(Sum,D1,D2) end,
60
+ ToList = fun(X) -> {struct, L} = X, L end,
61
+ Lists = lists:map(ToList, Values),
62
+ List = lists:foldl(Merge, [], Lists),
63
+ [{struct, List}].
data/riak-record.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: riak-record 0.6.2 ruby lib
5
+ # stub: riak-record 0.7.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "riak-record"
9
- s.version = "0.6.2"
9
+ s.version = "0.7.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Robert Graff"]
14
- s.date = "2014-10-23"
14
+ s.date = "2014-10-27"
15
15
  s.description = "RiakRecord is a thin and immature wrapper around riak-ruby-client. It creates a bucket for\n each class, provides a simple finder, and creates attribute reader."
16
16
  s.email = "robert_graff@yahoo.com"
17
17
  s.extra_rdoc_files = [
@@ -33,8 +33,9 @@ Gem::Specification.new do |s|
33
33
  "lib/riak_record/associations.rb",
34
34
  "lib/riak_record/base.rb",
35
35
  "lib/riak_record/callbacks.rb",
36
- "lib/riak_record/finder.rb",
37
- "riak-record-0.5.0.gem",
36
+ "lib/riak_record/finder/basic.rb",
37
+ "lib/riak_record/finder/erlang_enhanced.rb",
38
+ "map_reduce/riak_record_kv_mapreduce.erl",
38
39
  "riak-record.gemspec",
39
40
  "spec/riak_record/associations_spec.rb",
40
41
  "spec/riak_record/base_spec.rb",
@@ -124,7 +124,7 @@ describe RiakRecord::Associations do
124
124
  @comment_for_other_post.save
125
125
  end
126
126
  it "should return a RiakRecord::Finder" do
127
- expect(post.comments).to be_an_instance_of(RiakRecord::Finder)
127
+ expect(post.comments).to be_an_instance_of(RiakRecord::Finder::Basic)
128
128
  end
129
129
 
130
130
  it "should include the associated records" do
@@ -239,13 +239,13 @@ describe RiakRecord::Base do
239
239
 
240
240
  describe "where" do
241
241
  it "should return an instance of RiakRecord::Finder" do
242
- expect( ExampleA.where(:index1 => 'hello') ).to be_an_instance_of(RiakRecord::Finder)
242
+ expect( ExampleA.where(:index1 => 'hello') ).to be_an_instance_of(RiakRecord::Finder::Basic)
243
243
  end
244
244
  end
245
245
 
246
246
  describe "finder" do
247
247
  it "should return a finder for the bucket" do
248
- expect( ExampleB.finder ).to be_an_instance_of(RiakRecord::Finder)
248
+ expect( ExampleB.finder ).to be_an_instance_of(RiakRecord::Finder::Basic)
249
249
  end
250
250
 
251
251
  describe "uses of class finder" do
@@ -254,7 +254,7 @@ describe RiakRecord::Base do
254
254
 
255
255
  describe "all" do
256
256
  it "should return all the objects in the bucket" do
257
- expect(ExampleB.all).to eq [record1, record2]
257
+ expect(ExampleB.all).to include(record1, record2)
258
258
  end
259
259
  end
260
260
 
@@ -8,8 +8,10 @@ class Artist < RiakRecord::Base
8
8
  index_bin_attributes :category
9
9
  end
10
10
 
11
- describe RiakRecord::Finder do
11
+ RSpec.shared_examples "riak_record_finder" do
12
12
  before :each do
13
+ RiakRecord::Base.finder_class = described_class
14
+
13
15
  @pop_artists = Array(1..155).map do |c|
14
16
  a = Artist.new(c.to_s)
15
17
  a.name = "Pop Artist #{c}"
@@ -29,8 +31,8 @@ describe RiakRecord::Finder do
29
31
  end
30
32
  end
31
33
 
32
- let(:pop_finder){ RiakRecord::Finder.new(Artist, :category => 'pop') }
33
- let(:country_finder){ RiakRecord::Finder.new(Artist, :category => 'country') }
34
+ let(:pop_finder){ described_class.new(Artist, :category => 'pop') }
35
+ let(:country_finder){ described_class.new(Artist, :category => 'country') }
34
36
 
35
37
  describe "all" do
36
38
 
@@ -197,3 +199,11 @@ describe RiakRecord::Finder do
197
199
  end
198
200
 
199
201
  end
202
+
203
+ describe RiakRecord::Finder::Basic do
204
+ it_behaves_like "riak_record_finder"
205
+ end
206
+
207
+ describe RiakRecord::Finder::ErlangEnhanced do
208
+ it_behaves_like "riak_record_finder"
209
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riak-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Graff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-23 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riak-client
@@ -160,8 +160,9 @@ files:
160
160
  - lib/riak_record/associations.rb
161
161
  - lib/riak_record/base.rb
162
162
  - lib/riak_record/callbacks.rb
163
- - lib/riak_record/finder.rb
164
- - riak-record-0.5.0.gem
163
+ - lib/riak_record/finder/basic.rb
164
+ - lib/riak_record/finder/erlang_enhanced.rb
165
+ - map_reduce/riak_record_kv_mapreduce.erl
165
166
  - riak-record.gemspec
166
167
  - spec/riak_record/associations_spec.rb
167
168
  - spec/riak_record/base_spec.rb
Binary file