drip 0.1.0 → 0.1.1

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 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