drip 0.1.0 → 0.1.1

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
- SHA1:
3
- metadata.gz: 7fe0e76a3ce8cc23242eba6e08c6800eebbfbe18
4
- data.tar.gz: fd19e70695e3da3b1ec9cccd4494d0209865285e
2
+ SHA256:
3
+ metadata.gz: ccc378c36cdf4c16d9f69116b4921264a81c861ed30fd27453ed6c52f257b03c
4
+ data.tar.gz: 1f9f813e80c22eb8788289b79e59ed53e96e70fe32d6c572cc905274a3906441
5
5
  SHA512:
6
- metadata.gz: 6b7fd18f94adc3263e4523fdd000ba77904201745daf725a9f6a9f8469c92b0d6382a23ebc7ebe0739599327578d559787691e948ad151223e8270db1ab0e817
7
- data.tar.gz: 15a8fbf484bbcd9e19b29d945fba8c6ac4472711b417ad5394d7e787d5de04c83beb0ce269f16ecedfeffd46f7681101ffc94657035bc18160e14e4dbf18925e
6
+ metadata.gz: '038ac25011da60f555b56a65b69060befe154f938263a0cb3cbd541324cee6841d2a7cf482b1b1b3027152fd395fa9947d5a995a0b506a1ecd279de1dc75f5e8'
7
+ data.tar.gz: 0b93f499b391e0a5d376f851746ba2c44dac5d5a2dba18016050cddf769a0c9ff75f9efc818c24267c1131751d1dd583e80c9eec69afdcb4dc3a16f1c393993b
@@ -12,7 +12,9 @@ Gem::Specification.new do |s|
12
12
  s.description = ""
13
13
 
14
14
  s.rubyforge_project = "drip"
15
- s.add_dependency "rbtree"
15
+ s.add_dependency "rbtree"
16
+ s.add_development_dependency "test-unit"
17
+ s.add_development_dependency "sqlite3"
16
18
  s.files = `git ls-files`.split("\n")
