tupelo 0.16 → 0.17

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.
@@ -0,0 +1,123 @@
1
+ require 'rbtree' # gem install rbtree
2
+ require 'set'
3
+ require 'digest/md5'
4
+
5
+ # An implementation of consistent hashing
6
+ # (https://en.wikipedia.org/wiki/Consistent_hashing) using a circular structure
7
+ # of bins.
8
+ #
9
+ # Synopsis:
10
+ #
11
+ # circle = BinCircle.new reps: 20
12
+ #
13
+ # 100.times do |id|
14
+ # circle.add_bin id
15
+ # end
16
+ #
17
+ # circle.find_bin "foo"
18
+ #
19
+ # The #find_bin method determines which bin a given object is associated with.
20
+ # For example: use it to look up which distributed cache the object is stored
21
+ # in.
22
+ #
23
+ # BinCircle Does not store or cache any data. The state of a BinCircle instance
24
+ # depends entirely on two things: the replications number (either passed to
25
+ # BinCircle#new or set per bin in #add_bin), and the current set of bins, which
26
+ # is managed with #add_bin and #delete_bin. Note: like rbtree, not thread-safe
27
+ # (for #delete and #show_bins).
28
+ class BinCircle
29
+ KEY_BITS = 30
30
+ KEY_MAX = 2**KEY_BITS - 1
31
+ DEFAULT_REPS = 10
32
+
33
+ attr_accessor :default_reps
34
+
35
+ def initialize reps: DEFAULT_REPS
36
+ @tree = MultiRBTree.new # hashed_bin_id => bin_id
37
+ @default_reps = reps
38
+ end
39
+
40
+ # +id+ should be an identifier for your bin, typically a number or string.
41
+ # Uses id.to_s, so +id+ should not contain a hash (which would not determine
42
+ # a unique string).
43
+ def add_bin id, reps: default_reps
44
+ rep_id = "#{id} 0000"
45
+ reps.times do |i|
46
+ key = key_for_string(rep_id)
47
+ @tree[key] = id
48
+ rep_id.succ!
49
+ end
50
+ end
51
+
52
+ # Returns the set of bin ids now in the circle.
53
+ def bins
54
+ Set.new @tree.values
55
+ end
56
+
57
+ def inspect
58
+ "#<#{self.class} bins=#{bins.to_a}>"
59
+ end
60
+
61
+ # This hashing fn is applied to both bin ids and object identifiers (in
62
+ # principle, these could be two different function with the same range of
63
+ # outputs.
64
+ def key_for_string str
65
+ Digest::MD5.hexdigest(str).to_i(16) & KEY_MAX
66
+ end
67
+
68
+ # Delete the bin specified by +id+ (same as argument to #add_bin).
69
+ def delete_bin id
70
+ @tree.delete_if {|k,v| v == id}
71
+ end
72
+
73
+ # +id+ should be an identifier for your object, typically a number or string.
74
+ # Uses id.to_s, so +id+ should not contain a hash (which would not determine
75
+ # a unique string). It is not necessary for +id+ to be unique across objects.
76
+ def find_bin obj
77
+ find_bin_by_key(key_for_string(obj.to_s))
78
+ end
79
+
80
+ def find_bin_by_key key
81
+ _, id = @tree.lower_bound(key) || @tree.first
82
+ id
83
+ end
84
+
85
+ def bin_size
86
+ Hash.new(0).tap do |bs|
87
+ bs[@tree.first[1]] = 2**30 - @tree.last[0] + @tree.first[0]
88
+ @tree.each_cons(2) do |(prev, _), (key, id)|
89
+ bs[id] += key - prev
90
+ end
91
+ end
92
+ end
93
+
94
+ # To help in tuning the replication counts, you can look at the
95
+ # distribution of bin sizes, plus mean and variance.
96
+ def show_bins
97
+ bs = bin_size
98
+ p bs
99
+
100
+ mean = bs.inject(0.0) {|sum, (id,n)| sum + n} / N_BINS
101
+ variance = bs.inject(0.0) {|sum_sqerr, (id,n)|
102
+ sum_sqerr + (n - mean)**2} / (N_BINS-1)
103
+ printf "mean : %14d\n" % mean
104
+ printf "stdev: %14d\n" % Math.sqrt(variance)
105
+ end
106
+ end
107
+
108
+ if __FILE__ == $0
109
+ N_BINS = 100
110
+ N_REPS = 20
111
+
112
+ circle = BinCircle.new reps: N_REPS
113
+
114
+ N_BINS.times do |id|
115
+ circle.add_bin id
116
+ end
117
+
118
+ p circle
119
+ circle.show_bins
120
+
121
+ p circle.find_bin "foo"
122
+ p circle.find_bin "bar"
123
+ end
@@ -1,3 +1,3 @@
1
1
  module Tupelo
