mmap2 2.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Changes +55 -0
- data/README.rdoc +36 -0
- data/b.rb +33 -0
- data/ext/mmap/extconf.rb +22 -0
- data/ext/mmap/mmap.c +2606 -0
- data/lib/mmap/version.rb +5 -0
- data/lib/mmap.rb +21 -0
- data/mmap.rd +253 -0
- data/test/test_mmap.rb +373 -0
- metadata +60 -0
data/lib/mmap/version.rb
ADDED
data/lib/mmap.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# The Mmap class implement memory-mapped file objects
|
2
|
+
#
|
3
|
+
# Most of these methods have the same syntax than the methods of String
|
4
|
+
#
|
5
|
+
# === WARNING
|
6
|
+
# === The variables $' and $` are not available with gsub! and sub!
|
7
|
+
require 'mmap/mmap' unless defined? Mmap
|
8
|
+
require 'mmap/version'
|
9
|
+
|
10
|
+
class Mmap
|
11
|
+
include Comparable
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
def clone # :nodoc:
|
15
|
+
raise TypeError, "can't clone instance of #{self.class}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def dup # :nodoc:
|
19
|
+
raise TypeError, "can't dup instance of #{self.class}"
|
20
|
+
end
|
21
|
+
end
|
data/mmap.rd
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
=begin
|
2
|
+
= Mmap
|
3
|
+
|
4
|
+
((<Download|URL:ftp://moulon.inra.fr/pub/ruby/>))
|
5
|
+
|
6
|
+
The Mmap class implement memory-mapped file objects
|
7
|
+
|
8
|
+
=== WARNING
|
9
|
+
=== The variables $' and $` are not available with gsub! and sub!
|
10
|
+
|
11
|
+
== SuperClass
|
12
|
+
|
13
|
+
Object
|
14
|
+
|
15
|
+
== Included Modules
|
16
|
+
|
17
|
+
* Comparable
|
18
|
+
* Enumerable
|
19
|
+
|
20
|
+
== Class Methods
|
21
|
+
|
22
|
+
--- lockall(flag)
|
23
|
+
disable paging of all pages mapped. ((|flag|)) can be
|
24
|
+
((|Mmap::MCL_CURRENT|)) or ((|Mmap::MCL_FUTURE|))
|
25
|
+
|
26
|
+
--- new(file, mode = "r", protection = Mmap::MAP_SHARED, options = {})
|
27
|
+
--- new(nil, length, protection = Mmap::MAP_SHARED, options = {})
|
28
|
+
create a new Mmap object
|
29
|
+
|
30
|
+
: ((|file|))
|
31
|
+
Pathname of the file, if ((|nil|)) is given an anonymous map
|
32
|
+
is created ((|Mmanp::MAP_ANON|))
|
33
|
+
|
34
|
+
: ((|mode|))
|
35
|
+
Mode to open the file, it can be "r", "w", "rw", "a"
|
36
|
+
|
37
|
+
: ((|protection|))
|
38
|
+
specify the nature of the mapping
|
39
|
+
|
40
|
+
: ((|Mmap::MAP_SHARED|))
|
41
|
+
Creates a mapping that's shared with all other processes
|
42
|
+
mapping the same areas of the file.
|
43
|
+
The default value is ((|Mmap::MAP_SHARED|))
|
44
|
+
|
45
|
+
: ((|Mmap::MAP_PRIVATE|))
|
46
|
+
Creates a private copy-on-write mapping, so changes to the
|
47
|
+
contents of the mmap object will be private to this process
|
48
|
+
|
49
|
+
: ((|options|))
|
50
|
+
Hash. If one of the options ((|length|)) or ((|offset|))
|
51
|
+
is specified it will not possible to modify the size of
|
52
|
+
the mapped file.
|
53
|
+
|
54
|
+
: ((|length|))
|
55
|
+
Maps ((|length|)) bytes from the file
|
56
|
+
|
57
|
+
: ((|offset|))
|
58
|
+
The mapping begin at ((|offset|))
|
59
|
+
|
60
|
+
: ((|advice|))
|
61
|
+
The type of the access (see #madvise)
|
62
|
+
|
63
|
+
|
64
|
+
--- unlockall
|
65
|
+
reenable paging
|
66
|
+
|
67
|
+
== Methods
|
68
|
+
|
69
|
+
--- extend(count)
|
70
|
+
add ((|count|)) bytes to the file (i.e. pre-extend the file)
|
71
|
+
|
72
|
+
--- madvise(advice)
|
73
|
+
((|advice|)) can have the value ((|Mmap::MADV_NORMAL|)),
|
74
|
+
((|Mmap::MADV_RANDOM|)), ((|Mmap::MADV_SEQUENTIAL|)),
|
75
|
+
((|Mmap::MADV_WILLNEED|)), ((|Mmap::MADV_DONTNEED|))
|
76
|
+
|
77
|
+
--- mprotect(mode)
|
78
|
+
change the mode, value must be "r", "w" or "rw"
|
79
|
+
|
80
|
+
--- mlock
|
81
|
+
disable paging
|
82
|
+
|
83
|
+
--- msync
|
84
|
+
--- flush
|
85
|
+
flush the file
|
86
|
+
|
87
|
+
--- munlock
|
88
|
+
reenable paging
|
89
|
+
|
90
|
+
--- munmap
|
91
|
+
terminate the association
|
92
|
+
|
93
|
+
=== Other methods with the same syntax than for the class String
|
94
|
+
|
95
|
+
|
96
|
+
--- self == other
|
97
|
+
comparison
|
98
|
+
|
99
|
+
--- self > other
|
100
|
+
comparison
|
101
|
+
|
102
|
+
--- self >= other
|
103
|
+
comparison
|
104
|
+
|
105
|
+
--- self < other
|
106
|
+
comparison
|
107
|
+
|
108
|
+
--- self <= other
|
109
|
+
comparison
|
110
|
+
|
111
|
+
--- self === other
|
112
|
+
used for ((|case|)) comparison
|
113
|
+
|
114
|
+
--- self << other
|
115
|
+
append ((|other|)) to ((|self|))
|
116
|
+
|
117
|
+
--- self =~ other
|
118
|
+
return an index of the match
|
119
|
+
|
120
|
+
--- self[nth]
|
121
|
+
retrieve the ((|nth|)) character
|
122
|
+
|
123
|
+
--- self[start..last]
|
124
|
+
return a substring from ((|start|)) to ((|last|))
|
125
|
+
|
126
|
+
--- self[start, length]
|
127
|
+
return a substring of ((|lenght|)) characters from ((|start|))
|
128
|
+
|
129
|
+
--- self[nth] = val
|
130
|
+
change the ((|nth|)) character with ((|val|))
|
131
|
+
|
132
|
+
--- self[start..last] = val
|
133
|
+
change substring from ((|start|)) to ((|last|)) with ((|val|))
|
134
|
+
|
135
|
+
--- self[start, len] = val
|
136
|
+
replace ((|length|)) characters from ((|start|)) with ((|val|)).
|
137
|
+
|
138
|
+
--- self <=> other
|
139
|
+
comparison : return -1, 0, 1
|
140
|
+
|
141
|
+
--- casecmp(other) >= 1.7.1
|
142
|
+
|
143
|
+
--- concat(other)
|
144
|
+
append the contents of ((|other|))
|
145
|
+
|
146
|
+
--- capitalize!
|
147
|
+
change the first character to uppercase letter
|
148
|
+
|
149
|
+
--- chop!
|
150
|
+
chop off the last character
|
151
|
+
|
152
|
+
--- chomp!([rs])
|
153
|
+
chop off the line ending character, specified by ((|rs|))
|
154
|
+
|
155
|
+
--- count(o1 [, o2, ...])
|
156
|
+
each parameter defines a set of character to count
|
157
|
+
|
158
|
+
--- crypt(salt)
|
159
|
+
crypt with ((|salt|))
|
160
|
+
|
161
|
+
--- delete!(str)
|
162
|
+
delete every characters included in ((|str|))
|
163
|
+
|
164
|
+
--- downcase!
|
165
|
+
change all uppercase character to lowercase character
|
166
|
+
|
167
|
+
--- each_byte {|char|...}
|
168
|
+
iterate on each byte
|
169
|
+
|
170
|
+
--- each([rs]) {|line|...}
|
171
|
+
--- each_line([rs]) {|line|...}
|
172
|
+
iterate on each line
|
173
|
+
|
174
|
+
--- empty?
|
175
|
+
return ((|true|)) if the file is empty
|
176
|
+
|
177
|
+
--- freeze
|
178
|
+
freeze the current file
|
179
|
+
|
180
|
+
--- frozen
|
181
|
+
return ((|true|)) if the file is frozen
|
182
|
+
|
183
|
+
--- gsub!(pattern, replace)
|
184
|
+
global substitution
|
185
|
+
|
186
|
+
--- gsub!(pattern) {|str|...}
|
187
|
+
global substitution
|
188
|
+
|
189
|
+
--- include?(other)
|
190
|
+
return ((|true|)) if ((|other|)) is found
|
191
|
+
|
192
|
+
--- index(substr[, pos])
|
193
|
+
return the index of ((|substr|))
|
194
|
+
|
195
|
+
--- insert(index, str) >= 1.7.1
|
196
|
+
insert ((|str|)) at ((|index|))
|
197
|
+
|
198
|
+
--- length
|
199
|
+
return the size of the file
|
200
|
+
|
201
|
+
--- reverse!
|
202
|
+
reverse the content of the file
|
203
|
+
|
204
|
+
--- rindex(substr[, pos])
|
205
|
+
return the index of the last occurrence of ((|substr|))
|
206
|
+
|
207
|
+
--- scan(pattern)
|
208
|
+
return an array of all occurence matched by ((|pattern|))
|
209
|
+
|
210
|
+
--- scan(pattern) {|str| ...}
|
211
|
+
iterate through the file, matching the ((|pattern|))
|
212
|
+
|
213
|
+
--- size
|
214
|
+
return the size of the file
|
215
|
+
|
216
|
+
--- slice
|
217
|
+
same than ((|[]|))
|
218
|
+
|
219
|
+
--- slice!
|
220
|
+
delete the specified portion of the file
|
221
|
+
|
222
|
+
--- split([sep[, limit]])
|
223
|
+
splits into a list of strings and return this array
|
224
|
+
|
225
|
+
--- squeeze!([str])
|
226
|
+
squeezes sequences of the same characters which is included in ((|str|))
|
227
|
+
|
228
|
+
--- strip!
|
229
|
+
removes leading and trailing whitespace
|
230
|
+
|
231
|
+
--- sub!(pattern, replace)
|
232
|
+
substitution
|
233
|
+
|
234
|
+
--- sub!(pattern) {|str| ...}
|
235
|
+
substitution
|
236
|
+
|
237
|
+
--- sum([bits])
|
238
|
+
return a checksum
|
239
|
+
|
240
|
+
--- swapcase!
|
241
|
+
replaces all lowercase characters to uppercase characters, and vice-versa
|
242
|
+
|
243
|
+
--- tr!(search, replace)
|
244
|
+
translate the character from ((|search|)) to ((|replace|))
|
245
|
+
|
246
|
+
--- tr_s!(search, replace)
|
247
|
+
translate the character from ((|search|)) to ((|replace|)), then
|
248
|
+
squeeze sequence of the same characters
|
249
|
+
|
250
|
+
--- upcase!
|
251
|
+
replaces all lowercase characters to downcase characters
|
252
|
+
|
253
|
+
=end
|
data/test/test_mmap.rb
ADDED
@@ -0,0 +1,373 @@
|
|
1
|
+
require 'mmap'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
class TestMmap < Minitest::Test
|
7
|
+
EXT_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', 'ext', 'mmap'))
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@tmp = Dir.tmpdir
|
11
|
+
FileUtils.cp(File.join(EXT_DIR, 'mmap.c'), @tmp)
|
12
|
+
|
13
|
+
@mmap_c = File.join(@tmp, 'mmap.c')
|
14
|
+
|
15
|
+
@mmap = Mmap.new(@mmap_c, "rw")
|
16
|
+
@str = File.read @mmap_c
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
@mmap.unmap
|
21
|
+
aa = File.join(@tmp, 'aa')
|
22
|
+
bb = File.join(@tmp, 'bb')
|
23
|
+
FileUtils.rm(aa) if File.exist?(aa)
|
24
|
+
FileUtils.rm(bb) if File.exist?(bb)
|
25
|
+
end
|
26
|
+
|
27
|
+
def internal_read
|
28
|
+
File.readlines(@mmap_c, nil)[0]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_inspect
|
32
|
+
assert @mmap.inspect
|
33
|
+
end
|
34
|
+
|
35
|
+
# Make sure clone raises. Cloning would be bad.
|
36
|
+
def test_clone
|
37
|
+
assert_raises(TypeError) do
|
38
|
+
@mmap.clone
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Make sure dup raises. Cloning would be bad.
|
43
|
+
def test_dup
|
44
|
+
assert_raises(TypeError) do
|
45
|
+
@mmap.dup
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_length
|
50
|
+
assert_equal(@mmap.length, @str.length, "<lenght>")
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_simple_aref
|
54
|
+
assert_equal(@str[10], @mmap[10], "<aref>");
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_aref
|
58
|
+
max = @str.size * 2
|
59
|
+
72.times do
|
60
|
+
ran1 = rand(max)
|
61
|
+
assert_equal(@str[ran1], @mmap[ran1], "<aref>");
|
62
|
+
assert_equal(@str[-ran1], @mmap[-ran1], "<aref>");
|
63
|
+
ran2 = rand(max)
|
64
|
+
assert_equal(@str[ran1, ran2], @mmap[ran1, ran2], "<double aref>");
|
65
|
+
assert_equal(@str[-ran1, ran2], @mmap[-ran1, ran2], "<double aref>");
|
66
|
+
assert_equal(@str[ran1, -ran2], @mmap[ran1, -ran2], "<double aref>");
|
67
|
+
assert_equal(@str[-ran1, -ran2], @mmap[-ran1, -ran2], "<double aref>");
|
68
|
+
assert_equal(@str[ran1 .. ran2], @mmap[ran1 .. ran2], "<double aref>");
|
69
|
+
assert_equal(@str[-ran1 .. ran2], @mmap[-ran1 .. ran2], "<double aref>");
|
70
|
+
assert_equal(@str[ran1 .. -ran2], @mmap[ran1 .. -ran2], "<double aref>");
|
71
|
+
assert_equal(@str[-ran1 .. -ran2], @mmap[-ran1 .. -ran2], "<double aref>");
|
72
|
+
end
|
73
|
+
assert_equal(@str[/random/], @mmap[/random/], "<aref regexp>")
|
74
|
+
assert_equal(@str[/real/], @mmap[/real/], "<aref regexp>")
|
75
|
+
assert_equal(@str[/none/], @mmap[/none/], "<aref regexp>")
|
76
|
+
end
|
77
|
+
|
78
|
+
def internal_aset(a, b = nil, c = true)
|
79
|
+
access = if b
|
80
|
+
repl = ''
|
81
|
+
rand(12).times do
|
82
|
+
repl << (65 + rand(25))
|
83
|
+
end
|
84
|
+
if c
|
85
|
+
"[a, b] = '#{repl}'"
|
86
|
+
else
|
87
|
+
"[a .. b] = '#{repl}'"
|
88
|
+
end
|
89
|
+
else
|
90
|
+
"[a] = #{(65 + rand(25))}.chr"
|
91
|
+
end
|
92
|
+
begin
|
93
|
+
eval "@str#{access}"
|
94
|
+
rescue IndexError, RangeError
|
95
|
+
begin
|
96
|
+
eval "@mmap#{access}"
|
97
|
+
rescue IndexError, RangeError
|
98
|
+
else
|
99
|
+
flunk("*must* fail with IndexError")
|
100
|
+
end
|
101
|
+
else
|
102
|
+
eval "@mmap#{access}"
|
103
|
+
end
|
104
|
+
assert_equal(@mmap.to_str, @str, "<internal aset>")
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_aset
|
108
|
+
@mmap[/...../] = "change it"
|
109
|
+
@str[/...../] = "change it"
|
110
|
+
assert_equal(@mmap.to_str, @str, "aset regexp")
|
111
|
+
@mmap["ge i"] = "change it"
|
112
|
+
@str["ge i"] = "change it"
|
113
|
+
assert_equal(@mmap.to_str, @str, "aset regexp")
|
114
|
+
max = @str.size * 2
|
115
|
+
72.times do
|
116
|
+
ran1 = rand(max)
|
117
|
+
internal_aset(ran1)
|
118
|
+
internal_aset(-ran1)
|
119
|
+
ran2 = rand(max)
|
120
|
+
internal_aset(ran1, ran2)
|
121
|
+
internal_aset(ran1, -ran2)
|
122
|
+
internal_aset(-ran1, ran2)
|
123
|
+
internal_aset(-ran1, -ran2)
|
124
|
+
internal_aset(ran1, ran2, false)
|
125
|
+
internal_aset(ran1, -ran2, false)
|
126
|
+
internal_aset(-ran1, ran2, false)
|
127
|
+
internal_aset(-ran1, -ran2, false)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def internal_slice(a, b = nil, c = true)
|
132
|
+
access = if b
|
133
|
+
if c
|
134
|
+
".slice!(a, b)"
|
135
|
+
else
|
136
|
+
".slice!(a .. b)"
|
137
|
+
end
|
138
|
+
else
|
139
|
+
".slice!(a)"
|
140
|
+
end
|
141
|
+
begin
|
142
|
+
eval "@str#{access}"
|
143
|
+
rescue IndexError, RangeError
|
144
|
+
begin
|
145
|
+
eval "@mmap#{access}"
|
146
|
+
rescue IndexError, RangeError
|
147
|
+
else
|
148
|
+
flunk("*must* fail with IndexError")
|
149
|
+
end
|
150
|
+
else
|
151
|
+
eval "@mmap#{access}"
|
152
|
+
end
|
153
|
+
assert_equal(@mmap.to_str, @str, "<internal aset>")
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_slice
|
157
|
+
max = @str.size * 2
|
158
|
+
72.times do
|
159
|
+
ran1 = rand(max)
|
160
|
+
internal_slice(ran1)
|
161
|
+
internal_slice(-ran1)
|
162
|
+
ran2 = rand(max)
|
163
|
+
internal_slice(ran1, ran2)
|
164
|
+
internal_slice(ran1, -ran2)
|
165
|
+
internal_slice(-ran1, ran2)
|
166
|
+
internal_slice(-ran1, -ran2)
|
167
|
+
internal_slice(ran1, ran2, false)
|
168
|
+
internal_slice(ran1, -ran2, false)
|
169
|
+
internal_slice(-ran1, ran2, false)
|
170
|
+
internal_slice(-ran1, -ran2, false)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_easy_sub!
|
175
|
+
assert_equal(@mmap.index("rb_raise"), @mmap.index("rb_raise"), "<index>")
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_reg
|
179
|
+
assert_equal(@str.scan(/include/), @mmap.scan(/include/), "<scan>")
|
180
|
+
assert_equal(@mmap.index("rb_raise"), @mmap.index("rb_raise"), "<index>")
|
181
|
+
assert_equal(@mmap.rindex("rb_raise"), @mmap.rindex("rb_raise"), "<rindex>")
|
182
|
+
assert_equal(@mmap.index(/rb_raise/), @mmap.index(/rb_raise/), "<index>")
|
183
|
+
assert_equal(@mmap.rindex(/rb_raise/), @mmap.rindex(/rb_raise/), "<rindex>")
|
184
|
+
('a' .. 'z').each do |i|
|
185
|
+
assert_equal(@mmap.index(i), @str.index(i), "<index>")
|
186
|
+
assert_equal(@mmap.rindex(i), @str.rindex(i), "<rindex>")
|
187
|
+
assert_equal(@mmap.index(i), @str.index(/#{i}/), "<index>")
|
188
|
+
assert_equal(@mmap.rindex(i), @str.rindex(/#{i}/), "<rindex>")
|
189
|
+
end
|
190
|
+
@mmap.sub!(/GetMmap/, 'XXXX'); @str.sub!(/GetMmap/, 'XXXX')
|
191
|
+
assert_equal(@str, @mmap.to_str, "<after sub!>")
|
192
|
+
@mmap.gsub!(/GetMmap/, 'XXXX'); @str.gsub!(/GetMmap/, 'XXXX')
|
193
|
+
assert_equal(@mmap.to_str, @str, "<after gsub!>")
|
194
|
+
@mmap.gsub!(/YYYY/, 'XXXX'); @str.gsub!(/YYYY/, 'XXXX')
|
195
|
+
assert_equal(@mmap.to_str, @str, "<after gsub!>")
|
196
|
+
assert_equal(@mmap.split(/\w+/), @str.split(/\w+/), "<split>")
|
197
|
+
assert_equal(@mmap.split(/\W+/), @str.split(/\W+/), "<split>")
|
198
|
+
assert_equal(@mmap.crypt("abc"), @str.crypt("abc"), "<crypt>")
|
199
|
+
end
|
200
|
+
|
201
|
+
def internal_modify idmod, *args
|
202
|
+
if res = @str.method(idmod)[*args]
|
203
|
+
assert_equal(@mmap.method(idmod)[*args].to_str, res, "<#{idmod}>")
|
204
|
+
else
|
205
|
+
assert_equal(@mmap.method(idmod)[*args], res, "<#{idmod}>")
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_modify
|
210
|
+
skip "pending"
|
211
|
+
internal_modify(:reverse!)
|
212
|
+
internal_modify(:upcase!)
|
213
|
+
internal_modify(:downcase!)
|
214
|
+
internal_modify(:capitalize!)
|
215
|
+
internal_modify(:swapcase!)
|
216
|
+
internal_modify(:strip!)
|
217
|
+
internal_modify(:chop!)
|
218
|
+
internal_modify(:chomp!)
|
219
|
+
internal_modify(:squeeze!)
|
220
|
+
internal_modify(:tr!, 'abcdefghi', '123456789')
|
221
|
+
internal_modify(:tr_s!, 'jklmnopqr', '123456789')
|
222
|
+
internal_modify(:delete!, 'A-Z')
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_iterate
|
226
|
+
mmap = []; @mmap.each_byte {|l| mmap << l}
|
227
|
+
str = []; @str.each_byte {|l| str << l}
|
228
|
+
assert_equal(mmap, str, "<each_byte>")
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_concat
|
232
|
+
[@mmap, @str].each {|l| l << "bc"; l << 12; l << "ab"}
|
233
|
+
assert_equal(@mmap.to_str, @str, "<<")
|
234
|
+
assert_raises(TypeError) { @mmap << 456 }
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_extend
|
238
|
+
@mmap.extend(4096)
|
239
|
+
assert_equal(@mmap.to_str, @str, "extend")
|
240
|
+
if @str.respond_to?(:insert)
|
241
|
+
10.times do
|
242
|
+
pos = rand(@mmap.size)
|
243
|
+
str = "XX" * rand(66)
|
244
|
+
@str.insert(pos, str)
|
245
|
+
@mmap.insert(pos, str)
|
246
|
+
assert_equal(@mmap.to_str, @str, "insert")
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_msync
|
252
|
+
3.times do |i|
|
253
|
+
[@mmap, @str].each {|l| l << "x" * 4096 }
|
254
|
+
str = internal_read
|
255
|
+
if str != @mmap.to_str
|
256
|
+
@mmap.msync
|
257
|
+
assert_equal(@mmap.to_str, internal_read, "msync")
|
258
|
+
break
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_protect
|
264
|
+
assert_equal(@mmap, @mmap.protect("w"), "protect")
|
265
|
+
assert_equal("a", @mmap[12] = "a", "affect")
|
266
|
+
@str[12] = "a"
|
267
|
+
assert_equal(@mmap.to_str, @str, "protect")
|
268
|
+
assert_raises(TypeError) { @mmap << "a" }
|
269
|
+
assert_equal(@mmap, @mmap.protect("r"), "protect")
|
270
|
+
assert_raises(RuntimeError) { @mmap[12] = "a" }
|
271
|
+
assert_raises(RuntimeError) { @mmap.protect("rw") }
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_anonymous
|
275
|
+
if defined?(Mmap::MAP_ANONYMOUS)
|
276
|
+
assert_kind_of(Mmap, @mmap =
|
277
|
+
Mmap.new(nil, "length" => 8192, "offset" => 12,
|
278
|
+
"increment" => 1024, "initialize" => " "))
|
279
|
+
@str = " " * 8192
|
280
|
+
1024.times do
|
281
|
+
pos = rand(8192)
|
282
|
+
@mmap[pos] = @str[pos] = (32 + rand(64)).chr
|
283
|
+
end
|
284
|
+
assert_equal(@mmap.to_str, @str, "insert anonymous")
|
285
|
+
assert_raises(IndexError) { @mmap[12345] = "a" }
|
286
|
+
assert_raises(TypeError) { @mmap << "a" }
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_fileno
|
291
|
+
@mmap = Mmap.new(File.new(@mmap_c, "r+"), "rw")
|
292
|
+
test_aref
|
293
|
+
@mmap[12] = "3"; @str[12] = "3"
|
294
|
+
assert_equal(@mmap.to_str, @str, "insert io")
|
295
|
+
assert_equal(0, @mmap <=> @str, "cmp")
|
296
|
+
assert_raises(TypeError) { @mmap[12] = "ab" }
|
297
|
+
@mmap.freeze
|
298
|
+
if @str.respond_to?(:match)
|
299
|
+
assert_equal(@str.match("rb_match_busy").offset(0),
|
300
|
+
@mmap.match("rb_match_busy").offset(0), "match")
|
301
|
+
assert_equal(@str.match(/rb_../).offset(0),
|
302
|
+
@mmap.match(/rb_../).offset(0), "match")
|
303
|
+
assert_equal(@str.match("rb_match_buzy"),
|
304
|
+
@mmap.match("rb_match_buzy"), "no match")
|
305
|
+
assert_equal(@str =~ /rb_match_busy/,
|
306
|
+
@mmap =~ /rb_match_busy/, "match")
|
307
|
+
assert_equal(@str =~ /rb_match_buzy/,
|
308
|
+
@mmap =~ /rb_match_buzy/, "no match")
|
309
|
+
end
|
310
|
+
assert_raises(RuntimeError) { @mmap[12] = "a" }
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_div
|
314
|
+
string = "azertyuiopqsdfghjklm"
|
315
|
+
assert_kind_of(Mmap, m0 = Mmap.new("#{@tmp}/aa", "a"), "new a")
|
316
|
+
File.open("#{@tmp}/bb", "w") {|f| f.puts "aaa" }
|
317
|
+
assert_kind_of(Mmap, m1 = Mmap.new("#{@tmp}/bb", "w"), "new a")
|
318
|
+
assert_equal(true, m0.empty?, "empty")
|
319
|
+
assert_equal(true, m1.empty?, "empty")
|
320
|
+
assert_equal(m0, m0 << string, "<<")
|
321
|
+
assert_equal(m1, m1 << string, "<<")
|
322
|
+
assert_equal(false, m0.empty?, "empty")
|
323
|
+
assert_equal(false, m1.empty?, "empty")
|
324
|
+
assert_equal(true, m0 == m1, "==")
|
325
|
+
if string.respond_to?(:casecmp)
|
326
|
+
assert_equal(0, m0.casecmp(string.upcase), "casecmp")
|
327
|
+
assert_equal(0, m0.casecmp(m1), "casecmp")
|
328
|
+
end
|
329
|
+
assert_equal(true, m0 === m1, "===")
|
330
|
+
assert_equal(false, m0 === string, "===")
|
331
|
+
assert_equal(true, m0.eql?(m1), ".eql?")
|
332
|
+
assert_equal(true, m1.eql?(m0), ".eql?")
|
333
|
+
assert_equal(false, m1.eql?(string), ".eql?")
|
334
|
+
assert_equal(m0.hash, m1.hash, "hash")
|
335
|
+
assert_equal(true, m0.include?("azert"), "include")
|
336
|
+
assert_equal(false, m1.include?("aqert"), "include")
|
337
|
+
i = 0
|
338
|
+
m0.scan(/./) {|c| assert_equal(c, string[i,1], "scan"); i += 1}
|
339
|
+
assert_nil(m0.munmap, "munmap")
|
340
|
+
assert_nil(m1.munmap, "munmap")
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_other
|
344
|
+
test_div
|
345
|
+
if File.exist?("#{@tmp}/aa")
|
346
|
+
string = "azertyuiopqsdfghjklm"
|
347
|
+
assert_kind_of(Mmap, m0 = Mmap.new("#{@tmp}/aa", "r"), "new r")
|
348
|
+
assert_equal(string, m0.to_str, "content")
|
349
|
+
assert_raises(RuntimeError) { m0[0] = 12 }
|
350
|
+
assert_raises(RuntimeError) { m0 << 12 }
|
351
|
+
assert_nil(m0.munmap, "munmap")
|
352
|
+
if defined?(Mmap::MAP_ANONYMOUS)
|
353
|
+
assert_raises(ArgumentError) { Mmap.new(nil, "w") }
|
354
|
+
assert_kind_of(Mmap, m0 = Mmap.new(nil, 12), "new w")
|
355
|
+
assert_equal(false, m0.empty?, "empty")
|
356
|
+
assert_equal("a", m0[0] = "a", "set")
|
357
|
+
assert_raises(TypeError) { m0 << 12 }
|
358
|
+
if defined?(Mmap::MADV_DONTNEED)
|
359
|
+
assert_nil(m0.advise(Mmap::MADV_DONTNEED), "advise")
|
360
|
+
assert_equal("a", m0[0,1], "get")
|
361
|
+
end
|
362
|
+
assert_equal(m0, m0.sub!(/./) { "y" }, "sub")
|
363
|
+
assert_equal(m0, m0.gsub!(/./) { "x" }, "gsub")
|
364
|
+
assert_equal("x" * 12, m0.to_str, "retrieve")
|
365
|
+
assert_equal("ab", m0[1..2] = "ab", "range")
|
366
|
+
assert_raises(TypeError) { m0[1..2] = "abc" }
|
367
|
+
assert_raises(ArgumentError) { m0.lock }
|
368
|
+
assert_raises(ArgumentError) { Mmap::lockall(0) }
|
369
|
+
assert_nil(m0.munmap, "munmap")
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mmap2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.2.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guy Decoux
|
8
|
+
- Aaron Patterson
|
9
|
+
- Kevin Lyda
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2017-02-15 00:00:00.000000000 Z
|
14
|
+
dependencies: []
|
15
|
+
description: The Mmap class implement memory-mapped file objects for Ruby 2.x
|
16
|
+
email:
|
17
|
+
- ts@moulon.inra.fr
|
18
|
+
- tenderlove@github.com
|
19
|
+
- lyda@gitlab.com
|
20
|
+
executables: []
|
21
|
+
extensions:
|
22
|
+
- ext/mmap/extconf.rb
|
23
|
+
extra_rdoc_files: []
|
24
|
+
files:
|
25
|
+
- Changes
|
26
|
+
- README.rdoc
|
27
|
+
- b.rb
|
28
|
+
- ext/mmap/extconf.rb
|
29
|
+
- ext/mmap/mmap.c
|
30
|
+
- lib/mmap.rb
|
31
|
+
- lib/mmap/version.rb
|
32
|
+
- mmap.rd
|
33
|
+
- test/test_mmap.rb
|
34
|
+
homepage: https://gitlab.com/lyda/mmap
|
35
|
+
licenses:
|
36
|
+
- Ruby
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.5.1
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: The Mmap class
|
58
|
+
test_files:
|
59
|
+
- b.rb
|
60
|
+
- test/test_mmap.rb
|