campchair 0.1.1 → 0.2.0
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 +7 -0
- data/Gemfile +1 -1
- data/README.md +24 -196
- data/Rakefile +2 -5
- data/campchair.gemspec +5 -6
- data/lib/campchair.rb +0 -1
- data/lib/campchair/version.rb +3 -1
- metadata +19 -30
- data/lib/campchair/views.rb +0 -4
- data/spec/campchair/views_spec.rb +0 -4
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 40f0f2322fed1bd3467b787b7d2ecdb3b924b0a1
|
4
|
+
data.tar.gz: ad56fcf4e38d1b375d480537412f48d060677fda
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4f83f7ce711c607e35909abbf04d1803e6953b5be15dd4ec93dcb74afc29c8fa83aef9aa657adfb740eee8597580d66994c4e6049dcac093d03bd380b569f8ba
|
7
|
+
data.tar.gz: b160dab7ad0c2d1508ed027ff6d4f8b7a22f62dd691d521604d5d1779c35b29034e66508316b90b4784c51e8c8451912dd2b8d663aa5dfd9e6699c8f34074439
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# ⑁ Campchair
|
2
|
-
### A fast
|
2
|
+
### A fast LevelDB object-persistence layer for Ruby
|
3
3
|
|
4
4
|
[](http://travis-ci.org/captainpete/campchair)
|
5
5
|
|
@@ -9,16 +9,27 @@ Campchair provides some helpers for lazily materialized views,
|
|
9
9
|
and gives you a choice of using ActiveRecord-like models
|
10
10
|
or class-based, barebones data-structure access.
|
11
11
|
|
12
|
-
|
13
|
-
Campchair is not a service and has no client-server stuff.
|
14
|
-
Parallel access is not supported yet, but that's okay – you can use something
|
15
|
-
else for concurrency and use this in your persistence fiber/thread/process.
|
16
|
-
|
17
|
-
Persistence happens through [LevelDB](http://code.google.com/p/leveldb/).
|
12
|
+
Persistence happens with [LevelDB](http://code.google.com/p/leveldb/).
|
18
13
|
Objects are serialized into documents using Ruby's Marshal class.
|
19
|
-
|
14
|
+
|
15
|
+
### Update 2014-04
|
20
16
|
|
21
17
|
This project was born at [Railscamp 11](http://railscamps.com/).
|
18
|
+
Then I forgot about it, and in the interim learned a lot more about concurrent programming, to the point where I'd like to revive this project but would need to change nearly everything about it!
|
19
|
+
|
20
|
+
I'm sure you've been there...
|
21
|
+
|
22
|
+
### Dependencies
|
23
|
+
|
24
|
+
- Needs `leveldb` libraries `brew install leveldb`
|
25
|
+
- Needs Ruby ;)
|
26
|
+
|
27
|
+
### Current Limitations
|
28
|
+
|
29
|
+
- This is not append-only and replication is not a feature.
|
30
|
+
- There is no concurrent access.
|
31
|
+
- There are no transactions.
|
32
|
+
- There is no promise pipeline.
|
22
33
|
|
23
34
|
### As a basic data structure store
|
24
35
|
|
@@ -106,188 +117,6 @@ fred.save
|
|
106
117
|
People[fred.key] # => { :favourite_colour => 'LSD' }
|
107
118
|
```
|
108
119
|
|
109
|
-
### Basic views _not yet implemented_
|
110
|
-
|
111
|
-
For views to be available on classes we need to include `Campchair::Views`.
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
class People # add some views to the people class
|
115
|
-
include Campchair::Views
|
116
|
-
|
117
|
-
# Map to document by id
|
118
|
-
view :all do
|
119
|
-
map { |id, person| emit id, person }
|
120
|
-
end
|
121
|
-
|
122
|
-
# Map to name by doc id
|
123
|
-
view :names do
|
124
|
-
map { |id, person| emit id, person.name }
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
People.names
|
129
|
-
# ['Fred', 'Jane']
|
130
|
-
```
|
131
|
-
|
132
|
-
### Using reduce _not yet implemented_
|
133
|
-
|
134
|
-
Reduce gets called on groups of map results.
|
135
|
-
|
136
|
-
```ruby
|
137
|
-
class People
|
138
|
-
# Map to count by doc id
|
139
|
-
# Reduce to sum of counts
|
140
|
-
view :count do
|
141
|
-
map { |id, person| emit id, 1 }
|
142
|
-
reduce do |keys, values|
|
143
|
-
values.inject(0) { |memo, values| memo + values }
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
People.count
|
149
|
-
# 2
|
150
|
-
```
|
151
|
-
|
152
|
-
Reduce happens in stages. Supply a rereduce step to handle reducing reduce
|
153
|
-
results. The advantage of rereduce is results can be cached in a b-tree index.
|
154
|
-
|
155
|
-
If `rereduce` is supplied then `reduce` is called with a portion of the `map`
|
156
|
-
results and those reductions are passed to `rereduce`. If `rereduce` is
|
157
|
-
omitted then `reduce` results will not be cached.
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
class People
|
161
|
-
# Map to location by doc id
|
162
|
-
# Reduce by unique location
|
163
|
-
view :unique_locations do
|
164
|
-
map { |id, person| emit id, person.location }
|
165
|
-
reduce do |keys, values|
|
166
|
-
results = values.uniq
|
167
|
-
end
|
168
|
-
rereduce do |results|
|
169
|
-
results.inject(Set.new) { |memo, values| memo.merge values }
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
People.unique_locations
|
175
|
-
# <Set: {"Flinders St Station, Melbourne, Australia"}>
|
176
|
-
```
|
177
|
-
|
178
|
-
Keep in mind that if `rereduce` is not supplied, `reduce` will always get
|
179
|
-
called with the entire keyspace. If the dataset is large this might consume a
|
180
|
-
lot of memory.
|
181
|
-
|
182
|
-
### Using keys with reduce _not yet implemented_
|
183
|
-
|
184
|
-
```ruby
|
185
|
-
class People
|
186
|
-
# Map to count by name
|
187
|
-
# Reduce by sum of counts
|
188
|
-
view :count_by_name do
|
189
|
-
map { |id, person| emit name, 1 }
|
190
|
-
reduce do |keys, values|
|
191
|
-
values.inject(0) { |memo, value| memo + value }
|
192
|
-
end
|
193
|
-
rereduce do |results|
|
194
|
-
results.inject(0) { |memo, value| memo + value }
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
People.count_by_name['Jane']
|
200
|
-
# 1
|
201
|
-
People.count_by_name
|
202
|
-
# 2
|
203
|
-
```
|
204
|
-
|
205
|
-
### Controlling the index _not yet relevant_
|
206
|
-
|
207
|
-
It's possible to write reduce methods that return results larger than the
|
208
|
-
input. If you're doing this, you're gonna have a bad time. Unless you're sure
|
209
|
-
the dataset will remain small enough that the index for each `rereduce` doesn't
|
210
|
-
blow out your disk store.
|
211
|
-
|
212
|
-
```ruby
|
213
|
-
class People
|
214
|
-
# DANGER: this view will blow out the index
|
215
|
-
|
216
|
-
# Map to count by name
|
217
|
-
# Reduce by sum of counts by name
|
218
|
-
view :count_all_by_name do
|
219
|
-
map { |id, person| emit person.name, 1 }
|
220
|
-
reduce do |keys, values|
|
221
|
-
result = Hash.new
|
222
|
-
keys.each_with_index do |key, index|
|
223
|
-
result[key] ||= 0
|
224
|
-
result[key] += values[index]
|
225
|
-
end
|
226
|
-
result # scary, nearly as large as the input
|
227
|
-
end
|
228
|
-
rereduce(:cache => false) do |results|
|
229
|
-
result = {}
|
230
|
-
results.each do |name, count|
|
231
|
-
result[name] ||= 0
|
232
|
-
result[name] += count
|
233
|
-
end
|
234
|
-
result # likewise, this will explode the index
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
People.count_all_by_name['Jane']
|
240
|
-
# { 'Jane' => 1 }
|
241
|
-
People.count_all_by_name
|
242
|
-
# { 'Fred' => 1, 'Jane' => 1 }
|
243
|
-
```
|
244
|
-
|
245
|
-
### Re-re-reducing _not yet implemented_
|
246
|
-
|
247
|
-
Sometimes it's useful to post-process reduce results. Add another rereduce to
|
248
|
-
process rereduced values. Only the first rereduce gets called on values it
|
249
|
-
produces itself. Subsequent rereduces are chained to the initial result.
|
250
|
-
|
251
|
-
```ruby
|
252
|
-
clas People
|
253
|
-
# Map to height by location
|
254
|
-
# Reduce by count and sum of heights
|
255
|
-
# Rereduce by the calculating average
|
256
|
-
view :average_height_by_location do
|
257
|
-
map { |id, person| emit location, height }
|
258
|
-
reduce do |keys, values|
|
259
|
-
result = Hash.new
|
260
|
-
keys.each_with_index do |key, index|
|
261
|
-
result[key] ||= { :count => 0, :sum => 0 }
|
262
|
-
result[key][:count] += 1
|
263
|
-
result[key][:sum] += height
|
264
|
-
end
|
265
|
-
result
|
266
|
-
end
|
267
|
-
rereduce do |results|
|
268
|
-
result = { :count => 0, :sum => 0 }
|
269
|
-
results.each do |result|
|
270
|
-
result[:count] += part[:count]
|
271
|
-
result[:sum] += part[:sum]
|
272
|
-
end
|
273
|
-
result
|
274
|
-
end
|
275
|
-
rereduce do |results|
|
276
|
-
count = results.inject(0) { |memo, result| result[:count] }
|
277
|
-
sum = results.inject(0) { |memo, result| result[:sum] }
|
278
|
-
count == 0 ? nil : sum / count
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
People.average_height_by_location
|
284
|
-
# 1.690999999
|
285
|
-
People.average_height_by_location['Flinders St Station, Melbourne, Australia']
|
286
|
-
# 1.690999999
|
287
|
-
People.average_height_by_location['Docklands, Melbourne, Australia']
|
288
|
-
# nil
|
289
|
-
```
|
290
|
-
|
291
120
|
### Custom database path
|
292
121
|
|
293
122
|
By default, the folder for db files is 'cddb'.
|
@@ -306,9 +135,8 @@ end
|
|
306
135
|
|
307
136
|
### TODO
|
308
137
|
|
309
|
-
-
|
310
|
-
-
|
311
|
-
-
|
312
|
-
-
|
313
|
-
|
314
|
-
- cache priming
|
138
|
+
- Transactions
|
139
|
+
- Portable Promise Pipelines
|
140
|
+
- Transforms
|
141
|
+
- Cache invalidation / Bindings
|
142
|
+
|
data/Rakefile
CHANGED
data/campchair.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Peter Hollows"]
|
9
9
|
s.email = ["pete@dojo7.com"]
|
10
10
|
s.homepage = "https://github.com/captainpete/campchair"
|
11
|
-
s.summary = %q{A fast
|
12
|
-
s.description = %q{Campchair is
|
11
|
+
s.summary = %q{A fast LevelDB object-persistence layer for Ruby}
|
12
|
+
s.description = %q{Campchair is simple persistence mixin using LevelDB and Marshal to persist Ruby objects.}
|
13
13
|
|
14
14
|
s.rubyforge_project = "campchair"
|
15
15
|
|
@@ -18,8 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency
|
22
|
-
|
23
|
-
s.add_development_dependency
|
24
|
-
s.add_development_dependency %q<rake>, ["~> 10.0.0"]
|
21
|
+
s.add_dependency 'leveldb-ruby', '~> 0.14'
|
22
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
23
|
+
s.add_development_dependency 'rake', '~> 10.0.0'
|
25
24
|
end
|
data/lib/campchair.rb
CHANGED
data/lib/campchair/version.rb
CHANGED
metadata
CHANGED
@@ -1,75 +1,68 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: campchair
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Peter Hollows
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-04-24 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: leveldb-ruby
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0.14'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0.14'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 2.12.0
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 2.12.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 10.0.0
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 10.0.0
|
62
|
-
description: Campchair is
|
63
|
-
Ruby
|
55
|
+
description: Campchair is simple persistence mixin using LevelDB and Marshal to persist
|
56
|
+
Ruby objects.
|
64
57
|
email:
|
65
58
|
- pete@dojo7.com
|
66
59
|
executables: []
|
67
60
|
extensions: []
|
68
61
|
extra_rdoc_files: []
|
69
62
|
files:
|
70
|
-
- .gitignore
|
71
|
-
- .rspec
|
72
|
-
- .travis.yml
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
73
66
|
- Gemfile
|
74
67
|
- README.md
|
75
68
|
- Rakefile
|
@@ -78,43 +71,39 @@ files:
|
|
78
71
|
- lib/campchair/model.rb
|
79
72
|
- lib/campchair/store.rb
|
80
73
|
- lib/campchair/version.rb
|
81
|
-
- lib/campchair/views.rb
|
82
74
|
- spec/.gitkeep
|
83
75
|
- spec/campchair/model_spec.rb
|
84
76
|
- spec/campchair/store_spec.rb
|
85
|
-
- spec/campchair/views_spec.rb
|
86
77
|
- spec/campchair_spec.rb
|
87
78
|
- spec/integration/readme_examples_spec.rb
|
88
79
|
- spec/spec_helper.rb
|
89
80
|
- tmp/.gitkeep
|
90
81
|
homepage: https://github.com/captainpete/campchair
|
91
82
|
licenses: []
|
83
|
+
metadata: {}
|
92
84
|
post_install_message:
|
93
85
|
rdoc_options: []
|
94
86
|
require_paths:
|
95
87
|
- lib
|
96
88
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
89
|
requirements:
|
99
|
-
- -
|
90
|
+
- - ">="
|
100
91
|
- !ruby/object:Gem::Version
|
101
92
|
version: '0'
|
102
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
-
none: false
|
104
94
|
requirements:
|
105
|
-
- -
|
95
|
+
- - ">="
|
106
96
|
- !ruby/object:Gem::Version
|
107
97
|
version: '0'
|
108
98
|
requirements: []
|
109
99
|
rubyforge_project: campchair
|
110
|
-
rubygems_version:
|
100
|
+
rubygems_version: 2.2.2
|
111
101
|
signing_key:
|
112
|
-
specification_version:
|
113
|
-
summary: A fast
|
102
|
+
specification_version: 4
|
103
|
+
summary: A fast LevelDB object-persistence layer for Ruby
|
114
104
|
test_files:
|
115
105
|
- spec/campchair/model_spec.rb
|
116
106
|
- spec/campchair/store_spec.rb
|
117
|
-
- spec/campchair/views_spec.rb
|
118
107
|
- spec/campchair_spec.rb
|
119
108
|
- spec/integration/readme_examples_spec.rb
|
120
109
|
- spec/spec_helper.rb
|
data/lib/campchair/views.rb
DELETED