Skip to content

[Extractors] Thread map-extractor and vmap-extractor tile processing - #5

Merged
billy1arm merged 2 commits into
mangosfour:masterfrom
r-log:feat/thread-extractors
Jun 30, 2026
Merged

[Extractors] Thread map-extractor and vmap-extractor tile processing#5
billy1arm merged 2 commits into
mangosfour:masterfrom
r-log:feat/thread-extractors

Conversation

@r-log

@r-log r-log commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Threads both map-extractor and vmap-extractor — each adds -t/--threads (0 = auto-detect cores, default; 1 = serial) and processes a map's ADT tiles across a worker pool, mirroring the movemap generator. Ports the same change shipped in the mangosthree in-tree extractors.

map-extractor (commit 1)

  • per-map tile queue + N workers; each .map file is independent → identical output regardless of thread count
  • per-tile scratch buffers thread_local; counters std::atomic; one MPQ-read mutex around the archive read in ConvertADT
  • zero every per-tile scratch buffer up front (stale liquid cells made .map bytes tile-order-dependent → non-deterministic across threads)

vmap-extractor (commit 2)

  • one mutex in the MPQFile ctor serialises archive reads; parsing + geometry conversion run in parallel
  • model dedup via a claim set; a worker referencing a model another worker is mid-extracting blocks on a condition variable until the file existsModelInstance drops the placement otherwise (this dropped ~156 placements in testing before the fix)
  • per-tile temp dir_bin files concatenated in order (avoids interleaved records); GenerateDoodadUniqueId mutex-guarded; per-worker failedPaths

Verified: both build green (MSVC). The identical mangosthree changes were validated on-client — map output byte-for-byte identical (serial vs auto); vmap produces the same model + vmap file sets and identical dir_bin records (doodad-id values aside, which are order-dependent).

Depends on #3 (the loadlib relocation fix) — master doesn't build without it; verified locally with #3 applied. Once #3 lands I'll rebase.


This change is Reviewable

r-log added 2 commits June 30, 2026 23:01
Add a -t/--threads option to map-extractor and convert each map's ADT
tiles across a worker pool (0 = auto-detect cores, default; 1 = serial),
mirroring the movemap generator's threading.

- per-map tile queue drained by N workers; each .map output file is
  independent, so the result is identical regardless of thread count
- per-tile scratch buffers (area/height/liquid grids) are thread_local
- success/failed counters are std::atomic
- MPQ reads are serialised by one mutex held only around the archive read
  in ConvertADT (StormLib's shared per-archive file position has no
  internal lock, so concurrent reads from one handle are unsafe); the
  parse/pack/write that follows runs in parallel
- zero every per-tile scratch buffer up front so a tile's output never
  inherits residual bytes from the prior tile (which made the .map bytes
  depend on tile order -- non-deterministic across threads)

Mirrors the same change in the mangosthree in-tree extractor, where full
extraction at --threads 1 vs auto was verified byte-for-byte identical.
Add -t/--threads to vmap-extractor and process each map's ADT tiles
across a worker pool (0 = auto-detect cores, default; 1 = serial).

- one mutex in the MPQFile ctor serialises all archive reads (StormLib's
  shared per-archive file position has no internal lock); parsing and
  geometry conversion run in parallel
- model dedup: a worker claims a model, extracts it, and any worker
  referencing the same model blocks on a condition variable until its file
  is on disk -- the placement written next (ModelInstance) opens that file
  and drops the spawn if it is missing
- each tile writes its own temp dir_bin file (a placement is several
  fwrites, so a shared handle would interleave records), concatenated in
  tile order afterwards
- GenerateDoodadUniqueId's shared map + counter are mutex-guarded
- failedPaths is accumulated per worker and merged
- g_WmoDoodads is populated by the serial ExtractWmo pass that runs first,
  so it is read-only during the threaded tile pass

Mirrors the mangosthree in-tree change, verified on-client: same model and
vmap file sets and identical dir_bin records (doodad ids aside) vs serial.
@billy1arm
billy1arm merged commit 57d612a into mangosfour:master Jun 30, 2026
@r-log
r-log deleted the feat/thread-extractors branch July 5, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants