Skip to content

openapi: a path item's census is recomputed once per operation it mounts #414

Description

@OmarAlJarrah

Summary

applyPathItem runs once per operation a path item mounts, and everything it
reads is a property of the item, not of the operation. So an item with N
operations recomputes the same answer N times:

  • undeclaredPathItemKeys walks the whole folded operations map,
  • the result is sorted on a fresh copy,
  • RawChildNode scans the item's mapping node once per key, with no early exit,
  • each kept value is re-marshalled from YAML to JSON.

Only the writing has to repeat — each operation gets its own Unmodeled
entry — so the key computation and the value marshalling could be done once per
item and the results written N times.

The diagnostics are recomputed too and then discarded: they are identical across
the operations of one item, so compilers/compile dedupes them on full identity.
Probing 8 methods x 2 undeclared keys constructs 16 diagnostics and keeps 2.

Scale

The key set is the document's to choose the size of. MaxUnknownKeys bounds what
is kept, not what is allocated to decide it, so the slice is materialized three
times (append, slices.Sorted, unrecorded's make) before the 64-key trim —
once per operation.

This is not a regression: the servers and extensions halves beside it have always
been per-operation, and correctness comes before performance here. It is worth
recording because the census made the per-operation body meaningfully more
expensive than it was when only two cheap constructs shared it.

What would close it

Hoisting the item-level work out of the per-operation loop — compute the keys,
their values and the diagnostics once per path item, then write the entries onto
each operation. The natural shape is for applyPathItem to take the list of
carriers rather than being called once per carrier, which would also make the
one-diagnostic-per-source-key property explicit instead of leaving it to the
dedupe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions