Skip to content

Commit 87acfca

Browse files
committed
chore: development v0.2.102 - comprehensive testing complete [auto-commit]
1 parent cc4b104 commit 87acfca

File tree

12 files changed

+49
-17
lines changed

12 files changed

+49
-17
lines changed

Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ exclude = [
3939
# Workspace Package Metadata (inherited by all crates)
4040
# ─────────────────────────────────────────────────────────────────────────────
4141
[workspace.package]
42-
version = "0.2.101"
42+
version = "0.2.102"
4343
edition = "2024"
4444
rust-version = "1.85"
4545
license = "MPL-2.0 OR LicenseRef-UFFS-Commercial"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
2121

2222
**UFFS reads the MFT directly** - once - and queries it in memory using Polars DataFrames. This is like reading the entire phonebook once instead of looking up each name individually.
2323

24-
### Benchmark Results (v0.2.101)
24+
### Benchmark Results (v0.2.102)
2525

2626
| Drive Type | Records | Time | Throughput |
2727
|------------|---------|------|------------|
@@ -33,7 +33,7 @@ Traditional file search tools (including `os.walk`, `FindFirstFile`, etc.) work
3333

3434
| Comparison | Records | Time | Notes |
3535
|------------|---------|------|-------|
36-
| **UFFS v0.2.101** | **18.7 Million** | **~142 seconds** | All disks, fast mode |
36+
| **UFFS v0.2.102** | **18.7 Million** | **~142 seconds** | All disks, fast mode |
3737
| UFFS v0.1.30 | 18.7 Million | ~315 seconds | Baseline |
3838
| Everything | 19 Million | 178 seconds | All disks |
3939
| WizFile | 6.5 Million | 299 seconds | Single HDD |

crates/uffs-mft/src/index.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4688,7 +4688,9 @@ const INDEX_MAGIC: &[u8; 8] = b"UFFSIDX\0";
46884688
/// Current index file format version.
46894689
/// Version 2: Changed `IndexNameRef` to use bit-packed `meta` field instead of
46904690
/// separate length/flags
4691-
const INDEX_VERSION: u32 = 2;
4691+
/// Version 3: Added tree metrics (descendants, treesize, `tree_allocated`) to
4692+
/// `FileRecord` serialization
4693+
const INDEX_VERSION: u32 = 3;
46924694

46934695
/// Persistent index header stored at the beginning of the index file.
46944696
#[derive(Debug, Clone)]
@@ -4836,6 +4838,10 @@ impl MftIndex {
48364838
buffer.extend_from_slice(&record.first_stream.name.offset.to_le_bytes());
48374839
buffer.extend_from_slice(&record.first_stream.name.meta.to_le_bytes());
48384840
buffer.extend_from_slice(&record.first_stream.flags.to_le_bytes());
4841+
// Tree metrics (Version 3+)
4842+
buffer.extend_from_slice(&record.descendants.to_le_bytes());
4843+
buffer.extend_from_slice(&record.treesize.to_le_bytes());
4844+
buffer.extend_from_slice(&record.tree_allocated.to_le_bytes());
48394845
}
48404846

48414847
// Write names
@@ -5039,6 +5045,10 @@ impl MftIndex {
50395045
let stream_name_offset = read_u32!();
50405046
let stream_name_meta = read_u32!();
50415047
let stream_flags = read_u8!();
5048+
// Tree metrics (Version 3+)
5049+
let descendants = if version >= 3 { read_u32!() } else { 0 };
5050+
let treesize = if version >= 3 { read_u64!() } else { 0 };
5051+
let tree_allocated = if version >= 3 { read_u64!() } else { 0 };
50425052

50435053
records.push(FileRecord {
50445054
frs,
@@ -5072,9 +5082,9 @@ impl MftIndex {
50725082
},
50735083
flags: stream_flags,
50745084
},
5075-
descendants: 0,
5076-
treesize: 0,
5077-
tree_allocated: 0,
5085+
descendants,
5086+
treesize,
5087+
tree_allocated,
50785088
});
50795089
}
50805090

@@ -5193,6 +5203,12 @@ impl MftIndex {
51935203
// Compute stats from loaded data
51945204
index.recompute_stats();
51955205

5206+
// If loading an old version (< 3) without tree metrics, recompute them
5207+
if version < 3 {
5208+
tracing::debug!("Old index version {version} - recomputing tree metrics");
5209+
index.compute_tree_metrics();
5210+
}
5211+
51965212
Ok((index, header))
51975213
}
51985214

crates/uffs-mft/src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4062,6 +4062,14 @@ async fn cmd_index_update(drive: char, force_full: bool, ttl: Option<u64>) -> Re
40624062
);
40634063
println!(" Applied in {:.3}s", apply_time.as_secs_f64());
40644064

4065+
// Recompute tree metrics after structural changes
4066+
println!();
4067+
println!("🔨 Recomputing tree metrics...");
4068+
let tree_start = Instant::now();
4069+
updated_index.compute_tree_metrics();
4070+
let tree_time = tree_start.elapsed();
4071+
println!(" Computed in {:.3}s", tree_time.as_secs_f64());
4072+
40654073
// Save updated index
40664074
let handle = VolumeHandle::open(drive)?;
40674075
let volume_data = handle.volume_data();

crates/uffs-mft/src/reader.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3897,6 +3897,10 @@ impl MultiDriveMftReader {
38973897
"📊 USN changes applied"
38983898
);
38993899

3900+
// Recompute tree metrics after structural changes
3901+
debug!(drive = %drive, "🔨 Recomputing tree metrics after USN updates");
3902+
index.compute_tree_metrics();
3903+
39003904
// Save updated index to cache with new checkpoint
39013905
let handle = match VolumeHandle::open(drive) {
39023906
Ok(h) => h,

dist/latest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.2.101
1+
v0.2.102

0 commit comments

Comments
 (0)