|
7 | 7 |
|
8 | 8 | from random import randint |
9 | 9 | from time import time |
| 10 | +import os |
10 | 11 | import sys |
11 | 12 | from copy import copy |
12 | 13 |
|
@@ -62,110 +63,118 @@ def test_memory_manager(self): |
62 | 63 |
|
63 | 64 | # use a region, verify most basic functionality |
64 | 65 | fc = FileCreator(self.k_window_test_size, "manager_test") |
65 | | - c = man.make_cursor(fc.path) |
66 | | - assert c.use_region(10, 10).is_valid() |
67 | | - assert c.ofs_begin() == 10 |
68 | | - assert c.size() == 10 |
69 | | - assert c.buffer()[:] == open(fc.path, 'rb').read(20)[10:] |
| 66 | + fd = os.open(fc.path, os.O_RDONLY) |
| 67 | + for item in (fc.path, fd): |
| 68 | + c = man.make_cursor(item) |
| 69 | + assert c.use_region(10, 10).is_valid() |
| 70 | + assert c.ofs_begin() == 10 |
| 71 | + assert c.size() == 10 |
| 72 | + assert c.buffer()[:] == open(fc.path, 'rb').read(20)[10:] |
| 73 | + #END for each input |
| 74 | + os.close(fd) |
70 | 75 |
|
71 | 76 | def test_memman_operation(self): |
72 | 77 | # test more access, force it to actually unmap regions |
73 | 78 | fc = FileCreator(self.k_window_test_size, "manager_operation_test") |
74 | 79 | data = open(fc.path, 'rb').read() |
75 | | - assert len(data) == fc.size |
76 | | - |
77 | | - # small windows, a reasonable max memory. Not too many regions at once |
78 | | - max_num_handles = 15 |
79 | | - man = MappedMemoryManager(window_size=fc.size / 100, max_memory_size=fc.size / 3, max_open_handles=max_num_handles) |
80 | | - c = man.make_cursor(fc.path) |
81 | | - |
82 | | - # still empty (more about that is tested in test_memory_manager() |
83 | | - assert man.num_open_files() == 0 |
84 | | - assert man.mapped_memory_size() == 0 |
85 | | - |
86 | | - base_offset = 5000 |
87 | | - size = man.window_size() / 2 |
88 | | - assert c.use_region(base_offset, size).is_valid() |
89 | | - rr = c.region_ref() |
90 | | - assert rr().client_count() == 2 # the manager and the cursor and us |
91 | | - |
92 | | - assert man.num_open_files() == 1 |
93 | | - assert man.num_file_handles() == 1 |
94 | | - assert man.mapped_memory_size() == rr().size() |
95 | | - assert c.size() == size |
96 | | - assert c.ofs_begin() == base_offset |
97 | | - assert rr().ofs_begin() == 0 # it was aligned and expanded |
98 | | - assert rr().size() == align_to_page(man.window_size(), True) # but isn't larger than the max window (aligned) |
99 | | - |
100 | | - assert c.buffer()[:] == data[base_offset:base_offset+size] |
101 | | - |
102 | | - # obtain second window, which spans the first part of the file - it is a still the same window |
103 | | - assert c.use_region(0, size-10).is_valid() |
104 | | - assert c.region_ref()() == rr() |
105 | | - assert man.num_file_handles() == 1 |
106 | | - assert c.size() == size-10 |
107 | | - assert c.ofs_begin() == 0 |
108 | | - assert c.buffer()[:] == data[:size-10] |
109 | | - |
110 | | - # map some part at the end, our requested size cannot be kept |
111 | | - overshoot = 4000 |
112 | | - base_offset = fc.size - size + overshoot |
113 | | - assert c.use_region(base_offset, size).is_valid() |
114 | | - assert man.num_file_handles() == 2 |
115 | | - assert c.size() < size |
116 | | - assert c.region_ref()() is not rr() # old region is still available, but has not curser ref anymore |
117 | | - assert rr().client_count() == 1 # only held by manager |
118 | | - rr = c.region_ref() |
119 | | - assert rr().client_count() == 2 # manager + cursor |
120 | | - assert rr().ofs_begin() < c.ofs_begin() # it should have extended itself to the left |
121 | | - assert rr().ofs_end() <= fc.size # it cannot be larger than the file |
122 | | - assert c.buffer()[:] == data[base_offset:base_offset+size] |
123 | | - |
124 | | - # unising a region makes the cursor invalid |
125 | | - c.unuse_region() |
126 | | - assert not c.is_valid() |
127 | | - # but doesn't change anything regarding the handle count - we cache it and only |
128 | | - # remove mapped regions if we have to |
129 | | - assert man.num_file_handles() == 2 |
130 | | - |
131 | | - # iterate through the windows, verify data contents |
132 | | - # this will trigger map collection after a while |
133 | | - max_random_accesses = 5000 |
134 | | - num_random_accesses = max_random_accesses |
135 | | - memory_read = 0 |
136 | | - st = time() |
137 | | - |
138 | | - # cache everything to get some more performance |
139 | | - includes_ofs = c.includes_ofs |
140 | | - max_mapped_memory_size = man.max_mapped_memory_size() |
141 | | - max_file_handles = man.max_file_handles() |
142 | | - mapped_memory_size = man.mapped_memory_size |
143 | | - num_file_handles = man.num_file_handles |
144 | | - while num_random_accesses: |
145 | | - num_random_accesses -= 1 |
146 | | - base_offset = randint(0, fc.size - 1) |
| 80 | + fd = os.open(fc.path, os.O_RDONLY) |
| 81 | + for item in (fc.path, fd): |
| 82 | + assert len(data) == fc.size |
| 83 | + |
| 84 | + # small windows, a reasonable max memory. Not too many regions at once |
| 85 | + max_num_handles = 15 |
| 86 | + man = MappedMemoryManager(window_size=fc.size / 100, max_memory_size=fc.size / 3, max_open_handles=max_num_handles) |
| 87 | + c = man.make_cursor(item) |
147 | 88 |
|
148 | | - # precondition |
149 | | - assert max_mapped_memory_size >= mapped_memory_size() |
150 | | - assert max_file_handles >= num_file_handles() |
| 89 | + # still empty (more about that is tested in test_memory_manager() |
| 90 | + assert man.num_open_files() == 0 |
| 91 | + assert man.mapped_memory_size() == 0 |
| 92 | + |
| 93 | + base_offset = 5000 |
| 94 | + size = man.window_size() / 2 |
151 | 95 | assert c.use_region(base_offset, size).is_valid() |
152 | | - csize = c.size() |
153 | | - assert c.buffer()[:] == data[base_offset:base_offset+csize] |
154 | | - memory_read += csize |
| 96 | + rr = c.region_ref() |
| 97 | + assert rr().client_count() == 2 # the manager and the cursor and us |
155 | 98 |
|
156 | | - assert includes_ofs(base_offset) |
157 | | - assert includes_ofs(base_offset+csize-1) |
158 | | - assert not includes_ofs(base_offset+csize) |
159 | | - # END while we should do an access |
160 | | - elapsed = time() - st |
161 | | - mb = float(1000 * 1000) |
162 | | - sys.stderr.write("Read %i mb of memory with %i random accesses in %fs (%f mb/s)\n" |
163 | | - % (memory_read/mb, max_random_accesses, elapsed, (memory_read/mb)/elapsed)) |
164 | | - |
165 | | - # an offset as large as the size doesn't work ! |
166 | | - assert not c.use_region(fc.size, size).is_valid() |
167 | | - |
168 | | - # collection - it should be able to collect all |
169 | | - assert man.num_file_handles() |
170 | | - assert man.collect() |
171 | | - assert man.num_file_handles() == 0 |
| 99 | + assert man.num_open_files() == 1 |
| 100 | + assert man.num_file_handles() == 1 |
| 101 | + assert man.mapped_memory_size() == rr().size() |
| 102 | + assert c.size() == size |
| 103 | + assert c.ofs_begin() == base_offset |
| 104 | + assert rr().ofs_begin() == 0 # it was aligned and expanded |
| 105 | + assert rr().size() == align_to_page(man.window_size(), True) # but isn't larger than the max window (aligned) |
| 106 | + |
| 107 | + assert c.buffer()[:] == data[base_offset:base_offset+size] |
| 108 | + |
| 109 | + # obtain second window, which spans the first part of the file - it is a still the same window |
| 110 | + assert c.use_region(0, size-10).is_valid() |
| 111 | + assert c.region_ref()() == rr() |
| 112 | + assert man.num_file_handles() == 1 |
| 113 | + assert c.size() == size-10 |
| 114 | + assert c.ofs_begin() == 0 |
| 115 | + assert c.buffer()[:] == data[:size-10] |
| 116 | + |
| 117 | + # map some part at the end, our requested size cannot be kept |
| 118 | + overshoot = 4000 |
| 119 | + base_offset = fc.size - size + overshoot |
| 120 | + assert c.use_region(base_offset, size).is_valid() |
| 121 | + assert man.num_file_handles() == 2 |
| 122 | + assert c.size() < size |
| 123 | + assert c.region_ref()() is not rr() # old region is still available, but has not curser ref anymore |
| 124 | + assert rr().client_count() == 1 # only held by manager |
| 125 | + rr = c.region_ref() |
| 126 | + assert rr().client_count() == 2 # manager + cursor |
| 127 | + assert rr().ofs_begin() < c.ofs_begin() # it should have extended itself to the left |
| 128 | + assert rr().ofs_end() <= fc.size # it cannot be larger than the file |
| 129 | + assert c.buffer()[:] == data[base_offset:base_offset+size] |
| 130 | + |
| 131 | + # unising a region makes the cursor invalid |
| 132 | + c.unuse_region() |
| 133 | + assert not c.is_valid() |
| 134 | + # but doesn't change anything regarding the handle count - we cache it and only |
| 135 | + # remove mapped regions if we have to |
| 136 | + assert man.num_file_handles() == 2 |
| 137 | + |
| 138 | + # iterate through the windows, verify data contents |
| 139 | + # this will trigger map collection after a while |
| 140 | + max_random_accesses = 5000 |
| 141 | + num_random_accesses = max_random_accesses |
| 142 | + memory_read = 0 |
| 143 | + st = time() |
| 144 | + |
| 145 | + # cache everything to get some more performance |
| 146 | + includes_ofs = c.includes_ofs |
| 147 | + max_mapped_memory_size = man.max_mapped_memory_size() |
| 148 | + max_file_handles = man.max_file_handles() |
| 149 | + mapped_memory_size = man.mapped_memory_size |
| 150 | + num_file_handles = man.num_file_handles |
| 151 | + while num_random_accesses: |
| 152 | + num_random_accesses -= 1 |
| 153 | + base_offset = randint(0, fc.size - 1) |
| 154 | + |
| 155 | + # precondition |
| 156 | + assert max_mapped_memory_size >= mapped_memory_size() |
| 157 | + assert max_file_handles >= num_file_handles() |
| 158 | + assert c.use_region(base_offset, size).is_valid() |
| 159 | + csize = c.size() |
| 160 | + assert c.buffer()[:] == data[base_offset:base_offset+csize] |
| 161 | + memory_read += csize |
| 162 | + |
| 163 | + assert includes_ofs(base_offset) |
| 164 | + assert includes_ofs(base_offset+csize-1) |
| 165 | + assert not includes_ofs(base_offset+csize) |
| 166 | + # END while we should do an access |
| 167 | + elapsed = time() - st |
| 168 | + mb = float(1000 * 1000) |
| 169 | + sys.stderr.write("Read %i mb of memory with %i random on cursor initialized with %s accesses in %fs (%f mb/s)\n" |
| 170 | + % (memory_read/mb, max_random_accesses, type(item), elapsed, (memory_read/mb)/elapsed)) |
| 171 | + |
| 172 | + # an offset as large as the size doesn't work ! |
| 173 | + assert not c.use_region(fc.size, size).is_valid() |
| 174 | + |
| 175 | + # collection - it should be able to collect all |
| 176 | + assert man.num_file_handles() |
| 177 | + assert man.collect() |
| 178 | + assert man.num_file_handles() == 0 |
| 179 | + #END for each item |
| 180 | + os.close(fd) |
0 commit comments