| 288 | self.close() |
| 289 | |
| 290 | def reorganize(self): |
| 291 | if self._readonly: |
| 292 | raise error('The database is opened for reading only') |
| 293 | self._verify_open() |
| 294 | # Ensure all changes are committed before reorganizing. |
| 295 | self._commit() |
| 296 | # Open file in r+ to allow changing in-place. |
| 297 | with _io.open(self._datfile, 'rb+') as f: |
| 298 | reorganize_pos = 0 |
| 299 | |
| 300 | # Iterate over existing keys, sorted by starting byte. |
| 301 | for key in sorted(self._index, key = lambda k: self._index[k][0]): |
| 302 | pos, siz = self._index[key] |
| 303 | f.seek(pos) |
| 304 | val = f.read(siz) |
| 305 | |
| 306 | f.seek(reorganize_pos) |
| 307 | f.write(val) |
| 308 | self._index[key] = (reorganize_pos, siz) |
| 309 | |
| 310 | blocks_occupied = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE |
| 311 | reorganize_pos += blocks_occupied * _BLOCKSIZE |
| 312 | |
| 313 | f.truncate(reorganize_pos) |
| 314 | # Commit changes to index, which were not in-place. |
| 315 | self._commit() |
| 316 | |
| 317 | |
| 318 | |