ModernUO/Projects/UOContent/Engines/Pathing/Cache
Kamron Batman 6149b4ef21
perf(pathing): pool the StepCache strata buffer and cut a hot-path dictionary lookup
BuildChunk accumulated packed multi-Z strata into a List<byte>, which grew by
doubling (256 -> 512 -> 1024 -> ...) and then paid a final ToArray(). A full map
bake runs this ~114k times. It now writes into a byte[] rented from
STArrayPool<byte>.Shared via a WriteStratum span writer, and hands the chunk a
single exact-size copy.

This required tightening the record-fit guard. It reserved headroom for 8 strata
(StratumByteLength * 8) while ComputeStandableSurfaceZs can return up to 16, so a
cell could write 305 bytes past a 65,383-byte offset. Against a List that was
benign - it just grew past 64KB, and offsets stayed under the NoStrata sentinel.
Against a fixed-size rented buffer it is an out-of-bounds write. The guard is now
exact (strataLen + recordLength <= NoStrata), which also proves no emitted offset
can collide with the NoStrata == ushort.MaxValue sentinel.

Also:

- ShouldPromoteAfterMiss did two dictionary lookups per miss (TryGetValue, then an
  indexer assignment that re-hashes and re-probes). It now mutates the entry in
  place through CollectionsMarshal.GetValueRefOrNullRef. This runs on every
  uncached chunk touch during A* expansion, so it is the one change here that
  lands on the query path. The window-expiry branch keeps its explicit early
  return so threshold=1 still resets rather than promoting.

- Drop StepProbe.ComputeStrataAt and ComputedStratum. Dead code, and the last
  per-call array allocation in the probe.

- Collapse six 18-argument `new StepMask(0, 0, ..., kind)` blocks into
  Fallthrough(kind), and the thrice-repeated telemetry switch into
  RecordServed(kind). No behavior change; TryGetMask goes from ~220 to ~90 lines.

TryGetMask itself was already allocation-free (StepMask is a readonly struct,
StaticTileEnumerable is a ref struct, ChunkMissState is a struct), so this is a
bake-throughput and GC-churn win rather than a query-latency one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 19:05:25 -07:00
..
CacheEvictionTimer.cs feat(pathfinding): .swb format v8 compact index (#3b) (#2471) 2026-06-07 01:22:20 -07:00
CacheHitKind.cs fix: Fixes pathfinding prebake and pathfinding multi-fallthrough. (#2478) 2026-06-08 11:59:24 -07:00
CacheStats.cs feat(pathfinding): multi-aware mask synthesizer + warm interior cache for house/boat cells (#2479) 2026-06-09 08:02:05 -07:00
MultiMaskCache.cs feat(pathfinding): multi-aware mask synthesizer + warm interior cache for house/boat cells (#2479) 2026-06-09 08:02:05 -07:00
StepCache.cs perf(pathing): pool the StepCache strata buffer and cut a hot-path dictionary lookup 2026-07-12 19:05:25 -07:00
StepCacheFile.cs fix: Fixes pathfinding prebake and pathfinding multi-fallthrough. (#2478) 2026-06-08 11:59:24 -07:00
StepChunk.cs feat(pathfinding): .swb format v8 compact index (#3b) (#2471) 2026-06-07 01:22:20 -07:00
StepMask.cs feat: expand cache to nearly all mobiles + dynamic-obstacle pass (#2447) 2026-05-06 00:14:08 -07:00
StepProbe.cs perf(pathing): pool the StepCache strata buffer and cut a hot-path dictionary lookup 2026-07-12 19:05:25 -07:00