# Changelog
## [3.2.0] - 2026-05-25
### Added
- `dds_calc_dd_tables_batched` and `dds_solve_boards_batched` FFI entry
points in `src/dds_context.{h,cpp}`. Each accepts N independent
deals/boards plus a per-worker `DdsSolverConfig`, spawns an internal
pool sized to `std::thread::hardware_concurrency()` (overridable via
the `n_threads` argument), and dispatches work via an atomic
fetch-add counter. Every worker owns its own `SolverContext` — no
shared mutable state, so the thread-safety guarantee that 3.1.1
added to `dds_calc_dd_table` extends naturally to the batched path.
The first non-success status from any worker is preserved (later
successes do not overwrite it); workers continue draining the
remaining items after an error, mirroring the existing per-deal
Rust caller pattern. This ports the structural performance win
from the `ddss` fork's `CalcAllTablesPBNx` (in-vendor batched
scheduling) without reintroducing the `cparam` global it relies on.
### Changed
- Removed the `[profile.dev] opt-level = 3` override. Dev builds now
use Cargo's default opt-level 0 for both Rust and `cc`-built C++.
Same rationale as the corresponding removal in `ddss-sys` 0.1.2:
don't mask the converse-class bugs (UB-in-unsafe miscompilations
and the like) that only surface at -O2/-O3.
- Refresh the `vendor` submodule (`26ee3ce` → `d2f3200`): rebase the
three local patches (thread-safe `calc_dd_table`, dead `System`
callback cleanup) onto upstream master, picking up an upstream typo
fix, Bazel/CI updates, and the `DDS_VERSION` macro bump from `20900`
to `30000`. No FFI surface change, but `DDSInfo.major/minor/patch`
(and the "Version" line in `systemString`) now report **3.0.0**
instead of 2.9.0 at runtime — downstream consumers that pin the
reported version (e.g. dds-bridge's `system_info_version_is_2_9_0`
test) will need to update once a release picks this up.
- Retire the `jdh8/dds` fork as the `vendor` submodule remote. Upstream
`dds-bridge/dds` has since landed equivalents of the fork's local
patches (notably `1b121af` "eliminate all mutable global state from
solver and par code", which subsumes the fork's thread-safe
`calc_dd_table(ctx)` rewrite), so the submodule now tracks the
official `develop` branch (`d2f3200` → `1ce9026`). The only thing
lost is the fork's removal of unused legacy `System` callback /
`calc_*` shim code paths; those compile cleanly upstream as dead
code and are not on any path `dds_context.{h,cpp}` exercises. No
FFI surface change and all tests (incl. `solver_context_batched_*`)
pass against the upstream tree.
## [3.1.1] - 2026-05-24
### Tooling
- Restore a committed `.clangd` at the crate root and drop the per-build
`compile_commands.json` emission from `build.rs`. The build-script write
broke docs.rs (its workdir is mounted read-only — only `OUT_DIR` is
writable), and would have shipped that breakage in v3.1.1; v3.1.0 was
unaffected because it predates the emission. The new `.clangd` supplies
the flags needed for files in `src/` (where the wrapper and
`dds_context.{h,cpp}` live) and suppresses diagnostics under `vendor/`,
which we don't lint anyway. No `cargo build` step is needed to get
IntelliSense.
- `.gitignore` now also covers the remaining DDS diagnostic-dump prefixes
(`toplevel*.txt`, `retrieved*.txt`, `stored*.txt`, `sched*.txt`) in
addition to the previously-listed `ABstats*`/`TTstats*`/`timer*`/
`movestats*` patterns, so any future debug build never leaves untracked
files behind.
### Known issues
- DDS's per-thread diagnostic-dump compile flags (`DDS_TOP_LEVEL`,
`DDS_AB_STATS`, `DDS_TT_STATS`, `DDS_TIMING`, `DDS_MOVES`, `DDS_AB_HITS`,
and the umbrella `DDS_DEBUG_ALL` in
`vendor/library/src/utility/debug.h`) are non-buildable in v3.x and
therefore not exposed as Cargo features. Two upstream issues need fixing
before any of them can be turned on: the `File` class referenced by
`ThreadData::file*` members was deleted as "unused" in upstream commit
`7a3ace6` ("Deletes unused File.h") even though `thread_data.{hpp,cpp}`
and `solver_if.cpp` still reference it under `#ifdef` guards; and
`thread_data.hpp` reads `DDS_AB_STATS`/`DDS_TIMING` before
`utility/debug.h` is included, so the `DDS_DEBUG_ALL` umbrella never
fans out for that header. Resolving both — most likely by restoring
`library/src/File.{h,cpp}` (~60 LOC `ofstream` wrapper, recoverable
from `7a3ace6^` on the `jdh8/dds` fork) and adding `#include "File.h"`
plus `#include "utility/debug.h"` to `thread_data.hpp` — is a
prerequisite for any future `debug-*` Cargo feature.
### Fixed
- Repoint the `vendor` submodule at the `jdh8/dds` fork's
`pons-parallel-calc` branch, which removes the file-scope `ParamType
cparam` global from `library/src/calc_tables.cpp`. Before the patch, two
threads each holding their own `DdsSolverContext` and calling
`dds_calc_dd_table` simultaneously could race on `cparam.bop` /
`cparam.solvedp` / `cparam.error` and write results into the wrong
output buffer — contradicting the 3.1.0 changelog's "safe for
concurrent use across threads" claim, which was true for
`dds_solve_board` but not for `dds_calc_dd_table`. The patch also drops
the now-unreachable `scheduler.RegisterRun(...)` call and reduces the
legacy `calc_single_common` / `copy_calc_single` / `calc_chunk_common`
shims to empty stubs so `init.cpp`'s `System` constructor still links.
## [3.1.0] - 2026-05-21
### Added
- `DdsSolverContext` opaque handle and `dds_solver_context_*` /
`dds_solve_board` / `dds_calc_dd_table` / `dds_calc_dd_table_pbn` /
`dds_calc_par` / `dds_calc_par_from_table` C entry points for DDS 3's
modern `SolverContext` API. A small `extern "C"` shim
(`src/dds_context.{h,cpp}`) compiles alongside the vendor sources and is
bindgen-wrapped like the rest of the FFI surface. One context per OS
thread; safe for concurrent use across threads when each thread owns
its own context.
### Documented (existing v3.0.0 behavior)
- Internal batch threading in DDS is removed: `SolveAllBoardsBin`,
`CalcAllTables`, and `AnalyseAllPlays*` execute sequentially inside
DDS regardless of `SetMaxThreads(N)`. Concurrent callers must drive
parallelism from the application side, preferably via per-thread
`DdsSolverContext` instances.
- Legacy `SolveBoard(threadIndex>0)` returns `RETURN_THREAD_INDEX`; only
`threadIndex=0` remains valid on the legacy entry point, and each call
builds a fresh internal context (no TT reuse across calls).
### Internal
- Bindgen now reads `src/wrapper.h` (which includes both `api/dll.h`
and the new `dds_context.h`) instead of `api/dll.h` directly.
- Bindgen runs with `prepend_enum_name(false)` so enum constants keep
their natural C names (e.g., `DDS_TT_KIND_LARGE`) without the
`<TypeName>_` prefix that bindgen would otherwise emit.
## [3.0.0] - 2026-05-20
### Breaking
- Bump vendored `dds` library to **v3.0.0** (was v2.8.2-220). Bindgen now reads
the public C API header `vendor/library/src/api/dll.h` only; the broader set
of C++ internals previously surfaced through `vendor/src/dds.h` is no longer
exposed in the FFI bindings.
- Upstream renamed every public struct from camelCase to PascalCase and renamed
several struct fields from camelCase to snake_case. The bindgen output now
mirrors these names verbatim. Notable renames:
- `futureTricks` → `FutureTricks`
- `deal` → `Deal`, `dealPBN` → `DealPBN`
- `boards` → `Boards`, `boardsPBN` → `BoardsPBN`
- `solvedBoards` → `SolvedBoards` (field `solvedBoard` → `solved_board`)
- `ddTableDeal[s]` / `ddTableDeal[s]PBN` → `DdTableDeal[s]` /
`DdTableDeal[s]PBN` (field `noOfTables` → `no_of_tables`)
- `ddTableResults` → `DdTableResults` (field `resTable` → `res_table`)
- `ddTablesRes` → `DdTablesRes`
- `parResults` → `ParResults`, `allParResults` → `AllParResults`
(field `presults` → `par_results`)
- `parResultsDealer` → `ParResultsDealer`
- `parResultsMaster` → `ParResultsMaster`
- `parTextResults` → `ParTextResults`
- `contractType` → `ContractType` (fields `underTricks` → `under_tricks`,
`overTricks` → `over_tricks`)
- `playTraceBin` / `playTracePBN` / `playTracesBin` / `playTracesPBN` →
`PlayTraceBin` / `PlayTracePBN` / `PlayTracesBin` / `PlayTracesPBN`
- `solvedPlay[s]` → `SolvedPlay[s]`
- `Boards`, `SolvedBoards`, `DdTablesRes`, `PlayTracesBin`, `SolvedPlays`
each rename `noOfBoards` → `no_of_boards`
- `DDSInfo` is unchanged.
- Removed Cargo features `debug-timing`, `debug-ab-stats`, `debug-tt-stats`,
`debug-moves`. The corresponding upstream code paths no longer compile in
v3.0.0. `debug-dump` is retained.
### Changed
- Build C++ sources with `-std=c++20` (was c++14), matching upstream's Bazel
config.
- Compile the full new vendor tree (`vendor/library/src/**/*.cpp` across
`system/`, `moves/`, `heuristic_sorting/`, `utility/`, `lookup_tables/`,
`solver_context/`, `trans_table/`) instead of only `vendor/src/*.cpp`.
- Force-include `<sstream>` and `<iomanip>` via `cc::Build` flags to work
around upstream sources that depend on these standard headers transitively
but never include them.
## [2.1.1] - 2026-04-24
### Changed
- Simplify `examples/info.rs` to print DDS's `systemString` (comprehensive
version/compiler/system info) in a single line, instead of per-field output
for version, thread count, and thread sizes
### Internal
- Rename `mod test` to `mod tests` in `src/lib.rs` to mirror the `tests/`
directory convention and avoid visual collision with `#[cfg(test)]`
- Allow `clippy::all` and `clippy::pedantic` in the generated bindings module so
lints aren't enforced on auto-generated code
- Add `CLAUDE.md` with contributor notes for AI-assisted development
- Require Windows CI to pass: drop `continue-on-error` on the Windows test
matrix leg so failures block the workflow instead of being silently ignored
- Ignore diagnostic dumps emitted by the `debug-*` features (`dump.txt`,
`timer*.txt`, `ABstats*.txt`, `TTstats*.txt`, `movestats*.txt`) in
`.gitignore`
## [2.1.0] - 2026-04-20
### Added
- Cargo features `debug-dump`, `debug-timing`, `debug-ab-stats`,
`debug-tt-stats`, `debug-moves` — enable upstream DDS debug/profiling
output files (off by default; each emits per-thread `.txt` files into
the cwd)
## [2.0.5] - 2026-04-17
### Documentation
- Document thread safety categories for all functions in README, covering non-reentrant, reentrant (explicit `threadIndex`), always-safe, and thread-pool management groups
- Add reference to the higher-level `dds-bridge` crate and its `Solver` type
### Dependencies
- Relax build-dependency version pins to minor ranges (`anyhow = "1"`, `bindgen = "0.72"`, `cc = "1"`, `glob = "0.3"`)
- Replace `once_cell` dev-dependency with `parking_lot = "0.12.5"` for simpler mutex handling in tests
### Internal
- Simplify test mutex using `parking_lot::Mutex` + `std::sync::LazyLock` (Rust 1.85 stable), removing manual poison handling
- Use `&raw mut` instead of `&mut` for raw pointer coercions in test FFI calls
- Set `rust-version = "1.85"` in `Cargo.toml`
- Add `homepage`, `documentation`, and `readme` fields to `Cargo.toml`
- Fix GitHub workflow to recurse submodules when fetching the C++ dependency
## [2.0.4] - 2026-03-18
- Update Rust to 2024
- Update bindgen
[3.2.0]: https://github.com/jdh8/dds-bridge-sys/releases/tag/3.2.0
[2.1.1]: https://github.com/jdh8/dds-bridge-sys/releases/tag/2.1.1
[2.1.0]: https://github.com/jdh8/dds-bridge-sys/releases/tag/2.1.0
[2.0.5]: https://github.com/jdh8/dds-bridge-sys/releases/tag/2.0.5
[2.0.4]: https://github.com/jdh8/dds-bridge-sys/releases/tag/2.0.4