aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-07-18 11:24:35 +0300
committerValentin Popov <valentin@popov.link>2026-07-18 11:24:35 +0300
commitf4fd8f4fce8ea3eda8780ddb09339b52ea784b27 (patch)
treeaaf31a8035bf0625669d17618b872196a14b307d
parentbcf1ce99719bb455d47e716951a7d3943dd41b33 (diff)
downloadfparkan-f4fd8f4fce8ea3eda8780ddb09339b52ea784b27.tar.xz
fparkan-f4fd8f4fce8ea3eda8780ddb09339b52ea784b27.zip
perf(assets): cache visual graph anchors
-rw-r--r--crates/fparkan-assets/src/lib.rs20
-rw-r--r--docs/tomes/05-render.md8
2 files changed, 23 insertions, 5 deletions
diff --git a/crates/fparkan-assets/src/lib.rs b/crates/fparkan-assets/src/lib.rs
index ac64648..d133574 100644
--- a/crates/fparkan-assets/src/lib.rs
+++ b/crates/fparkan-assets/src/lib.rs
@@ -1205,19 +1205,29 @@ pub fn extend_graph_report_with_visual_dependencies_with_progress<R: ResourceRep
let mut wear_requests = 0usize;
let mut material_requests = 0usize;
let mut texture_requests = 0usize;
+ // Capture all base-graph anchors before this traversal appends visual
+ // resources and edges. Looking them up again from the growing graph would
+ // make each later prototype scan an ever larger collection.
+ let prototype_mesh_anchors: Vec<_> = (0..prototypes.len())
+ .map(|prototype_index| {
+ let prototype_node_id = prototype_node_id(graph, prototype_index)?;
+ let mesh_node_id = prototype_mesh_node_id(graph, prototype_node_id)?;
+ Some((mesh_node_id, mesh_edge_id(graph, prototype_node_id)))
+ })
+ .collect();
for (prototype_index, prototype) in prototypes.iter().enumerate() {
let PrototypeGeometry::Mesh(mesh) = &prototype.geometry else {
continue;
};
report.wear_request_count += 1;
- let Some(prototype_node_id) = prototype_node_id(graph, prototype_index) else {
- continue;
- };
- let Some(mesh_node_id) = prototype_mesh_node_id(graph, prototype_node_id) else {
+ let Some((mesh_node_id, mesh_parent_edge)) = prototype_mesh_anchors
+ .get(prototype_index)
+ .copied()
+ .flatten()
+ else {
continue;
};
- let mesh_parent_edge = mesh_edge_id(graph, prototype_node_id);
let root_index = root_index_for_prototype(graph, prototype_index);
wear_requests = wear_requests.saturating_add(1);
diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md
index 1acb056..520361c 100644
--- a/docs/tomes/05-render.md
+++ b/docs/tomes/05-render.md
@@ -1110,6 +1110,14 @@ before the first TEXM progress marker. The differing checkpoints rule out the
previous overly narrow claim that TEXM is the sole remaining target. Profiling
must compare WEAR, MAT0, TEXM, graph allocation and archive I/O quantitatively.
+Visual expansion now snapshots each prototype's base-graph `Prototype→MSH`
+anchor before it appends any WEAR/MAT0/TEXM nodes and edges. The subsequent
+traversal reads this immutable vector rather than repeatedly linearly searching
+the growing graph; graph content, node/edge IDs and provenance remain
+unchanged. The same controlled 180-second Part 2 probe still ended at
+`GraphVisualMaterials`, so this is a complexity/correctness improvement rather
+than measured evidence of a startup checkpoint advance.
+
Mission loading now raises the decoded-payload cache entry budget from 64 to
256 while retaining its 64 MiB byte budget. This avoids premature entry-count
eviction during resource-rich loads without making memory unbounded. The same