obuf 1.1.0 → 1.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.
- data/.travis.yml +6 -2
- data/Gemfile +4 -3
- data/History.txt +4 -0
- data/{README.rdoc → README.md} +21 -16
- data/lib/obuf.rb +18 -50
- data/lib/obuf/lens.rb +70 -0
- data/lib/obuf/protected_lens.rb +23 -0
- data/obuf.gemspec +16 -11
- data/test/test_obuf.rb +72 -9
- metadata +51 -15
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,37 +1,42 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* http://github.com/julik/obuf
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
1
|
+
# obuf
|
6
2
|
|
7
3
|
A simple Ruby object buffer. Use this if you need to temporarily store alot of serializable Ruby objects.
|
8
4
|
|
9
|
-
== FEATURES/PROBLEMS:
|
10
|
-
|
11
|
-
* Thread safe (for as far as I can gauge it)
|
12
|
-
* Gives both read and write access to the storage
|
13
|
-
|
14
|
-
== SYNOPSIS:
|
15
|
-
|
16
5
|
obuf = Obuf.new
|
17
6
|
5_000_000.times{ obuf.push(compute_some_object) } # no memory inflation
|
18
7
|
obuf.each do | stored_object | # objects are restored one by one
|
19
8
|
# do something with stored_object
|
20
9
|
end
|
21
10
|
|
22
|
-
|
11
|
+
You can also write objects in one process, and recover them in another, using `Obuf::Lens`:
|
12
|
+
|
13
|
+
# In fork process
|
14
|
+
File.open('/tmp/output.bin', 'a') do |f|
|
15
|
+
Obuf::Lens.new(f) << my_object
|
16
|
+
end
|
17
|
+
|
18
|
+
# In join process after forks completed
|
19
|
+
File.open('/tmp/output.bin', 'r') do |f|
|
20
|
+
Obuf::Lens.new(f).each do | object_written_by_fork |
|
21
|
+
puts object_written_by_fork.inspect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
The `Lens` is what is used under the hood in the main Obuf as well.
|
26
|
+
|
27
|
+
## Requirements
|
23
28
|
|
24
29
|
* Ruby 1.8.6+
|
25
30
|
|
26
|
-
|
31
|
+
## Installation
|
27
32
|
|
28
33
|
* gem install obuf
|
29
34
|
|
30
|
-
|
35
|
+
## License
|
31
36
|
|
32
37
|
(The MIT License)
|
33
38
|
|
34
|
-
Copyright (c) 2011 Julik Tarkhanov <me@julik.nl>
|
39
|
+
Copyright (c) 2011-2015 Julik Tarkhanov <me@julik.nl>
|
35
40
|
|
36
41
|
Permission is hereby granted, free of charge, to any person obtaining
|
37
42
|
a copy of this software and associated documentation files (the
|
data/lib/obuf.rb
CHANGED
@@ -19,13 +19,12 @@ require "thread" # required for ruby 18
|
|
19
19
|
#
|
20
20
|
# Both reading and writing aim to be threadsafe
|
21
21
|
class Obuf
|
22
|
-
VERSION = "1.
|
22
|
+
VERSION = "1.2.0"
|
23
|
+
require File.dirname(__FILE__) + "/obuf/lens"
|
24
|
+
require File.dirname(__FILE__) + "/obuf/protected_lens"
|
23
25
|
|
24
26
|
include Enumerable
|
25
27
|
|
26
|
-
DELIM = "\t"
|
27
|
-
END_RECORD = "\n"
|
28
|
-
|
29
28
|
# Returns the number of objects stored so far
|
30
29
|
attr_reader :size
|
31
30
|
|
@@ -34,13 +33,15 @@ class Obuf
|
|
34
33
|
def initialize(enumerable = [])
|
35
34
|
@sem = Mutex.new
|
36
35
|
@store = Tempfile.new("obuf")
|
37
|
-
@store.set_encoding(Encoding::BINARY) if @store.respond_to?(:set_encoding)
|
38
36
|
@store.binmode
|
39
37
|
@size = 0
|
40
38
|
|
39
|
+
@lens = Obuf::ProtectedLens.new(@store)
|
40
|
+
|
41
41
|
# Store everything from the enumerable in self
|
42
|
-
enumerable.each(
|
42
|
+
enumerable.each { |e| push(e) }
|
43
43
|
|
44
|
+
# ...and yield self for any configuration
|
44
45
|
yield self if block_given?
|
45
46
|
end
|
46
47
|
|
@@ -51,14 +52,10 @@ class Obuf
|
|
51
52
|
|
52
53
|
# Store an object
|
53
54
|
def push(object_to_store)
|
54
|
-
|
55
|
-
|
56
|
-
@store.write(blob.size)
|
57
|
-
@store.write(DELIM)
|
58
|
-
@store.write(blob)
|
59
|
-
@store.write(END_RECORD)
|
55
|
+
@sem.synchronize {
|
56
|
+
@lens << object_to_store
|
60
57
|
@size += 1
|
61
|
-
|
58
|
+
}
|
62
59
|
object_to_store
|
63
60
|
end
|
64
61
|
|
@@ -68,7 +65,8 @@ class Obuf
|
|
68
65
|
# methods are also available (but be careful with Enumerable#map and to_a)
|
69
66
|
def each
|
70
67
|
with_separate_read_io do | iterable |
|
71
|
-
|
68
|
+
reading_lens = Obuf::Lens.new(iterable)
|
69
|
+
@size.times { yield(reading_lens.recover_object) }
|
72
70
|
end
|
73
71
|
end
|
74
72
|
|
@@ -89,15 +87,8 @@ class Obuf
|
|
89
87
|
|
90
88
|
def recover_at(idx)
|
91
89
|
with_separate_read_io do | iterable |
|
92
|
-
|
93
|
-
|
94
|
-
# Do not unmarshal anything but wind the IO in fixed offsets
|
95
|
-
idx.times do
|
96
|
-
skip_bytes = iterable.gets("\t").to_i
|
97
|
-
iterable.seek(iterable.pos + skip_bytes)
|
98
|
-
end
|
99
|
-
|
100
|
-
recover_object_from(iterable)
|
90
|
+
reading_lens = Obuf::Lens.new(iterable)
|
91
|
+
reading_lens.recover_at(idx)
|
101
92
|
end
|
102
93
|
end
|
103
94
|
|
@@ -105,38 +96,15 @@ class Obuf
|
|
105
96
|
# and iterate through that (we will have one IO handle per loop nest)
|
106
97
|
def with_separate_read_io
|
107
98
|
# Ensure all data is written before we read it
|
108
|
-
@sem.synchronize
|
99
|
+
iterable = @sem.synchronize do
|
100
|
+
@store.flush
|
101
|
+
File.open(@store.path, "rb")
|
102
|
+
end
|
109
103
|
|
110
|
-
iterable = File.open(@store.path, "rb")
|
111
104
|
begin
|
112
105
|
yield(iterable)
|
113
106
|
ensure
|
114
107
|
iterable.close
|
115
108
|
end
|
116
109
|
end
|
117
|
-
|
118
|
-
def recover_object_from(io)
|
119
|
-
# Up to the tab is the amount of bytes to read
|
120
|
-
demarshal_bytes = io.gets("\t").to_i
|
121
|
-
|
122
|
-
# When at end of IO return nil
|
123
|
-
return nil if demarshal_bytes == 0
|
124
|
-
|
125
|
-
blob = io.read(demarshal_bytes)
|
126
|
-
demarshal_object(blob)
|
127
|
-
end
|
128
|
-
|
129
|
-
# This method is only used internally.
|
130
|
-
# Override this if you need non-default marshalling
|
131
|
-
# (don't forget to also override demarshal_object)
|
132
|
-
def marshal_object(object_to_store)
|
133
|
-
d = Marshal.dump(object_to_store)
|
134
|
-
end
|
135
|
-
|
136
|
-
# This method is only used internally.
|
137
|
-
# Override this if you need non-default demarshalling
|
138
|
-
# (don't forget to also override marshal_object)
|
139
|
-
def demarshal_object(blob)
|
140
|
-
Marshal.load(blob)
|
141
|
-
end
|
142
110
|
end
|
data/lib/obuf/lens.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
# Provides a per-object iterator on top of any IO object or pipe
|
4
|
+
class Obuf::Lens
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
DELIM = "\t"
|
8
|
+
END_RECORD = "\n"
|
9
|
+
|
10
|
+
# Creates a new Lens on top of a File object, IO object or pipe.
|
11
|
+
# The object given should support +seek+, +gets+, and +read+ to recover
|
12
|
+
# objects, and +write+ to dump objects.
|
13
|
+
def initialize(io_or_pipe)
|
14
|
+
@io = io_or_pipe
|
15
|
+
end
|
16
|
+
|
17
|
+
# Store an object
|
18
|
+
def <<(object_to_store)
|
19
|
+
blob = marshal_object(object_to_store)
|
20
|
+
@io.write(blob.size)
|
21
|
+
@io.write(DELIM)
|
22
|
+
@io.write(blob)
|
23
|
+
@io.write(END_RECORD)
|
24
|
+
object_to_store
|
25
|
+
end
|
26
|
+
|
27
|
+
# Recover Nth object
|
28
|
+
def recover_at(idx)
|
29
|
+
@io.seek(0)
|
30
|
+
# Do not unmarshal anything but wind the IO in fixed offsets
|
31
|
+
idx.times do
|
32
|
+
skip_bytes = @io.gets("\t").to_i
|
33
|
+
@io.seek(@io.pos + skip_bytes + 1)
|
34
|
+
end
|
35
|
+
recover_object
|
36
|
+
end
|
37
|
+
|
38
|
+
# Recover the object at the current position in the IO. Returns +nil+
|
39
|
+
# if there is nothing to recover or the backing buffer is empty.
|
40
|
+
def recover_object
|
41
|
+
# Up to the tab is the amount of bytes to read
|
42
|
+
demarshal_bytes = @io.gets("\t").to_i
|
43
|
+
|
44
|
+
# When at end of IO return nil
|
45
|
+
return nil if demarshal_bytes == 0
|
46
|
+
|
47
|
+
blob = @io.read(demarshal_bytes)
|
48
|
+
demarshal_object(blob)
|
49
|
+
end
|
50
|
+
|
51
|
+
def each
|
52
|
+
yield(recover_object) until @io.eof?
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# This method is only used internally.
|
58
|
+
# Override this if you need non-default marshalling
|
59
|
+
# (don't forget to also override demarshal_object)
|
60
|
+
def marshal_object(object_to_store)
|
61
|
+
Marshal.dump(object_to_store)
|
62
|
+
end
|
63
|
+
|
64
|
+
# This method is only used internally.
|
65
|
+
# Override this if you need non-default demarshalling
|
66
|
+
# (don't forget to also override marshal_object)
|
67
|
+
def demarshal_object(blob)
|
68
|
+
Marshal.load(blob)
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
# Similar to Obuf::Lens but protects all the operations that change the IO offset
|
4
|
+
# with a Mutex.
|
5
|
+
class Obuf::ProtectedLens < Obuf::Lens
|
6
|
+
def initialize(io)
|
7
|
+
super
|
8
|
+
@mutex = Mutex.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# Store an object
|
12
|
+
def <<(object_to_store)
|
13
|
+
@mutex.synchronize { super }
|
14
|
+
end
|
15
|
+
|
16
|
+
def recover_at(idx)
|
17
|
+
@mutex.synchronize { super }
|
18
|
+
end
|
19
|
+
|
20
|
+
def recover_object
|
21
|
+
@mutex.synchronize { super }
|
22
|
+
end
|
23
|
+
end
|
data/obuf.gemspec
CHANGED
@@ -5,49 +5,54 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "obuf"
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Julik Tarkhanov"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2015-04-17"
|
13
13
|
s.description = "Stores marshaled temporary objects on-disk in a simple Enumerable"
|
14
14
|
s.email = "me@julik.nl"
|
15
15
|
s.extra_rdoc_files = [
|
16
|
-
"README.
|
16
|
+
"README.md"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".autotest",
|
20
20
|
".travis.yml",
|
21
21
|
"Gemfile",
|
22
22
|
"History.txt",
|
23
|
-
"README.
|
23
|
+
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"lib/obuf.rb",
|
26
|
+
"lib/obuf/lens.rb",
|
27
|
+
"lib/obuf/protected_lens.rb",
|
26
28
|
"obuf.gemspec",
|
27
29
|
"test/test_obuf.rb"
|
28
30
|
]
|
29
31
|
s.homepage = "http://github.com/julik/obuf"
|
30
32
|
s.licenses = ["MIT"]
|
31
33
|
s.require_paths = ["lib"]
|
32
|
-
s.rubygems_version = "1.8.
|
34
|
+
s.rubygems_version = "1.8.23.2"
|
33
35
|
s.summary = "Ruby disk-backed object buffer"
|
34
36
|
|
35
37
|
if s.respond_to? :specification_version then
|
36
38
|
s.specification_version = 3
|
37
39
|
|
38
40
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
39
|
-
s.add_development_dependency(%q<
|
40
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
41
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
41
42
|
s.add_development_dependency(%q<flexmock>, ["~> 0.8"])
|
43
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
44
|
+
s.add_development_dependency(%q<jeweler>, ["= 1.8.4"])
|
42
45
|
else
|
43
|
-
s.add_dependency(%q<
|
44
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
46
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
45
47
|
s.add_dependency(%q<flexmock>, ["~> 0.8"])
|
48
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
49
|
+
s.add_dependency(%q<jeweler>, ["= 1.8.4"])
|
46
50
|
end
|
47
51
|
else
|
48
|
-
s.add_dependency(%q<
|
49
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
52
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
50
53
|
s.add_dependency(%q<flexmock>, ["~> 0.8"])
|
54
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
55
|
+
s.add_dependency(%q<jeweler>, ["= 1.8.4"])
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
data/test/test_obuf.rb
CHANGED
@@ -4,6 +4,7 @@ require "flexmock"
|
|
4
4
|
require "flexmock/test_unit"
|
5
5
|
require "stringio"
|
6
6
|
|
7
|
+
# We are limited to flexmock 0.8 on Ruby 1.8
|
7
8
|
# http://redmine.ruby-lang.org/issues/4882
|
8
9
|
# https://github.com/jimweirich/flexmock/issues/4
|
9
10
|
# https://github.com/julik/flexmock/commit/4acea00677e7b558bd564ec7c7630f0b27d368ca
|
@@ -87,15 +88,6 @@ class TestObuf < Test::Unit::TestCase
|
|
87
88
|
assert_equal "E\r\nWow!", a[4]
|
88
89
|
end
|
89
90
|
|
90
|
-
def test_random_access
|
91
|
-
a = Obuf.new
|
92
|
-
letters = ("A".."Z").map{|e| "#{e}\r\nWow!"}.to_a
|
93
|
-
letters.map(&a.method(:push))
|
94
|
-
|
95
|
-
assert_equal "B\r\nWow!", a[1]
|
96
|
-
assert_equal "E\r\nWow!", a[4]
|
97
|
-
end
|
98
|
-
|
99
91
|
def test_random_access_out_of_bounds
|
100
92
|
a = Obuf.new
|
101
93
|
letters = ("A".."Z").map{|e| "#{e}\r\nWow!"}.to_a
|
@@ -119,3 +111,74 @@ class TestObuf < Test::Unit::TestCase
|
|
119
111
|
assert_equal 0, a.size
|
120
112
|
end
|
121
113
|
end
|
114
|
+
|
115
|
+
class TestLens < Test::Unit::TestCase
|
116
|
+
def test_lens_write
|
117
|
+
mock_io = flexmock()
|
118
|
+
lens = Obuf::Lens.new(mock_io)
|
119
|
+
flexmock(mock_io).should_receive(:write){|written|
|
120
|
+
assert_kind_of Fixnum, written
|
121
|
+
}
|
122
|
+
flexmock(mock_io).should_receive(:write).with("\t")
|
123
|
+
flexmock(mock_io).should_receive(:write){|byte_blob|
|
124
|
+
assert_kind_of String, byte_blob
|
125
|
+
}
|
126
|
+
flexmock(mock_io).should_receive(:write).with("\n")
|
127
|
+
lens << "Hi there!"
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_lens_recover_object_after_write
|
131
|
+
mock_io = StringIO.new
|
132
|
+
lens = Obuf::Lens.new(mock_io)
|
133
|
+
lens << "Hi there!"
|
134
|
+
|
135
|
+
recovered = lens.recover_object
|
136
|
+
assert_nil recovered, "The IO is at the end now"
|
137
|
+
|
138
|
+
mock_io.rewind
|
139
|
+
recovered = lens.recover_object
|
140
|
+
assert_equal "Hi there!", recovered
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_lens_each
|
144
|
+
mock_io = StringIO.new
|
145
|
+
|
146
|
+
writing_lens = Obuf::Lens.new(mock_io)
|
147
|
+
writing_lens << "Hi there!"
|
148
|
+
writing_lens << 98121
|
149
|
+
writing_lens << [123, :a]
|
150
|
+
|
151
|
+
mock_io.rewind
|
152
|
+
|
153
|
+
reading_lens = Obuf::Lens.new(mock_io)
|
154
|
+
items = []
|
155
|
+
reading_lens.each do | item |
|
156
|
+
items << item
|
157
|
+
end
|
158
|
+
|
159
|
+
assert_equal "Hi there!", items[0]
|
160
|
+
assert_equal 98121, items[1]
|
161
|
+
assert_equal [123, :a], items[2]
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_lens_recover_at
|
165
|
+
mock_io = StringIO.new
|
166
|
+
|
167
|
+
writing_lens = Obuf::Lens.new(mock_io)
|
168
|
+
writing_lens << "Hi there!"
|
169
|
+
writing_lens << 98121
|
170
|
+
writing_lens << [123, :a]
|
171
|
+
|
172
|
+
reading_lens = Obuf::Lens.new(mock_io)
|
173
|
+
# Also try to recover object at index 3, which does not exist in the underlying buffer
|
174
|
+
objects_at_positions = (0..3).to_a.reverse.map do | i |
|
175
|
+
reading_lens.recover_at(i)
|
176
|
+
end
|
177
|
+
|
178
|
+
assert_nil objects_at_positions[0]
|
179
|
+
assert_equal [123, :a], objects_at_positions[1]
|
180
|
+
assert_equal 98121, objects_at_positions[2]
|
181
|
+
assert_equal "Hi there!", objects_at_positions[3]
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obuf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,43 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement:
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
25
|
none: false
|
18
26
|
requirements:
|
19
27
|
- - ! '>='
|
20
28
|
- !ruby/object:Gem::Version
|
21
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: flexmock
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0.8'
|
22
38
|
type: :development
|
23
39
|
prerelease: false
|
24
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0.8'
|
25
46
|
- !ruby/object:Gem::Dependency
|
26
47
|
name: rake
|
27
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
@@ -32,32 +53,44 @@ dependencies:
|
|
32
53
|
version: '0'
|
33
54
|
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement:
|
63
|
+
name: jeweler
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
|
-
- -
|
67
|
+
- - '='
|
42
68
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
69
|
+
version: 1.8.4
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - '='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.4
|
47
78
|
description: Stores marshaled temporary objects on-disk in a simple Enumerable
|
48
79
|
email: me@julik.nl
|
49
80
|
executables: []
|
50
81
|
extensions: []
|
51
82
|
extra_rdoc_files:
|
52
|
-
- README.
|
83
|
+
- README.md
|
53
84
|
files:
|
54
85
|
- .autotest
|
55
86
|
- .travis.yml
|
56
87
|
- Gemfile
|
57
88
|
- History.txt
|
58
|
-
- README.
|
89
|
+
- README.md
|
59
90
|
- Rakefile
|
60
91
|
- lib/obuf.rb
|
92
|
+
- lib/obuf/lens.rb
|
93
|
+
- lib/obuf/protected_lens.rb
|
61
94
|
- obuf.gemspec
|
62
95
|
- test/test_obuf.rb
|
63
96
|
homepage: http://github.com/julik/obuf
|
@@ -73,6 +106,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
106
|
- - ! '>='
|
74
107
|
- !ruby/object:Gem::Version
|
75
108
|
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: 4056659205467737583
|
76
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
113
|
none: false
|
78
114
|
requirements:
|
@@ -81,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
117
|
version: '0'
|
82
118
|
requirements: []
|
83
119
|
rubyforge_project:
|
84
|
-
rubygems_version: 1.8.
|
120
|
+
rubygems_version: 1.8.23.2
|
85
121
|
signing_key:
|
86
122
|
specification_version: 3
|
87
123
|
summary: Ruby disk-backed object buffer
|