Skip to content

Commit

Permalink
[wip][performance] SquashFS: Use unbuffered pread when possible to ge…
Browse files Browse the repository at this point in the history
…t file blocks
  • Loading branch information
mxmlnkn committed Sep 12, 2024
1 parent a330fd2 commit 876b89a
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions core/ratarmountcore/SquashFSMountSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def _dir_scan(self, start_block, offset):
from .MountSource import FileInfo, MountSource
from .SQLiteIndex import SQLiteIndex, SQLiteIndexedTarUserData
from .SQLiteIndexMountSource import SQLiteIndexMountSource
from .utils import InvalidIndexError, overrides
from .utils import InvalidIndexError, openPreadable, overrides


class IsalZlibDecompressor(Compressor):
Expand Down Expand Up @@ -376,6 +376,20 @@ def _recursive_inodes_iterator(self, directory): # -> PySquashfsImage.file.File
cls = PySquashfsImage.filetype[entry["type"]]
yield self._join_inode_offset(start_block, offset), cls(self, inode, entry["name"], directory)

def _read_data_block(self, start, size):
print("[_read_data_block]")
compressedSizeBlock = PySquashfsImage.SQUASHFS_COMPRESSED_SIZE_BLOCK(size)
offset = self._offset + start
if hasattr(self._fd, 'pread'):
data = self._fd.pread(compressedSizeBlock, offset)
else:
self._fd.seek(offset)
data = self._fd.read(compressedSizeBlock)
if PySquashfsImage.SQUASHFS_COMPRESSED_BLOCK(size):
return self._comp.uncompress(data, compressedSizeBlock, self._sblk.block_size)
else:
return data

@property
def _root(self):
if self._real_root is None:
Expand Down Expand Up @@ -408,7 +422,11 @@ def __init__(
**options
# fmt: on
) -> None:
self.rawFileObject = open(fileOrPath, 'rb') if isinstance(fileOrPath, str) else fileOrPath
# Beware: We should not turn of file buffering because PySquashfsImage does LOTS of very small reads to
# read lists of integers to parse the SquashFS superblock. It would be nice to buffer this
# on the parser side, but for now, leave the file object buffered and instead try to use unbuffered
# reads for file accesses only.
self.rawFileObject = openPreadable(fileOrPath) if isinstance(fileOrPath, str) else fileOrPath
self.rawFileObject.seek(0)
offset = findSquashFSOffset(self.rawFileObject)
if offset < 0:
Expand Down

0 comments on commit 876b89a

Please sign in to comment.