mmap 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes +55 -0
- data/Manifest.txt +11 -0
- data/README.rdoc +36 -0
- data/Rakefile +27 -0
- data/b.rb +33 -0
- data/ext/mmap/extconf.rb +32 -0
- data/ext/mmap/mmap.c +2624 -0
- data/lib/mmap.rb +22 -0
- data/mmap.html +272 -0
- data/mmap.rd +253 -0
- data/test/test_mmap.rb +367 -0
- metadata +88 -0
data/test/test_mmap.rb
ADDED
@@ -0,0 +1,367 @@
|
|
1
|
+
require 'mmap'
|
2
|
+
require 'ftools'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestMmap < Test::Unit::TestCase
|
7
|
+
EXT_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..', 'ext', 'mmap'))
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@tmp = Dir.tmpdir
|
11
|
+
File.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_aref
|
54
|
+
max = @str.size * 2
|
55
|
+
72.times do
|
56
|
+
ran1 = rand(max)
|
57
|
+
assert_equal(@mmap[ran1], @str[ran1], "<aref>");
|
58
|
+
assert_equal(@mmap[-ran1], @str[-ran1], "<aref>");
|
59
|
+
ran2 = rand(max)
|
60
|
+
assert_equal(@mmap[ran1, ran2], @str[ran1, ran2], "<double aref>");
|
61
|
+
assert_equal(@mmap[-ran1, ran2], @str[-ran1, ran2], "<double aref>");
|
62
|
+
assert_equal(@mmap[ran1, -ran2], @str[ran1, -ran2], "<double aref>");
|
63
|
+
assert_equal(@mmap[-ran1, -ran2], @str[-ran1, -ran2], "<double aref>");
|
64
|
+
assert_equal(@mmap[ran1 .. ran2], @str[ran1 .. ran2], "<double aref>");
|
65
|
+
assert_equal(@mmap[-ran1 .. ran2], @str[-ran1 .. ran2], "<double aref>");
|
66
|
+
assert_equal(@mmap[ran1 .. -ran2], @str[ran1 .. -ran2], "<double aref>");
|
67
|
+
assert_equal(@mmap[-ran1 .. -ran2], @str[-ran1 .. -ran2], "<double aref>");
|
68
|
+
end
|
69
|
+
assert_equal(@mmap[/random/], @str[/random/], "<aref regexp>")
|
70
|
+
assert_equal(@mmap[/real/], @str[/real/], "<aref regexp>")
|
71
|
+
assert_equal(@mmap[/none/], @str[/none/], "<aref regexp>")
|
72
|
+
end
|
73
|
+
|
74
|
+
def internal_aset(a, b = nil, c = true)
|
75
|
+
access = if b
|
76
|
+
repl = ''
|
77
|
+
rand(12).times do
|
78
|
+
repl << (65 + rand(25))
|
79
|
+
end
|
80
|
+
if c
|
81
|
+
"[a, b] = '#{repl}'"
|
82
|
+
else
|
83
|
+
"[a .. b] = '#{repl}'"
|
84
|
+
end
|
85
|
+
else
|
86
|
+
"[a] = #{(65 + rand(25))}"
|
87
|
+
end
|
88
|
+
begin
|
89
|
+
eval "@str#{access}"
|
90
|
+
rescue IndexError, RangeError
|
91
|
+
begin
|
92
|
+
eval "@mmap#{access}"
|
93
|
+
rescue IndexError, RangeError
|
94
|
+
else
|
95
|
+
flunk("*must* fail with IndexError")
|
96
|
+
end
|
97
|
+
else
|
98
|
+
eval "@mmap#{access}"
|
99
|
+
end
|
100
|
+
assert_equal(@mmap.to_str, @str, "<internal aset>")
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_aset
|
104
|
+
@mmap[/...../] = "change it"
|
105
|
+
@str[/...../] = "change it"
|
106
|
+
assert_equal(@mmap.to_str, @str, "aset regexp")
|
107
|
+
@mmap["ge i"] = "change it"
|
108
|
+
@str["ge i"] = "change it"
|
109
|
+
assert_equal(@mmap.to_str, @str, "aset regexp")
|
110
|
+
max = @str.size * 2
|
111
|
+
72.times do
|
112
|
+
ran1 = rand(max)
|
113
|
+
internal_aset(ran1)
|
114
|
+
internal_aset(-ran1)
|
115
|
+
ran2 = rand(max)
|
116
|
+
internal_aset(ran1, ran2)
|
117
|
+
internal_aset(ran1, -ran2)
|
118
|
+
internal_aset(-ran1, ran2)
|
119
|
+
internal_aset(-ran1, -ran2)
|
120
|
+
internal_aset(ran1, ran2, false)
|
121
|
+
internal_aset(ran1, -ran2, false)
|
122
|
+
internal_aset(-ran1, ran2, false)
|
123
|
+
internal_aset(-ran1, -ran2, false)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def internal_slice(a, b = nil, c = true)
|
128
|
+
access = if b
|
129
|
+
if c
|
130
|
+
".slice!(a, b)"
|
131
|
+
else
|
132
|
+
".slice!(a .. b)"
|
133
|
+
end
|
134
|
+
else
|
135
|
+
".slice!(a)"
|
136
|
+
end
|
137
|
+
begin
|
138
|
+
eval "@str#{access}"
|
139
|
+
rescue IndexError, RangeError
|
140
|
+
begin
|
141
|
+
eval "@mmap#{access}"
|
142
|
+
rescue IndexError, RangeError
|
143
|
+
else
|
144
|
+
flunk("*must* fail with IndexError")
|
145
|
+
end
|
146
|
+
else
|
147
|
+
eval "@mmap#{access}"
|
148
|
+
end
|
149
|
+
assert_equal(@mmap.to_str, @str, "<internal aset>")
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_slice
|
153
|
+
max = @str.size * 2
|
154
|
+
72.times do
|
155
|
+
ran1 = rand(max)
|
156
|
+
internal_slice(ran1)
|
157
|
+
internal_slice(-ran1)
|
158
|
+
ran2 = rand(max)
|
159
|
+
internal_slice(ran1, ran2)
|
160
|
+
internal_slice(ran1, -ran2)
|
161
|
+
internal_slice(-ran1, ran2)
|
162
|
+
internal_slice(-ran1, -ran2)
|
163
|
+
internal_slice(ran1, ran2, false)
|
164
|
+
internal_slice(ran1, -ran2, false)
|
165
|
+
internal_slice(-ran1, ran2, false)
|
166
|
+
internal_slice(-ran1, -ran2, false)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_reg
|
171
|
+
assert_equal(@mmap.scan(/include/), @str.scan(/include/), "<scan>")
|
172
|
+
assert_equal(@mmap.index("rb_raise"), @str.index("rb_raise"), "<index>")
|
173
|
+
assert_equal(@mmap.rindex("rb_raise"), @str.rindex("rb_raise"), "<rindex>")
|
174
|
+
assert_equal(@mmap.index(/rb_raise/), @str.index(/rb_raise/), "<index>")
|
175
|
+
assert_equal(@mmap.rindex(/rb_raise/), @str.rindex(/rb_raise/), "<rindex>")
|
176
|
+
('a' .. 'z').each do |i|
|
177
|
+
assert_equal(@mmap.index(i), @str.index(i), "<index>")
|
178
|
+
assert_equal(@mmap.rindex(i), @str.rindex(i), "<rindex>")
|
179
|
+
assert_equal(@mmap.index(i), @str.index(/#{i}/), "<index>")
|
180
|
+
assert_equal(@mmap.rindex(i), @str.rindex(/#{i}/), "<rindex>")
|
181
|
+
end
|
182
|
+
@mmap.sub!(/GetMmap/, 'XXXX'); @str.sub!(/GetMmap/, 'XXXX')
|
183
|
+
assert_equal(@mmap.to_str, @str, "<after sub!>")
|
184
|
+
@mmap.gsub!(/GetMmap/, 'XXXX'); @str.gsub!(/GetMmap/, 'XXXX')
|
185
|
+
assert_equal(@mmap.to_str, @str, "<after gsub!>")
|
186
|
+
@mmap.gsub!(/YYYY/, 'XXXX'); @str.gsub!(/YYYY/, 'XXXX')
|
187
|
+
assert_equal(@mmap.to_str, @str, "<after gsub!>")
|
188
|
+
assert_equal(@mmap.split(/\w+/), @str.split(/\w+/), "<split>")
|
189
|
+
assert_equal(@mmap.split(/\W+/), @str.split(/\W+/), "<split>")
|
190
|
+
assert_equal(@mmap.crypt("abc"), @str.crypt("abc"), "<crypt>")
|
191
|
+
end
|
192
|
+
|
193
|
+
def internal_modify idmod, *args
|
194
|
+
if res = @str.method(idmod)[*args]
|
195
|
+
assert_equal(@mmap.method(idmod)[*args].to_str, res, "<#{idmod}>")
|
196
|
+
else
|
197
|
+
assert_equal(@mmap.method(idmod)[*args], res, "<#{idmod}>")
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_modify
|
202
|
+
internal_modify(:reverse!)
|
203
|
+
internal_modify(:upcase!)
|
204
|
+
internal_modify(:downcase!)
|
205
|
+
internal_modify(:capitalize!)
|
206
|
+
internal_modify(:swapcase!)
|
207
|
+
internal_modify(:strip!)
|
208
|
+
internal_modify(:chop!)
|
209
|
+
internal_modify(:chomp!)
|
210
|
+
internal_modify(:squeeze!)
|
211
|
+
internal_modify(:tr!, 'abcdefghi', '123456789')
|
212
|
+
internal_modify(:tr_s!, 'jklmnopqr', '123456789')
|
213
|
+
internal_modify(:delete!, 'A-Z')
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_iterate
|
217
|
+
mmap = []; @mmap.each {|l| mmap << l}
|
218
|
+
str = []; @str.each {|l| str << l}
|
219
|
+
assert_equal(mmap, str, "<each>")
|
220
|
+
mmap = []; @mmap.each_byte {|l| mmap << l}
|
221
|
+
str = []; @str.each_byte {|l| str << l}
|
222
|
+
assert_equal(mmap, str, "<each_byte>")
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_concat
|
226
|
+
[@mmap, @str].each {|l| l << "bc"; l << 12; l << "ab"}
|
227
|
+
assert_equal(@mmap.to_str, @str, "<<")
|
228
|
+
assert_raises(TypeError) { @mmap << 456 }
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_extend
|
232
|
+
@mmap.extend(4096)
|
233
|
+
assert_equal(@mmap.to_str, @str, "extend")
|
234
|
+
if @str.respond_to?(:insert)
|
235
|
+
10.times do
|
236
|
+
pos = rand(@mmap.size)
|
237
|
+
str = "XX" * rand(66)
|
238
|
+
@str.insert(pos, str)
|
239
|
+
@mmap.insert(pos, str)
|
240
|
+
assert_equal(@mmap.to_str, @str, "insert")
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_msync
|
246
|
+
3.times do |i|
|
247
|
+
[@mmap, @str].each {|l| l << "x" * 4096 }
|
248
|
+
str = internal_read
|
249
|
+
if str != @mmap.to_str
|
250
|
+
@mmap.msync
|
251
|
+
assert_equal(@mmap.to_str, internal_read, "msync")
|
252
|
+
break
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_protect
|
258
|
+
assert_equal(@mmap, @mmap.protect("w"), "protect")
|
259
|
+
assert_equal("a", @mmap[12] = "a", "affect")
|
260
|
+
@str[12] = "a"
|
261
|
+
assert_equal(@mmap.to_str, @str, "protect")
|
262
|
+
assert_raises(TypeError) { @mmap << "a" }
|
263
|
+
assert_equal(@mmap, @mmap.protect("r"), "protect")
|
264
|
+
assert_raises(TypeError) { @mmap[12] = "a" }
|
265
|
+
assert_raises(TypeError) { @mmap.protect("rw") }
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_anonymous
|
269
|
+
if defined?(Mmap::MAP_ANONYMOUS)
|
270
|
+
assert_kind_of(Mmap, @mmap =
|
271
|
+
Mmap.new(nil, "length" => 8192, "offset" => 12,
|
272
|
+
"increment" => 1024, "initialize" => " "))
|
273
|
+
@str = " " * 8192
|
274
|
+
1024.times do
|
275
|
+
pos = rand(8192)
|
276
|
+
@mmap[pos] = @str[pos] = 32 + rand(64)
|
277
|
+
end
|
278
|
+
assert_equal(@mmap.to_str, @str, "insert anonymous")
|
279
|
+
assert_raises(IndexError) { @mmap[12345] = "a" }
|
280
|
+
assert_raises(TypeError) { @mmap << "a" }
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_fileno
|
285
|
+
@mmap = Mmap.new(File.new(@mmap_c, "r+"), "rw")
|
286
|
+
test_aref
|
287
|
+
@mmap[12] = "3"; @str[12] = "3"
|
288
|
+
assert_equal(@mmap.to_str, @str, "insert io")
|
289
|
+
assert_equal(0, @mmap <=> @str, "cmp")
|
290
|
+
assert_raises(TypeError) { @mmap[12] = "ab" }
|
291
|
+
@mmap.freeze
|
292
|
+
if @str.respond_to?(:match)
|
293
|
+
assert_equal(@str.match("rb_match_busy").offset(0),
|
294
|
+
@mmap.match("rb_match_busy").offset(0), "match")
|
295
|
+
assert_equal(@str.match(/rb_../).offset(0),
|
296
|
+
@mmap.match(/rb_../).offset(0), "match")
|
297
|
+
assert_equal(@str.match("rb_match_buzy"),
|
298
|
+
@mmap.match("rb_match_buzy"), "no match")
|
299
|
+
assert_equal(@str =~ /rb_match_busy/,
|
300
|
+
@mmap =~ /rb_match_busy/, "match")
|
301
|
+
assert_equal(@str =~ /rb_match_buzy/,
|
302
|
+
@mmap =~ /rb_match_buzy/, "no match")
|
303
|
+
end
|
304
|
+
assert_raises(TypeError) { @mmap[12] = "a" }
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_div
|
308
|
+
string = "azertyuiopqsdfghjklm"
|
309
|
+
assert_kind_of(Mmap, m0 = Mmap.new("#{@tmp}/aa", "a"), "new a")
|
310
|
+
File.open("#{@tmp}/bb", "w") {|f| f.puts "aaa" }
|
311
|
+
assert_kind_of(Mmap, m1 = Mmap.new("#{@tmp}/bb", "w"), "new a")
|
312
|
+
assert_equal(true, m0.empty?, "empty")
|
313
|
+
assert_equal(true, m1.empty?, "empty")
|
314
|
+
assert_equal(m0, m0 << string, "<<")
|
315
|
+
assert_equal(m1, m1 << string, "<<")
|
316
|
+
assert_equal(false, m0.empty?, "empty")
|
317
|
+
assert_equal(false, m1.empty?, "empty")
|
318
|
+
assert_equal(true, m0 == m1, "==")
|
319
|
+
if string.respond_to?(:casecmp)
|
320
|
+
assert_equal(0, m0.casecmp(string.upcase), "casecmp")
|
321
|
+
assert_equal(0, m0.casecmp(m1), "casecmp")
|
322
|
+
end
|
323
|
+
assert_equal(true, m0 === m1, "===")
|
324
|
+
assert_equal(false, m0 === string, "===")
|
325
|
+
assert_equal(true, m0.eql?(m1), ".eql?")
|
326
|
+
assert_equal(true, m1.eql?(m0), ".eql?")
|
327
|
+
assert_equal(false, m1.eql?(string), ".eql?")
|
328
|
+
assert_equal(m0.hash, m1.hash, "hash")
|
329
|
+
assert_equal(true, m0.include?("azert"), "include")
|
330
|
+
assert_equal(false, m1.include?("aqert"), "include")
|
331
|
+
i = 0
|
332
|
+
m0.scan(/./) {|c| assert_equal(c, string[i,1], "scan"); i += 1}
|
333
|
+
assert_nil(m0.munmap, "munmap")
|
334
|
+
assert_nil(m1.munmap, "munmap")
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_other
|
338
|
+
test_div
|
339
|
+
if File.exist?("#{@tmp}/aa")
|
340
|
+
string = "azertyuiopqsdfghjklm"
|
341
|
+
assert_kind_of(Mmap, m0 = Mmap.new("#{@tmp}/aa", "r"), "new r")
|
342
|
+
assert_equal(string, m0.to_str, "content")
|
343
|
+
assert_raises(TypeError) { m0[0] = 12 }
|
344
|
+
assert_raises(TypeError) { m0 << 12 }
|
345
|
+
assert_nil(m0.munmap, "munmap")
|
346
|
+
if defined?(Mmap::MAP_ANONYMOUS)
|
347
|
+
assert_raises(ArgumentError) { Mmap.new(nil, "w") }
|
348
|
+
assert_kind_of(Mmap, m0 = Mmap.new(nil, 12), "new w")
|
349
|
+
assert_equal(false, m0.empty?, "empty")
|
350
|
+
assert_equal("a", m0[0] = "a", "set")
|
351
|
+
assert_raises(TypeError) { m0 << 12 }
|
352
|
+
if defined?(Mmap::MADV_DONTNEED)
|
353
|
+
assert_nil(m0.advise(Mmap::MADV_DONTNEED), "advise")
|
354
|
+
assert_equal("a", m0[0,1], "get")
|
355
|
+
end
|
356
|
+
assert_equal(m0, m0.sub!(/./) { "y" }, "sub")
|
357
|
+
assert_equal(m0, m0.gsub!(/./) { "x" }, "gsub")
|
358
|
+
assert_equal("x" * 12, m0.to_str, "retrieve")
|
359
|
+
assert_equal("ab", m0[1..2] = "ab", "range")
|
360
|
+
assert_raises(TypeError) { m0[1..2] = "abc" }
|
361
|
+
assert_raises(ArgumentError) { m0.lock }
|
362
|
+
assert_raises(ArgumentError) { Mmap::lockall(0) }
|
363
|
+
assert_nil(m0.munmap, "munmap")
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mmap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guy Decoux
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-07 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake-compiler
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.3
|
34
|
+
version:
|
35
|
+
description: The Mmap class implement memory-mapped file objects
|
36
|
+
email:
|
37
|
+
- ts@moulon.inra.fr
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions:
|
41
|
+
- ext/mmap/extconf.rb
|
42
|
+
extra_rdoc_files:
|
43
|
+
- Manifest.txt
|
44
|
+
- README.rdoc
|
45
|
+
files:
|
46
|
+
- Changes
|
47
|
+
- Manifest.txt
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- b.rb
|
51
|
+
- ext/mmap/extconf.rb
|
52
|
+
- ext/mmap/mmap.c
|
53
|
+
- lib/mmap.rb
|
54
|
+
- mmap.html
|
55
|
+
- mmap.rd
|
56
|
+
- test/test_mmap.rb
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://rubyforge.org/frs/?group_id=8350
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --main
|
64
|
+
- README.rdoc
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
- ext
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project: mmap
|
83
|
+
rubygems_version: 1.3.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: The Mmap class implement memory-mapped file objects
|
87
|
+
test_files:
|
88
|
+
- test/test_mmap.rb
|