17
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -1,3 +1,3 @@
1
1
  class Drip
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,410 @@
1
+ require 'drb/drb'
2
+ require 'rinda/tuplespace'
3
+ require 'enumerator'
4
+ require 'sqlite3'
5
+
6
+ class SQLite3::Database
7
+ def statement(s)
8
+ if @cache.nil?
9
+ @cache = Hash.new { |h, k| h[k] = self.prepare(k) }
10
+ end
11
+ @cache[s]
12
+ end
13
+ end
14
+
15
+ class SQLite3::Statement
16
+ def get_first_row(*bind_vars)
17
+ execute(*bind_vars).first
18
+ end
19
+
20
+ def get_first_value(*bind_vars)
21
+ execute(*bind_vars).each { |row| return row[0] }
22
+ nil
23
+ end
24
+ end
25
+
26
+ class Drip3
27
+ include DRbUndumped
28
+ INF = 1.0/0.0
29
+
30
+ def inspect; to_s; end
31
+
32
+ def initialize(dir)
33
+ @event = Rinda::TupleSpace.new(5)
34
+ @event.write([:last, 1])
35
+ setup_db(dir)
36
+ end
37
+
38
+ def self.time_to_key(time)
39
+ time.tv_sec * 1000000 + time.tv_usec
40
+ end
41
+
42
+ def time_to_key(time)
43
+ self.class.time_to_key(time)
44
+ end
45
+
46
+ def self.key_to_time(key)
47
+ Time.at(*key.divmod(1000000))
48
+ end
49
+
50
+ def key_to_time(key)
51
+ self.class.key_to_time(key)
52
+ end
53
+
54
+ def write(obj, tag=nil)
55
+ write_after(Time.now, obj, tag)
56
+ end
57
+
58
+ def write_after(at, obj, tag=nil)
59
+ make_key(at) do |key|
60
+ do_write(key, obj, tag)
61
+ end
62
+ end
63
+
64
+ def write_at(at, obj, tag=nil)
65
+ make_key_at(at) do |key|
66
+ do_write(key, obj, tag)
67
+ end
68
+ end
69
+
70
+ def write_if_latest(cond, obj, tag=nil)
71
+ make_key(Time.now) do |key|
72
+ do_write(key, obj, tag, cond)
73
+ end
74
+ end
75
+
76
+ def fetch(key)
77
+ do_fetch(key)
78
+ end
79
+ alias [] fetch
80
+
81
+ def head(n=1, tag=nil)
82
+ if tag
83
+ do_head_tag(n, tag)
84
+ else
85
+ do_head(n)
86
+ end
87
+ end
88
+
89
+ def read(key, n=1, at_least=1, timeout=nil)
90
+ key = time_to_key(Time.now) unless key
91
+ ary = do_read(key, n)
92
+ while ary.size < at_least
93
+ key = ary[-1][0] unless ary.empty?
94
+ begin
95
+ renewer = make_renewer(timeout)
96
+ wait(key, renewer)
97
+ rescue Rinda::RequestExpiredError
98
+ return ary
99
+ end
100
+ ary += do_read(key, n - ary.size)
101
+ end
102
+ ary
103
+ end
104
+
105
+ def read_tag(key, tag, n=1, at_least=1, timeout=nil)
106
+ at_least = n if n < at_least
107
+ key = time_to_key(Time.now) unless key
108
+ ary = do_read_tag(key, tag, n)
109
+ while ary.size < at_least
110
+ key = ary[-1][0] unless ary.empty?
111
+ begin
112
+ renewer = make_renewer(timeout)
113
+ wait_tag(key, tag, renewer)
114
+ rescue Rinda::RequestExpiredError
115
+ return ary
116
+ end
117
+ ary += do_read_tag(key, tag, n - ary.size)
118
+ end
119
+ ary
120
+ end
121
+
122
+ def latest?(key, tag=nil)
123
+ do_latest(key, tag)
124
+ end
125
+
126
+ def older(key, tag=nil)
127
+ do_older(key, tag)
128
+ end
129
+
130
+ def newer(key, tag=nil)
131
+ return read(key, 1, 0)[0] unless tag
132
+ read_tag(key, tag, 1, 0)[0]
133
+ end
134
+
135
+ def tag_next(tag)
136
+ do_tag_next(tag)
137
+ end
138
+
139
+ def tag_prev(tag)
140
+ do_tag_prev(tag)
141
+ end
142
+
143
+ private
144
+ def transaction_rw(key, &blk)
145
+ _, db = @event.take([key, nil])
146
+ db.transaction do
147
+ return yield(db)
148
+ end
149
+ ensure
150
+ @event.write([key, db])
151
+ end
152
+
153
+ def transaction(&blk)
154
+ transaction_rw(:db, &blk)
155
+ end
156
+
157
+ def transaction_w(&blk)
158
+ transaction_rw(@w_key, &blk)
159
+ end
160
+
161
+ def from_row(ary)
162
+ return nil unless ary
163
+ return ary[0], Marshal.load(ary[1]), ary[2]
164
+ end
165
+
166
+ def do_fetch(key)
167
+ transaction do |db|
168
+ db.statement('select value from Drip where key=?').execute(key).each do |row|
169
+ return Marshal.load(row[0])
170
+ end
171
+ end
172
+ nil
173
+ end
174
+
175
+ def do_tag_next(tag)
176
+ return nil if tag.nil?
177
+ transaction do |db|
178
+ sql = <<SQL
179
+ select tag from Drip where tag>? order by key asc limit 1
180
+ SQL
181
+ db.statement(sql).get_first_value(tag) rescue nil
182
+ end
183
+ end
184
+
185
+ def do_tag_prev(tag)
186
+ return nil if tag.nil?
187
+ transaction do |db|
188
+ sql = <<SQL
189
+ select tag from Drip where tag<? order by key desc limit 1
190
+ SQL
191
+ db.statement(sql).get_first_value(tag) rescue nil
192
+ end
193
+ end
194
+
195
+ def do_head_tag(n, tag)
196
+ transaction do |db|
197
+ sql = <<SQL
198
+ select key, value, tag from Drip where tag=? order by key desc limit ?;
199
+ SQL
200
+ db.statement(sql).execute(tag, n).collect {|row| from_row(row)}.reverse
201
+ end
202
+ end
203
+
204
+ def do_read_tag(key, tag, n=1)
205
+ transaction do |db|
206
+ sql = <<SQL
207
+ select key, value, tag from Drip
208
+ where key > ? and tag=?
209
+ order by key asc limit ?;
210
+ SQL
211
+ db.statement(sql).execute(key, tag, n).collect {|row| from_row(row)}
212
+ end
213
+ end
214
+
215
+ def wait(key, renewer)
216
+ @event.read([:last, key+1 .. INF], renewer)[1]
217
+ end
218
+
219
+ def wait_tag(key, tag, renewer)
220
+ @event.read([tag, key+1 .. INF], renewer)[1]
221
+ end
222
+
223
+ def make_renewer(timeout)
224
+ case timeout
225
+ when 0
226
+ return 0
227
+ when Numeric
228
+ return Renewer.new(timeout)
229
+ else
230
+ nil
231
+ end
232
+ end
233
+
234
+ def do_head(n)
235
+ transaction do |db|
236
+ sql = <<SQL
237
+ select key, value, tag from Drip order by key desc limit ?
238
+ SQL
239
+ db.statement(sql).execute(n).collect {|row| from_row(row)}.reverse
240
+ end
241
+ end
242
+
243
+ def do_read(key, n)
244
+ transaction do |db|
245
+ sql = <<SQL
246
+ select key, value, tag from Drip where key > ? order by key asc limit ?
247
+ SQL
248
+ db.statement(sql).execute(key, n).collect {|row| from_row(row)}
249
+ end
250
+ end
251
+
252
+ def do_older(key, tag)
253
+ if key.nil?
254
+ if tag.nil?
255
+ return do_head(1)[0]
256
+ else
257
+ return do_head_tag(1, tag)[0]
258
+ end
259
+ end
260
+
261
+ transaction do |db|
262
+ if tag
263
+ sql = <<SQL
264
+ select key, value, tag from Drip where key < ? and tag=?
265
+ order by key desc limit 1
266
+ SQL
267
+ from_row(db.statement(sql).get_first_row(key, tag))
268
+ else
269
+ sql = <<SQL
270
+ select key, value, tag from Drip where key < ?
271
+ order by key desc limit 1
272
+ SQL
273
+ from_row(db.statement(sql).get_first_row(key))
274
+ end
275
+ end
276
+ end
277
+
278
+ def make_key(at=Time.now)
279
+ synchronize do |last|
280
+ key = [time_to_key(at), last + 1].max
281
+ yield(key)
282
+ # key
283
+ end
284
+ end
285
+
286
+ def make_key_at(at)
287
+ synchronize do |last|
288
+ key = time_to_key(at)
289
+ raise 'InvalidTimeError' if key <= last
290
+ yield(key)
291
+ # key
292
+ end
293
+ end
294
+
295
+ def synchronize
296
+ _, last = @event.take([:last, nil])
297
+ last = yield(last)
298
+ ensure
299
+ @event.write([:last, last])
300
+ end
301
+
302
+ def do_latest(key, tag)
303
+ transaction do |db|
304
+ do_latest_inner(db, key, tag)
305
+ end
306
+ end
307
+
308
+ def do_latest_inner(db, key, tag)
309
+ if tag
310
+ sql = <<SQL
311
+ select max(key) from Drip where tag=?
312
+ SQL
313
+ v = db.statement(sql).get_first_value(tag) || 0
314
+ else
315
+ sql = <<SQL
316
+ select max(key) from Drip
317
+ SQL
318
+ v = db.statement(sql).get_first_value() || 0
319
+ end
320
+ return v == key
321
+ end
322
+
323
+ def do_write(key, obj, tag, cond=nil)
324
+ unless tag.nil?
325
+ raise(ArgumentError) unless String === tag
326
+ tag = tag.to_s
327
+ end
328
+ transaction_w do |db|
329
+ if cond
330
+ cond.each {|it|
331
+ return nil unless do_latest_inner(db, it[1], it[0])
332
+ }
333
+ end
334
+
335
+ if tag
336
+ @event.take([tag, nil], 0) rescue nil
337
+ @event.write([tag, key])
338
+ end
339
+ sql = 'insert into Drip values (?, ?, ?)'
340
+ db.statement(sql).execute(key, Marshal.dump(obj), tag)
341
+ end
342
+ key
343
+ end
344
+
345
+ private
346
+ def create_db(dir)
347
+ if dir
348
+ Dir.mkdir(dir) rescue nil
349
+ # fname = 'file:' + File.join(dir, 'drip.db') + '?cache=shared'
350
+ fname = File.join(dir, 'drip.db')
351
+ @w_key = :db
352
+ @event.write([:db, SQLite3::Database.open(fname)])
353
+ else
354
+ fname = ':memory:'
355
+ @w_key = :db
356
+ @event.write([:db, SQLite3::Database.open(fname)])
357
+ end
358
+ end
359
+
360
+ def setup_db(dir)
361
+ create_db(dir)
362
+ create_table
363
+ end
364
+
365
+ def create_table
366
+ transaction_w do |db|
367
+ begin
368
+ db.execute('create table Drip (key bigint, value blob, tag text);')
369
+ db.execute('create index DripKey on Drip(key);')
370
+ db.execute('create index Tags on Drip(key, tag);')
371
+ rescue SQLite3::SQLException
372
+ unless $!.message == 'table Drip already exists'
373
+ raise $!
374
+ end
375
+ end
376
+ end
377
+ end
378
+
379
+ class Renewer
380
+ def initialize(timeout)
381
+ @at = Time.now + timeout
382
+ end
383
+
384
+ def renew
385
+ @at - Time.now
386
+ end
387
+ end
388
+ end
389
+
390
+ if __FILE__ == $0
391
+ # d3 = Drip3.new('test_db')
392
+ d3 = Drip3.new(nil)
393
+
394
+ d3.write("こんにちはせかい\0\0こんにちはアゲイン")
395
+ p d3.head[0][1]
396
+
397
+ key = d3.write('start')
398
+ 50.times do |n|
399
+ Thread.new(n) do |x|
400
+ 100.times do
401
+ d3.write(x, 'count')
402
+ end
403
+ d3.write(x, 'wakeup')
404
+ end
405
+ end
406
+ 50.times do
407
+ key, value, = d3.read_tag(key, 'wakeup', 1)[0]
408
+ p value
409
+ end
410
+ end
@@ -0,0 +1,250 @@
1
+ require 'test/unit'
2
+ require '../lib/drip3.rb'
3
+ require 'fileutils'
4
+
5
+ class TestDrip < Test::Unit::TestCase
6
+ def setup
7
+ @drip = Drip3.new(nil)
8
+ end
9
+
10
+ def test_time_travel
11
+ @drip.write('age' => 1)
12
+ @drip.write('age' => 2)
13
+ @drip.write('age' => 3)
14
+ oid, value = @drip.older(nil)
15
+ assert_equal(value, 'age' => 3)
16
+ oid, value = @drip.older(oid)
17
+ assert_equal(value, 'age' => 2)
18
+ oid, value = @drip.older(oid)
19
+ assert_equal(value, 'age' => 1)
20
+ oid, value = @drip.older(oid)
21
+ assert_equal(oid, nil)
22
+ assert_equal(value, nil)
23
+
24
+ oid, value = @drip.newer(0)
25
+ assert_equal(value, 'age' => 1)
26
+ oid, value = @drip.newer(oid)
27
+ assert_equal(value, 'age' => 2)
28
+ oid, value = @drip.newer(oid)
29
+ assert_equal(value, 'age' => 3)
30
+ oid, value = @drip.newer(oid)
31
+ assert_equal(oid, nil)
32
+ assert_equal(value, nil)
33
+ end
34
+
35
+ def test_read
36
+ 11.times do |n|
37
+ @drip.write("n=#{n}" => 'x' * n, n => n, "n" => n, :symbol => n)
38
+ end
39
+ ary = @drip.read(0, 3)
40
+ assert_equal(ary.size, 3)
41
+ assert_equal(ary[0][1]['n'], 0)
42
+ assert_equal(ary[1][1]['n'], 1)
43
+ assert_equal(ary[2][1]['n'], 2)
44
+ ary = @drip.read(ary[2][0], 3)
45
+ assert_equal(ary.size, 3)
46
+ ary = @drip.read(ary[2][0], 3)
47
+ assert_equal(ary.size, 3)
48
+ ary = @drip.read(ary[2][0], 3)
49
+ assert_equal(ary.size, 2)
50
+
51
+ oid = @drip.write('latest', 'tag1')
52
+ oid, value, *tags = @drip.newer(oid - 1)
53
+ assert_equal(value, 'latest')
54
+ assert_equal(tags, ['tag1'])
55
+ end
56
+
57
+ def test_symbol_is_not_tag
58
+ assert_raise(ArgumentError){
59
+ @drip.write({:symbol => :symbol, 'string' => :string}, :symbol)
60
+ }
61
+ end
62
+
63
+ def test_number_is_not_tag
64
+ assert_raise(ArgumentError){
65
+ @drip.write({5 => :five, 'string' => :string}, 5)
66
+ }
67
+ end
68
+
69
+ def test_older_now_is_newest
70
+ @drip.write('age' => 1)
71
+ @drip.write('age' => 2)
72
+ @drip.write('age' => 3)
73
+ oid, value, = @drip.older(nil)
74
+ assert_equal(value, 'age' => 3)
75
+ oid, value, = @drip.older(@drip.time_to_key(Time.now))
76
+ assert_equal(value, 'age' => 3)
77
+
78
+ # newer(past)
79
+ assert_equal(@drip.newer(0)[1], 'age' => 1)
80
+ assert_equal(@drip.newer(0)[1], 'age' => 1)
81
+ end
82
+
83
+ def test_read_tag
84
+ 3.times do |n|
85
+ @drip.write({'n' => n}, 'n')
86
+ @drip.write({'n' => n, '2' => n * 2}, 'n')
87
+ @drip.write({'n' => n, '2' => n * 2, '3' => n * 3}, 'n')
88
+ end
89
+
90
+ ary = @drip.read_tag(0, 'n', 10)
91
+ assert_equal(ary.size, 9)
92
+ assert_equal(ary[0][1]['n'], 0)
93
+ assert_equal(ary[0][2], 'n')
94
+ end
95
+
96
+ def test_head
97
+ 10.times do |n|
98
+ @drip.write(n)
99
+ end
100
+
101
+ ary = @drip.head(3)
102
+ assert_equal(ary.size, 3)
103
+ assert_equal(ary[0][1], 7)
104
+ assert_equal(ary[2][1], 9)
105
+ end
106
+
107
+ def test_after
108
+ assert_equal(@drip.write_after(Time.at(1), 1), 1000000)
109
+ assert_equal(@drip.write_after(Time.at(2), 2), 2000000)
110
+ assert_equal(@drip.write_after(Time.at(3), 3), 3000000)
111
+ assert_equal(@drip.write_after(Time.at(4), 4), 4000000)
112
+ assert_equal(@drip.write_after(Time.at(4), 5), 4000001)
113
+ assert_equal(@drip.write_after(Time.at(2), 6), 4000002)
114
+ assert_equal(@drip.write_after(Time.at(5), 6), 5000000)
115
+ assert_equal(@drip.write_after(Time.at(5), 7), 5000001)
116
+ assert_equal(@drip.write_at(Time.at(6), 8), 6000000)
117
+ assert_raise(RuntimeError) {@drip.write_at(Time.at(6), 8)}
118
+ assert_equal(@drip.write_after(Time.at(5), 8), 6000001)
119
+ end
120
+
121
+ def test_use_string_tag
122
+ oid = @drip.write(:symbol, 'dup')
123
+ assert_equal(@drip[oid], :symbol)
124
+ end
125
+
126
+ def test_latest?
127
+ key = @drip.write(:start)
128
+
129
+ assert_equal(@drip.latest?(key), true)
130
+
131
+ 10.times do |n|
132
+ @drip.write(n)
133
+ end
134
+ assert_equal(@drip.latest?(key), false)
135
+ key = @drip.write(:stop)
136
+ assert_equal(@drip.latest?(key), true)
137
+
138
+ key = @drip.write(:tag_start, 'tag')
139
+ @drip.write(:tag, 'ignore tag')
140
+ assert_equal(@drip.latest?(key, 'tag'), true)
141
+ @drip.write(:tag, 'tag')
142
+ assert_equal(@drip.latest?(key, 'tag'), false)
143
+ end
144
+
145
+ def test_write_if_latest
146
+ t1 = @drip.write('t1', 't1')
147
+ t2 = @drip.write('t2', 't2')
148
+ t3 = @drip.write('t3', 't3')
149
+ assert_equal(@drip.latest?(t1, 't1'), true)
150
+ assert(@drip.write_if_latest([['t1', t1],
151
+ ['t2', t2],
152
+ ['t3', t3],
153
+ ['t4', 0]], 'hello', 't1'))
154
+ assert_equal(@drip.latest?(t1, 't1'), false)
155
+ assert_equal(@drip.write_if_latest([['t1', t1],
156
+ ['t2', t2],
157
+ ['t3', t3]], 'hello', 't1'), nil)
158
+ end
159
+
160
+ end
161
+
162
+ class TestDripUsingStorage < TestDrip
163
+ def remove_drip(dir='test_db')
164
+ FileUtils.rm_r(dir, :force => true)
165
+ end
166
+
167
+ def setup
168
+ remove_drip
169
+ @drip = Drip3.new('test_db')
170
+ end
171
+
172
+ def teardown
173
+ remove_drip
174
+ end
175
+
176
+ def test_tag_browse
177
+ @drip.write(1, 't1')
178
+ @drip.write(2, 't2')
179
+ @drip.write(3, 't3')
180
+ @drip.write(4, 't4')
181
+
182
+ assert_equal(@drip.tag_next(''), 't1')
183
+ assert_equal(@drip.tag_next('t1'), 't2')
184
+ assert_equal(@drip.tag_next('t3'), 't4')
185
+ assert_equal(@drip.tag_next('t5'), nil)
186
+
187
+ assert_equal(@drip.tag_prev('u'), 't4')
188
+ assert_equal(@drip.tag_prev('t2'), 't1')
189
+ assert_equal(@drip.tag_prev('t1'), nil)
190
+ end
191
+
192
+ def test_twice_latest?
193
+ assert_equal(@drip.latest?(1), false)
194
+ tag1 = @drip.write('tag1', 'tag1')
195
+ assert_equal(@drip.latest?(tag1), true)
196
+ @drip.write('nop', 'tag1')
197
+ @drip.write('nop', 'tag1')
198
+ tag2 = @drip.write('tag2', 'tag1')
199
+ assert_equal(@drip.latest?(1), false)
200
+ drip = Drip3.new('test_db')
201
+ assert_equal(drip.latest?(1), false)
202
+ assert_equal(drip.latest?(tag1, 'tag1'), false)
203
+ assert_equal(drip.latest?(tag2, 'tag1'), true)
204
+ assert_equal(drip.latest?(tag2, 'tag0'), false)
205
+ end
206
+
207
+ def test_twice
208
+ 11.times do |n|
209
+ @drip.write("n=#{n}" => 'x' * n, n => n, "n" => n, :symbol => n)
210
+ end
211
+
212
+ drip = Drip3.new('test_db')
213
+ ary = drip.head(3)
214
+ assert_equal(ary.size, 3)
215
+ assert_equal(ary[0][1]['n'], 8)
216
+ assert_equal(ary[1][1]['n'], 9)
217
+ assert_equal(ary[2][1]['n'], 10)
218
+ ary = drip.head(1)
219
+ assert_equal(ary.size, 1)
220
+ assert_equal(ary[0][1]['n'], 10)
221
+ ary = drip.read(0, 3)
222
+ assert_equal(ary.size, 3)
223
+ assert_equal(ary[0][1]['n'], 0)
224
+ assert_equal(ary[1][1]['n'], 1)
225
+ assert_equal(ary[2][1]['n'], 2)
226
+ ary = drip.read(ary[2][0], 3)
227
+ assert_equal(ary.size, 3)
228
+ ary = drip.read(ary[2][0], 3)
229
+ assert_equal(ary.size, 3)
230
+ ary = drip.read(ary[2][0], 3)
231
+ assert_equal(ary.size, 2)
232
+ end
233
+
234
+ def test_huge
235
+ str = File.read(__FILE__)
236
+
237
+ 10.times do
238
+ Thread.new do
239
+ 1000.times do |n|
240
+ @drip.write(str, "n=#{n}")
241
+ end
242
+ end
243
+ end
244
+
245
+ assert_equal(@drip.read_tag(0, 'n=999', 10, 10).size, 10)
246
+
247
+ assert_equal(10000, @drip.read(0, 12000, 10000).size)
248
+ end
249
+ end
250
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masatoshi Seki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-17 00:00:00.000000000 Z
11
+ date: 2018-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbtree
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test-unit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description: ''
28
56
  email:
29
57
  executables: []
@@ -39,6 +67,7 @@ files:
39
67
  - install.rb
40
68
  - lib/drip.rb
41
69
  - lib/drip/version.rb
70
+ - lib/drip3.rb
42
71
  - lib/my_drip.rb
43
72
  - sample/copocopo.rb
44
73
  - sample/demo4book/crawl.rb
@@ -54,6 +83,7 @@ files:
54
83
  - sample/simple-oauth.rb
55
84
  - sample/tw_markov.rb
56
85
  - test/basic.rb
86
+ - test/basic3.rb
57
87
  homepage: https://github.com/seki/Drip
58
88
  licenses: []
59
89
  metadata: {}
@@ -73,9 +103,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
103
  version: '0'
74
104
  requirements: []
75
105
  rubyforge_project: drip
76
- rubygems_version: 2.5.1
106
+ rubygems_version: 2.7.7
77
107
  signing_key:
78
108
  specification_version: 4
79
109
  summary: Simple RD-Stream for Rinda::TupleSpace lovers.
80
110
  test_files:
81
111
  - test/basic.rb
112
+ - test/basic3.rb