Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ under *Changed* or *Removed*.
The `Unreleased` block accumulates entries during development and is rolled into a
dated version block (`## [X.Y.Z] — YYYY-MM-DD`) when a release PR closes a milestone.

### Added

- **C4 component diagram of the pool internals** in the specification
([`docs/specs/01_spec_cpp_memory_pool.md`](docs/specs/01_spec_cpp_memory_pool.md), §4.2),
authored in Mermaid. [ADR-0041](docs/adr/0041-mermaid-diagram-tooling.md) records Mermaid
as the in-repo diagram tooling — C4 levels are drawn as flowcharts with `subgraph`
boundaries, and PlantUML, checked-in images, and Mermaid's experimental `C4Component` DSL
were considered and rejected. Closes the last open item of the specification review.
Documentation-only; no API change. Refs #105.

### Changed

- **`zh-Hans` / `ja` README translations re-synced to `v1.1.2`.** Carries the English
Expand Down
85 changes: 85 additions & 0 deletions docs/adr/0041-mermaid-diagram-tooling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# ADR-0041: Mermaid as the in-repo diagram tooling

- **Status:** Accepted
- **Date:** 2026-07-07
- **Deciders:** Daniel Polo (maintainer / project architect)
- **Related:** issue #105, spec [§4.2](../specs/01_spec_cpp_memory_pool.md#42-component-diagram-c4), [ADR-0013](0013-doxygen-for-api-markdown-for-narrative.md), [ADR-0032](0032-documentation-i18n-architecture.md)

## Context

