The striking part of this rustfs snapshot is the spread. The top five hotspots land in five different files, covering storage healing, Swift protocol handling, scanner traversal, lifecycle evaluation, and object listing. That distribution points less to one troubled module and more to a set of high-responsibility orchestration functions that have each accumulated too much branching.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
heal_object | crates/ecstore/src/set_disk/heal.rs | 19.7 | 79 | 7 | 41 |
handle_authenticated_request | crates/protocols/src/swift/handler.rs | 18.7 | 142 | 6 | 31 |
scan_folder | crates/scanner/src/scanner_folder.rs | 18.7 | 99 | 5 | 51 |
eval_inner | crates/ecstore/src/bucket/lifecycle/core.rs | 18.5 | 55 | 8 | 10 |
merge_entry_channels | crates/ecstore/src/store_list_objects.rs | 18.0 | 35 | 7 | 14 |
What the hotspot table shows
All five functions trigger the same structural warning signs: complex branching, deep nesting, exit-heavy control flow, god-function scope, and long-function shape. The risk scores are tightly packed — 19.7 at the top and 18.0 at the bottom — so this is not a one-function outlier story. handle_authenticated_request has the highest CC at 142, scan_folder has the highest FO at 51, and eval_inner has the deepest nesting at ND 8. Together, those metrics suggest several different refactoring seams rather than one universal fix.
heal_object — crates/ecstore/src/set_disk/heal.rs
With CC 79, ND 7, and FO 41, heal_object is the structural centre of gravity for the ecstore healing path. The name suggests orchestration: detecting object damage, coordinating shard reads, reconstructing data, validating outcomes, and writing repaired state back to disk. Those are separable phases, but in this function they appear to be sharing one large control-flow surface.
The god-function and long-function patterns compound the fan-out problem. With 41 callees, a change to a downstream helper can require understanding how heal_object prepares state for it, and a change inside heal_object can ripple outward through many collaborators. The ND 7 value is the clearest refactoring clue: start at the deepest branch, extract that block into a named helper, and give the helper a narrow input/output contract. Repeating that phase by phase should bring both CC and nesting down while making healing scenarios easier to test independently.
handle_authenticated_request — crates/protocols/src/swift/handler.rs
A CC of 142 is the largest raw path count in the table. For a protocol handler, some branching is expected — method, path, authentication state, account/container/object target, and error response handling all create legitimate decision points. The risk is that those decisions appear to be concentrated inside one request-handling function rather than separated into authentication, routing, and operation-specific handlers.
The fan-out of 31 reinforces that dispatcher shape. This function likely knows about many downstream operations, but ND 6 suggests the routing logic is not a flat table; it is nested enough that reviewers must track request state across multiple layers of conditionals. Replace the branching dispatcher with a routing-table or command-handler pattern: authenticate once, normalize the request into a typed operation, then dispatch to per-operation handlers behind a common trait or enum. That would turn the largest CC value in the report into a small coordination function plus testable operation units.
scan_folder — crates/scanner/src/scanner_folder.rs
scan_folder calls into 51 distinct functions, making it the widest call-graph hub in the top five. Its CC 99 and ND 5 show that this is not just a simple loop over directory entries; it is likely coordinating traversal, filtering, metadata reads, error handling, and result emission in one place.
The first refactoring target should be responsibility boundaries, not micro-optimisation. Split traversal from per-entry classification, isolate error handling into a small policy helper, and move output/update side effects behind a narrow interface. That keeps the scanner’s top-level flow readable while reducing the number of paths that any single test has to exercise.
eval_inner — crates/ecstore/src/bucket/lifecycle/core.rs
The standout number for eval_inner is ND 8, the deepest nesting in the table. CC 55 is already high, but eight levels of control flow is the bigger maintainability concern because it hides the assumptions that must hold at the innermost decision points. For lifecycle evaluation, encode the major cases as explicit rule objects or enum variants, then move each rule’s predicate and action into a dedicated helper. The goal is to make the top-level evaluation read like a sequence of named lifecycle decisions rather than a deeply nested decision tree.
merge_entry_channels — crates/ecstore/src/store_list_objects.rs
merge_entry_channels is the smallest hotspot here, but CC 35, ND 7, and FO 14 still put it well above a comfortable review threshold. Channel-merging code often mixes ordering, termination, error propagation, and backpressure in the same loop; that combination explains why nesting can grow quickly. Extract the merge policy from the channel-draining mechanics: one helper should decide which entry wins next, while another owns receiving and termination behavior. That separation would reduce branch density and make concurrency edge cases easier to test directly.
Key Takeaways
- Start with
handle_authenticated_requestandheal_object. They combine the largest path counts with broad downstream reach, so reducing their branch surfaces should have the highest reviewability payoff. - Treat
scan_folderas a hub refactor. FO 51 means the main risk is orchestration breadth; introduce smaller scanner phases with explicit interfaces. - Use nesting as the guide for
eval_innerandmerge_entry_channels. ND 8 and ND 7 point to extraction seams inside the deepest conditional blocks.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
complex_branching | 5 |
deeply_nested | 5 |
exit_heavy | 5 |
god_function | 5 |
long_function | 5 |
hub_function | 1 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Reproduce This Analysis
git clone https://github.com/rustfs/rustfs
cd rustfs
git checkout 522605a055264a60492e3f8147adb3d1659e252c
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →