Skip to content

Commit df818d6

Browse files
authored
Use htree for inode_at, fix inode_at performance (#32)
* Simplify inode_at logic * Add htree inode_at test * Implement htree, and fix linear scan performance * Bump version * Fix test image generation * Review feedback * Fix fuzz * Review feedback * only mmove data that returns * Update cachetools * Fix hash logic * Fix scan issue * Fix deprecation warning * Review feedback * Alphabetical slots
1 parent c09b5ef commit df818d6

9 files changed

Lines changed: 512 additions & 83 deletions

File tree

‎.github/workflows/build.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ jobs:
6262
test64.ext4
6363
test64.ext4.tmp
6464
test_htree.ext4
65+
test_htree_multi.ext4
6566
if-no-files-found: error
6667

6768
test:

‎_test_image.sh‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ mkimage test32 "$tmp_dir" 20 -O ^64bit
4545
mkimage test64 "$tmp_dir" 20 -O 64bit
4646

4747
rm -f "$tmp_dir"/test*.txt "$tmp_dir"/symlink.txt
48-
echo "[test] Generating files..."
4948

5049
echo "[test] Making image test_htree..."
5150
chronic dd if=/dev/zero of=test_htree.ext4 count=20 bs=1048576
@@ -59,3 +58,15 @@ sudo umount "$tmp_dir"
5958
# shellcheck disable=SC2064
6059
trap "rmdir \"$tmp_dir\"" EXIT
6160
chronic e2fsck -Dy test_htree.ext4
61+
62+
echo "[test] Making image test_htree_multi..."
63+
chronic dd if=/dev/zero of=test_htree_multi.ext4 count=20 bs=1048576
64+
chronic mkfs.ext4 -g 1024 -b 1024 -O 64bit,dir_index -N 13000 test_htree_multi.ext4
65+
sudo mount -t ext4 test_htree_multi.ext4 "$tmp_dir"
66+
# shellcheck disable=SC2064
67+
trap "sudo umount \"$tmp_dir\";rmdir \"$tmp_dir\"" EXIT
68+
printf '%s\n' "$tmp_dir"/{1..12000} | xargs sudo touch
69+
sudo umount "$tmp_dir"
70+
# shellcheck disable=SC2064
71+
trap "rmdir \"$tmp_dir\"" EXIT
72+
chronic e2fsck -Dy test_htree_multi.ext4

‎ext4/directory.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,16 @@ def __init__(self, directory: "Directory", offset: int) -> None:
3636

3737
@override
3838
def read_from_volume(self) -> None:
39-
data = self.directory._open().read()[self.offset : self.offset + self.size] # pyright: ignore[reportPrivateUsage]
40-
_ = memmove(addressof(self), data, self.size)
39+
reader = self.directory._open() # pyright: ignore[reportPrivateUsage]
40+
_ = reader.seek(self.offset)
41+
data = reader.read(self.size)
42+
# Do not guard against short reads, this happens for the last entry
43+
_ = memmove(addressof(self), data, len(data))
4144

4245

4346
class DirectoryEntryBase(DirectoryEntryStruct):
4447
__slots__: tuple[str, ...] = ()
48+
4549
@property
4650
def name_bytes(self) -> bytes:
4751
return bytes(self.name)[: self.name_len] # pyright: ignore[reportAny]

0 commit comments

Comments
 (0)