The specification review (#105) asked for a **C4 component diagram** of the pool
internals. Until now the project has expressed architecture purely in prose plus one
ASCII sketch of the intrusive free list (spec §4). No diagram-authoring convention exists
yet, so adding the first real diagram forces a one-time, repo-wide decision about *how*
diagrams are authored, versioned, and rendered.

The forces are specific to this repository:

- **Docs are Markdown**, rendered in three places: on GitHub, in the Doxygen HTML API site
([ADR-0027](0027-doxygen-html-site-and-publication-pipeline.md)), and mirrored by the
`zh-Hans` / `ja` translations ([ADR-0032](0032-documentation-i18n-architecture.md)).
- **Docs pay for zero build tooling.** The only doc gates are `markdownlint`, the Lychee
link check, and a dependency-free (pure-stdlib Python) consistency lint. Introducing a
renderer that needs Java, Graphviz, or a network round-trip would be a large new
dependency for a single picture.
- **A diagram must render for a reader browsing GitHub** with no local toolchain, and must
**diff cleanly** in review like the rest of the docs.

## Decision

We adopt **Mermaid** as the canonical in-repo diagramming tool. Diagrams are authored as
fenced ` ```mermaid ` code blocks embedded directly in the Markdown that discusses them.
GitHub renders Mermaid natively, so no build step, no checked-in raster/vector binary, and
no external renderer is introduced. For **C4-model** diagrams we express the *Component*
level as a Mermaid `flowchart` whose `subgraph` blocks delimit the C4 boundaries (system /
public surface / core engine / external store), rather than Mermaid's experimental
`C4Component` DSL. The tiny ASCII free-list sketch in §4 stays as-is — it is a byte-level
memory layout, not an architecture diagram, and reads perfectly as text.

## Alternatives Considered

- **PlantUML (including the C4-PlantUML macro library).** Rejected: it needs a Java +
Graphviz renderer or a server round-trip, and GitHub does not render PlantUML inline. We
would have to check in generated SVG/PNG and keep it in lockstep with its source — exactly
the silent drift the consistency lint exists to prevent, and an awkward fit for the i18n
mirrors.
- **Checked-in SVG/PNG exported from a GUI (draw.io, Excalidraw, …).** Rejected: binary
artifacts do not diff in review, go stale invisibly, and bloat the repository; there is no
textual source of truth a reviewer can read.
- **Mermaid's native `C4Component` DSL.** Rejected *for now*: it is marked experimental in
Mermaid, and its automatic layout produces overlapping, hard-to-read output for the
~10-component diagram this project needs. A `flowchart` with explicit `subgraph`
boundaries renders reliably on GitHub and gives us layout control. The C4 *model* (its
levels, boundaries, and typed relationships) is notation-independent, so drawing it with a
flowchart is fully faithful to C4.
- **ASCII art only (the status quo).** Kept for the small in-band-pointer sketch, but
rejected as the general tool: it does not scale to a multi-component diagram with typed,
directional relationships and reads poorly beyond a handful of boxes.

## Consequences

- **Wins.** No new build or tooling dependency; each diagram lives next to the prose it
illustrates, diffs as plain text, and renders on GitHub, in editors (VS Code), and in
mkdocs-material-style viewers. Where Mermaid is unavailable, the reader still sees a
legible source block rather than a broken image.
- **Costs / limits.** Rendering depends on the viewer; a bare `cat` of the file shows the
Mermaid source, not a picture. Complex graphs can hit Mermaid layout quirks — mitigated by
keeping each diagram to a single C4 level and using explicit `subgraph`s for structure.
- **i18n.** A Mermaid block inside a translated source counts as source content: translators
copy it verbatim (the labels are English identifiers and pattern names) or localize the
labels, and the change is tracked like any other source edit through the
`translation-status.md` manifest.
- **Tooling / testing.** No CI change. `markdownlint` already tolerates the block (`MD013`
and `MD040` are disabled repo-wide), and the Lychee link check ignores code fences.
- **Documentation.** This ADR is the convention; the first diagram lands in spec §4.2.
Future diagrams (a Container-level view, per-subsystem sequence diagrams, …) follow the
same rule and cite this ADR.

## References

- The C4 model — <https://c4model.com> (notation-independent architecture diagramming).
- Mermaid — <https://mermaid.js.org> and GitHub's native Mermaid rendering.
- [ADR-0013](0013-doxygen-for-api-markdown-for-narrative.md) — Doxygen for the API contract,
Markdown for the narrative.
- [ADR-0032](0032-documentation-i18n-architecture.md) — documentation i18n architecture.
- Issue #105 — specification review that requested the C4 diagram.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ Do **not** write one for purely local implementation details, formatting, or tri
| 0038 | [Split the changelog into one immutable Markdown file per release](0038-changelog-version-split.md) | Accepted |
| 0039 | [In-repo bug ledger and agent triage protocol](0039-bug-ledger-and-triage-protocol.md) | Accepted |
| 0040 | [Pull-request metadata policy (assignee, labels, milestone)](0040-pull-request-metadata-policy.md) | Accepted |
| 0041 | [Mermaid as the in-repo diagram tooling](0041-mermaid-diagram-tooling.md) | Accepted |

When adding a new ADR, append a row to this table in the same PR.
54 changes: 52 additions & 2 deletions docs/specs/01_spec_cpp_memory_pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,54 @@ Storing a next-pointer in-band imposes constraints, all enforced by the implemen

The intrusive-free-list design was chosen over a bitmap allocator; the rejected alternative and its rationale are recorded in [ADR-0009](../adr/0009-free-list-layout-block-size-constraints-and-alignment-guarantee.md).

### 4.2 Component diagram (C4)

The C4-model **Component** view below relates the public surface, the core engine (which lives behind the opaque `memory_pool_t` handle / Pimpl), and the operating-system backing store. It is authored in Mermaid per [ADR-0041](../adr/0041-mermaid-diagram-tooling.md); a viewer without Mermaid support sees the equivalent source. Solid arrows are runtime call / ownership paths; dashed arrows are optional or diagnostic relationships. Bracketed tags name the realizing technology or the design pattern applied.

```mermaid
%% C4 model — Component level for the pbr-cpp-memory-pool library.
%% Authored as a Mermaid flowchart with C4 boundary subgraphs (ADR-0041).
flowchart TB
app["Consumer application<br/>[C or C++]<br/>fixed-size allocation on a hot path"]

subgraph lib["pbr-cpp-memory-pool — static library"]
direction TB
subgraph surface["Public surface"]
direction TB
capi["C API — memory_pool.h [extern C]<br/>frozen 4-function ABI + create_dynamic + introspection"]
cpp["Pool / PoolBuilder [C++ RAII]<br/>move-only owner; factory / builder construction"]
adapters["TypedPool&lt;T&gt; · PoolAllocator&lt;T&gt; [templates]<br/>type-safe and STL-allocator adapters"]
instr["InstrumentedPool [Decorator]<br/>counters + lifecycle Observers"]
diag["FreeListView [diagnostics, gated]<br/>read-only free-list iterator"]
end
subgraph core["Core engine — behind the Pimpl / C ABI"]
direction TB
state["memory_pool [Pimpl struct]<br/>backing · head · sizes · chunk list · grow factor"]
skel["alloc / free skeleton [Template Method]<br/>range-checks, dispatches to the sync policy"]
policy["Sync policy [Strategy, compile-time]<br/>SingleThreaded / Mutex / LockFree (ABA-tagged Treiber)"]
freelist["Intrusive free list [LIFO]<br/>in-band next-pointer, zero per-block metadata"]
chunks["Chunk list [Composite]<br/>non-contiguous geometric growth; pointers stay valid"]
end
end

os[("Backing storage<br/>[over-aligned operator new]<br/>alignof(max_align_t)")]

app -->|"C ABI"| capi
app -->|"idiomatic C++"| cpp
adapters -->|"compose"| cpp
instr -.->|"decorate"| cpp
diag -.->|"iterate (gated)"| freelist
cpp -->|"own via C core"| capi
capi --> state
state --> skel
skel -->|"pop / push"| policy
policy --> freelist
skel -->|"grow on exhaustion"| chunks
chunks -->|"seed a sub-list"| freelist
chunks --> os
state --> os
```

---

## 5. API / Public Interface
Expand Down Expand Up @@ -171,6 +219,7 @@ Every requirement above is realized and recorded. The table maps the spec to its
| §2.4 thread safety (mutex / lock-free + ABA tag) | [ADR-0020](../adr/0020-thread-safety-strategy-and-compile-time-knob.md) |
| §3.2 overhead budget & introspection | [ADR-0015](../adr/0015-metadata-overhead-budget-and-introspection.md) |
| §4 free-list layout, constraints, alignment, intrusive-vs-bitmap | [ADR-0009](../adr/0009-free-list-layout-block-size-constraints-and-alignment-guarantee.md) |
| §4.2 component (C4) diagram & diagram tooling | [ADR-0041](../adr/0041-mermaid-diagram-tooling.md) |
| §5.1–5.2 API, RAII, Pimpl, builder, typed pool, STL adapter | [ADR-0010](../adr/0010-raii-pool-wrapper-and-pimpl-across-the-c-cpp-boundary.md), [ADR-0011](../adr/0011-factory-method-and-builder-for-pool-construction.md), [ADR-0017](../adr/0017-typed-pool-design.md), [ADR-0018](../adr/0018-stl-allocator-adapter.md) |
| §5.3 error semantics | [ADR-0012](../adr/0012-foreign-pointer-and-out-of-range-pointer-policy.md), [ADR-0016](../adr/0016-exception-policy-at-the-c-cpp-boundary.md) |
| §5.4 instrumentation / observers | [ADR-0025](../adr/0025-decorator-for-instrumented-pool.md), [ADR-0026](../adr/0026-observer-for-pool-lifecycle-events.md) |
Expand All @@ -184,5 +233,6 @@ These are explicitly out of the current build and tracked as issues:
- **`std::pmr::memory_resource` adapter** — the "door left open" in [ADR-0018](../adr/0018-stl-allocator-adapter.md) (issue #107).
- **Coverage-guided fuzzing harness** (issue #108).
- **Opt-in debug hardening** — freed-block poisoning, canaries, free-list safe-linking; would also add double-free detection (issue #109).
- **Benchmark extension** — external baselines (jemalloc/tcmalloc) and p99 percentile reporting.
- **C4 component diagram** of the pool internals.
- **Benchmark extension** — external baselines (jemalloc/tcmalloc) and p99 percentile reporting (issue #111).

The **C4 component diagram** of the pool internals, once deferred here, now ships in [Section 4.2](#42-component-diagram-c4) (its tooling decision is [ADR-0041](../adr/0041-mermaid-diagram-tooling.md)).
Loading