2
- VERSION = "0.16"
2
+ VERSION = "0.17"
3
3
  end
metadata CHANGED
@@ -1,72 +1,73 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tupelo
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.16'
4
+ version: '0.17'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel VanderWerf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-22 00:00:00.000000000 Z
11
+ date: 2014-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: atdo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: easy-serve
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: funl
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: object-template
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: Distributed tuplespace.
69
+ description: A distributed, transactional tuplespace for polyglot computation and
70
+ storage.
70
71
  email: vjoel@users.sourceforge.net
71
72
  executables:
72
73
  - tup
@@ -76,130 +77,133 @@ extra_rdoc_files:
76
77
  - README.md
77
78
  - COPYING
78
79
  files:
79
- - README.md
80
80
  - COPYING
81
+ - README.md
81
82
  - Rakefile
82
- - lib/tupelo/app/remote.rb
83
- - lib/tupelo/app/irb-shell.rb
84
- - lib/tupelo/app/trace.rb
85
- - lib/tupelo/app/builder.rb
86
- - lib/tupelo/client.rb
87
- - lib/tupelo/tuplets/persistent-archiver.rb
88
- - lib/tupelo/tuplets/persistent-archiver/worker.rb
89
- - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
90
- - lib/tupelo/util/boolean.rb
91
- - lib/tupelo/app.rb
92
- - lib/tupelo/archiver.rb
93
- - lib/tupelo/archiver/persister.rb
94
- - lib/tupelo/archiver/worker.rb
95
- - lib/tupelo/archiver/tuplespace.rb
96
- - lib/tupelo/archiver/persistent-tuplespace.rb
97
- - lib/tupelo/client/transaction.rb
98
- - lib/tupelo/client/worker.rb
99
- - lib/tupelo/client/reader.rb
100
- - lib/tupelo/client/tuplespace.rb
101
- - lib/tupelo/client/atdo.rb
102
- - lib/tupelo/client/common.rb
103
- - lib/tupelo/version.rb
104
83
  - bench/pipeline.rb
84
+ - bin/tspy
85
+ - bin/tup
105
86
  - bugs/read-take.rb
106
87
  - bugs/take-write.rb
107
- - example/timeout.rb
108
88
  - example/add-dsl.rb
109
- - example/remote.rb
110
- - example/increment.rb
111
- - example/matching.rb
112
- - example/dphil.rb
89
+ - example/add.rb
90
+ - example/app-and-tup.rb
91
+ - example/async-transaction.rb
92
+ - example/balance-xfer-locking.rb
93
+ - example/balance-xfer-retry.rb
94
+ - example/balance-xfer.rb
95
+ - example/boolean-match.rb
96
+ - example/bounded-retry.rb
97
+ - example/broker-locking.rb
98
+ - example/broker-optimistic-v2.rb
113
99
  - example/broker-optimistic.rb
100
+ - example/cancel.rb
101
+ - example/chat/chat-nohistory.rb
102
+ - example/chat/chat.rb
103
+ - example/concurrent-transactions.rb
104
+ - example/consistent-hash.rb
105
+ - example/custom-class.rb
106
+ - example/custom-search.rb
107
+ - example/deadlock.rb
108
+ - example/dphil-optimistic-v2.rb
109
+ - example/dphil-optimistic.rb
110
+ - example/dphil.rb
114
111
  - example/fail-and-retry.rb
112
+ - example/hash-tuples.rb
113
+ - example/increment.rb
114
+ - example/lease.rb
115
115
  - example/load-balancer.rb
116
- - example/read-in-trans.rb
117
- - example/bounded-retry.rb
118
- - example/pregel/remote.rb
116
+ - example/lock-mgr-with-queue.rb
117
+ - example/lock-mgr.rb
118
+ - example/map-reduce/map-reduce-v2.rb
119
+ - example/map-reduce/map-reduce.rb
120
+ - example/map-reduce/prime-factor-balanced.rb
121
+ - example/map-reduce/prime-factor.rb
122
+ - example/map-reduce/remote-map-reduce.rb
123
+ - example/matching.rb
124
+ - example/message-bus.rb
125
+ - example/multi-tier/drb.rb
126
+ - example/multi-tier/http.rb
127
+ - example/multi-tier/kvspace.rb
128
+ - example/multi-tier/memo.rb
129
+ - example/multi-tier/memo2.rb
130
+ - example/multi-tier/multi-sinatras.rb
131
+ - example/notify.rb
132
+ - example/optimist.rb
133
+ - example/parallel.rb
134
+ - example/pregel/distributed.rb
119
135
  - example/pregel/pagerank.rb
120
136
  - example/pregel/pregel.rb
121
- - example/pregel/distributed.rb
137
+ - example/pregel/remote.rb
122
138
  - example/pregel/update.rb
123
- - example/take-nowait.rb
124
- - example/boolean-match.rb
125
- - example/lease.rb
126
- - example/broker-locking.rb
127
- - example/transaction-logic.rb
128
- - example/message-bus.rb
139
+ - example/pubsub.rb
140
+ - example/pulse.rb
141
+ - example/read-in-trans.rb
142
+ - example/remote.rb
129
143
  - example/small-simplified.rb
130
144
  - example/small.rb
131
- - example/lock-mgr.rb
132
- - example/take-nowait-caution.rb
133
- - example/concurrent-transactions.rb
134
- - example/tcp.rb
135
- - example/notify.rb
136
- - example/pulse.rb
137
- - example/chat/chat.rb
138
- - example/chat/chat-nohistory.rb
139
- - example/hash-tuples.rb
140
- - example/balance-xfer-locking.rb
141
- - example/balance-xfer-retry.rb
142
- - example/custom-search.rb
143
- - example/app-and-tup.rb
144
- - example/multi-tier/memo2.rb
145
- - example/multi-tier/http.rb
146
- - example/multi-tier/multi-sinatras.rb
147
- - example/multi-tier/kvspace.rb
148
- - example/multi-tier/memo.rb
149
- - example/multi-tier/drb.rb
150
- - example/take-many.rb
151
- - example/subspaces/ramp.rb
152
- - example/subspaces/sorted-set-space.rb
145
+ - example/socket-broker.rb
146
+ - example/subspaces/addr-book-v2.rb
153
147
  - example/subspaces/addr-book.rb
154
- - example/subspaces/simple.rb
155
- - example/subspaces/shop/shop-v2.rb
156
- - example/subspaces/shop/shop-v1.rb
157
148
  - example/subspaces/pubsub.rb
158
- - example/subspaces/addr-book-v2.rb
159
- - example/dphil-optimistic.rb
160
- - example/async-transaction.rb
161
- - example/wait-interrupt.rb
162
- - example/fish0.rb
163
- - example/zk/lock.rb
164
- - example/deadlock.rb
165
- - example/fish.rb
166
- - example/add.rb
167
- - example/dphil-optimistic-v2.rb
168
- - example/tiny-service.rb
169
- - example/parallel.rb
170
- - example/tiny-client.rb
171
- - example/map-reduce/map-reduce.rb
172
- - example/map-reduce/remote-map-reduce.rb
173
- - example/map-reduce/map-reduce-v2.rb
174
- - example/map-reduce/prime-factor.rb
175
- - example/map-reduce/mr.rb
176
- - example/map-reduce/prime-factor-balanced.rb
177
- - example/lock-mgr-with-queue.rb
178
- - example/balance-xfer.rb
179
- - example/cancel.rb
180
- - example/socket-broker.rb
149
+ - example/subspaces/ramp.rb
150
+ - example/subspaces/shop/shop-v1.rb
151
+ - example/subspaces/shop/shop-v2.rb
152
+ - example/subspaces/simple.rb
153
+ - example/subspaces/sorted-set-space.rb
154
+ - example/take-many.rb
155
+ - example/take-nowait-caution.rb
156
+ - example/take-nowait.rb
157
+ - example/tcp.rb
181
158
  - example/timeout-trans.rb
159
+ - example/timeout.rb
160
+ - example/tiny-client.rb
161
+ - example/tiny-service.rb
162
+ - example/transaction-logic.rb
182
163
  - example/uniq-id.rb
183
- - example/optimist.rb
184
- - example/pubsub.rb
185
- - example/broker-optimistic-v2.rb
164
+ - example/wait-interrupt.rb
165
+ - example/wip/fish.rb
166
+ - example/wip/fish1.rb
167
+ - example/wip/fish2.rb
186
168
  - example/write-wait.rb
187
- - example/custom-class.rb
188
- - test/stress/archiver-load.rb
189
- - test/stress/concurrent-transactions.rb
190
- - test/system/test-archiver.rb
169
+ - example/zk/lock.rb
170
+ - lib/tupelo/app.rb
171
+ - lib/tupelo/app/builder.rb
172
+ - lib/tupelo/app/irb-shell.rb
173
+ - lib/tupelo/app/remote.rb
174
+ - lib/tupelo/app/trace.rb
175
+ - lib/tupelo/archiver.rb
176
+ - lib/tupelo/archiver/persistent-tuplespace.rb
177
+ - lib/tupelo/archiver/persister.rb
178
+ - lib/tupelo/archiver/tuplespace.rb
179
+ - lib/tupelo/archiver/worker.rb
180
+ - lib/tupelo/client.rb
181
+ - lib/tupelo/client/atdo.rb
182
+ - lib/tupelo/client/common.rb
183
+ - lib/tupelo/client/reader.rb
184
+ - lib/tupelo/client/subspace.rb
185
+ - lib/tupelo/client/transaction.rb
186
+ - lib/tupelo/client/tuplespace.rb
187
+ - lib/tupelo/client/worker.rb
188
+ - lib/tupelo/tuplets/persistent-archiver.rb
189
+ - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
190
+ - lib/tupelo/tuplets/persistent-archiver/worker.rb
191
+ - lib/tupelo/util/bin-circle.rb
192
+ - lib/tupelo/util/boolean.rb
193
+ - lib/tupelo/version.rb
191
194
  - test/lib/mock-client.rb
192
- - test/lib/time-fuzz.rb
195
+ - test/lib/mock-msg.rb
193
196
  - test/lib/mock-queue.rb
194
197
  - test/lib/mock-seq.rb
195
198
  - test/lib/testable-worker.rb
196
- - test/lib/mock-msg.rb
197
- - test/unit/test-mock-seq.rb
199
+ - test/lib/time-fuzz.rb
200
+ - test/stress/archiver-load.rb
201
+ - test/stress/concurrent-transactions.rb
202
+ - test/system/test-archiver.rb
203
+ - test/unit/test-mock-client.rb
198
204
  - test/unit/test-mock-queue.rb
205
+ - test/unit/test-mock-seq.rb
199
206
  - test/unit/test-ops.rb
200
- - test/unit/test-mock-client.rb
201
- - bin/tup
202
- - bin/tspy
203
207
  homepage: https://github.com/vjoel/tupelo
204
208
  licenses:
205
209
  - BSD
@@ -227,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
231
  version: '0'
228
232
  requirements: []
229
233
  rubyforge_project:
230
- rubygems_version: 2.1.11
234
+ rubygems_version: 2.2.1
231
235
  signing_key:
232
236
  specification_version: 4
233
237
  summary: Distributed tuplespace
@@ -1,61 +0,0 @@
1
- # see also ../parallel.rb and ../remote.rb
2
-
3
- #require 'tupelo/app'
4
- #require 'tupelo/app/remote'
5
- require 'easy-serve/remote'
6
-
7
- tunnel = !!ARGV.delete("--tunnel")
8
- host = ARGV.shift
9
-
10
- #Tupelo.tcp_application do
11
- ## This is fine:
12
- ## ez.remote host: host, tunnel: tunnel, eval: %{
13
- ## }
14
- #
15
- ## These break:
16
- #
17
- # ez.remote :seqd, :cseqd, host: host, tunnel: tunnel, log: true, eval: %{
18
- # require 'funl/client'
19
- #
20
- # log.progname = "client <starting>"
21
- #
22
- # seqd, cseqd = conns
23
- # client = Funl::Client.new(seq: seqd, cseq: cseqd, log: log)
24
- # client.cseq_read_client_id
25
- # }
26
- #
27
- ## remote host: host, tunnel: tunnel, eval: %{
28
- ## }
29
- #end
30
-
31
- EasyServe.start do |ez|
32
- log = ez.log
33
- log.level = Logger::INFO
34
- log.progname = File.basename($0)
35
-
36
- ez.start_servers do
37
- svhost = tunnel ? "localhost" : nil # no need to expose port if tunnelled
38
-
39
- ez.server :seqd, :tcp, svhost, 0 do |svr|
40
- require 'funl/message-sequencer'
41
- seq = Funl::MessageSequencer.new svr, log: log
42
- seq.start
43
- end
44
-
45
- ez.server :cseqd, :tcp, svhost, 0 do |svr|
46
- require 'funl/client-sequencer'
47
- cseq = Funl::ClientSequencer.new svr, log: log
48
- cseq.start
49
- end
50
- end
51
-
52
- ez.remote :seqd, :cseqd, host: host, tunnel: tunnel, log: true, eval: %{
53
- require 'funl/client'
54
-
55
- log.progname = "client <starting>"
56
-
57
- seqd, cseqd = conns
58
- client = Funl::Client.new(seq: seqd, cseq: cseqd, log: log)
59
- client.cseq_read_client_id
60
- }
61
- end