Skip to content

Wire mergedTracerTags as a read-through parent at span build (level-split) (phase 1a)#11932

Open
dougqh wants to merge 1 commit into
dougqh/tagmap-read-throughfrom
dougqh/tagmap-read-through-consumer
Open

Wire mergedTracerTags as a read-through parent at span build (level-split) (phase 1a)#11932
dougqh wants to merge 1 commit into
dougqh/tagmap-read-throughfrom
dougqh/tagmap-read-through-consumer

Conversation

@dougqh

@dougqh dougqh commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What Does This Do

Splits trace-level tags & span-level tags into two separate TagMap-s
To maintain full semantic compatibility, this is done via the read-through parent capability introduced in #11789.

Motivation

Reduces some allocation by avoiding the cloning of the BucketGroup collision chain
Reduces span creation time by replacing O(n) map-walk with O(1) referencing of parent TagMap

Additional Notes

Stacked on #11789 (TagMap read-through mechanism) — review that first.

Level-split phase 1: the wiring. Attaches mergedTracerTags as a read-through parent at span build (gated on !mergedTracerTagsNeedsIntercept) instead of copying it into every span's storage. This is the change that actually activates read-through — #11789 alone is inert (parent == null).

Commits: config-version handling out of the trace-level bundle, the read-through flip (DDSpanContext.parentTags / CoreTracer copy-vs-share gate), and a TagMapReadThroughBenchmark.

Draft — description to be refined; posting now so review can start this week ahead of the release cut.

🤖 Generated with Claude Code

@dd-octo-sts

dd-octo-sts Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.02 s 13.94 s [-0.4%; +1.4%] (no difference)
startup:insecure-bank:tracing:Agent 12.96 s 13.02 s [-1.2%; +0.3%] (no difference)
startup:petclinic:appsec:Agent 16.90 s 16.73 s [+0.1%; +1.9%] (maybe worse)
startup:petclinic:iast:Agent 16.83 s 16.99 s [-1.6%; -0.1%] (maybe better)
startup:petclinic:profiling:Agent 16.54 s 16.71 s [-2.4%; +0.4%] (no difference)
startup:petclinic:sca:Agent 16.94 s 16.88 s [-0.8%; +1.4%] (no difference)
startup:petclinic:tracing:Agent 16.01 s 16.14 s [-1.8%; +0.3%] (no difference)

Commit: 170eedb1 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch 2 times, most recently from 7bb20f4 to e65e58f Compare July 13, 2026 18:24
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch from 3a0a318 to e692601 Compare July 15, 2026 18:20
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from e65e58f to 3b9156e Compare July 15, 2026 18:24
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🎯 Code Coverage (details)
Patch Coverage: 61.54%
Overall Coverage: 57.31% (-0.00%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 170eedb | Docs | Datadog PR Page | Give us feedback!

@dougqh

dougqh commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Directional span-creation benchmark: master vs this branch

Grafted SpanCreationBenchmark (from #11915) onto both master and this branch and ran a directional comparison with a realistic trace-level bundle. Not committed to the branch — a one-off directional check.

Config: -f 2 -wi 3 -i 3 -w 5 -r 5 -prof gc, @Threads(8), JDK 17, quiet box. Trace-level bundle via -jvmArgsAppend "-Ddd.env=bench -Ddd.version=1.0.0 -Ddd.tags=team:apm,tier:web,region:us1,shard:7,build:1234" (7 non-interceptable tags → a non-empty mergedTracerTags for read-through to fall through to). Alloc = gc.alloc.rate.norm.

method master B/op branch B/op Δ Δ%
bareStartSpan 52,511 52,457 −54 −0.10%
bareBuildSpan 52,514 52,447 −67 −0.13%
webServerSpan 62,871 62,872 +1 ~0%
webServerSpanViaBuilder 69,543 69,484 −59 −0.08%
jdbcClientSpan 64,508 64,356 −153 −0.24%

Throughput deltas were all within noise (≤1.6%, no trend) — directional only, not quoted.

Read: the deltas are small but real — a consistent ~50–150 B/op reduction (the mergedTracerTags bucket structure read-through shares instead of copying), visible even on bare spans since the bundle applies to every span. But it's <0.25% of total span-creation alloc, which is dominated by a ~52–69 KB/op baseline (span/context/PendingTrace object graph). So this benchmark confirms read-through does what it should but is the wrong lens for its alloc win — that shows in the isolated TagMapReadThroughBenchmark (~300–600 B/op, −13% to −48% by bundle size).

Consistent with the settled framing: read-through is structural groundwork (dense-store enabler), not a standalone span-creation alloc headline.

From Claude: directional check requested during the fold/read-through rebase; grafted benches, not part of the branch diff.

🤖 Generated with Claude Code

dougqh added a commit that referenced this pull request Jul 15, 2026
StringIndex is a compact open-addressed string→index structure (the keyOf
substrate the dense tag store builds on): parallel hash/name arrays, linear
probing, on par with HashSet on lookup at a smaller footprint. Includes unit
tests, a footprint test (jol), and comparison benchmarks (vs HashSet/switch).

No TagMap changes — standalone util. Rebased onto the level-split stack
(consumer #11932) as the layer dense-store sits on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from 3b9156e to d2aa48f Compare July 15, 2026 21:19
dougqh added a commit that referenced this pull request Jul 15, 2026
StringIndex is a compact open-addressed string→index structure (the keyOf
substrate the dense tag store builds on): parallel hash/name arrays, linear
probing, on par with HashSet on lookup at a smaller footprint. Includes unit
tests, a footprint test (jol), and comparison benchmarks (vs HashSet/switch).

No TagMap changes — standalone util. Rebased onto the level-split stack
(consumer #11932) as the layer dense-store sits on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch from e692601 to b58bcc0 Compare July 20, 2026 13:59
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from d2aa48f to 1f257aa Compare July 20, 2026 15:43
dougqh added a commit that referenced this pull request Jul 20, 2026
StringIndex is a compact open-addressed string→index structure (the keyOf
substrate the dense tag store builds on): parallel hash/name arrays, linear
probing, on par with HashSet on lookup at a smaller footprint. Includes unit
tests, a footprint test (jol), and comparison benchmarks (vs HashSet/switch).

No TagMap changes — standalone util. Rebased onto the level-split stack
(consumer #11932) as the layer dense-store sits on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh dougqh changed the title Wire mergedTracerTags as a read-through parent at span build (level-split phase 1) Wire mergedTracerTags as a read-through parent at span build (level-split) (phase 1a) Jul 20, 2026
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch 2 times, most recently from bef20fa to 50cf53d Compare July 21, 2026 02:47
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from 1f257aa to 3237b90 Compare July 21, 2026 13:48
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch from 50cf53d to ae64f2a Compare July 21, 2026 14:50
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from 3237b90 to 2225a42 Compare July 21, 2026 14:51
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch from ae64f2a to 5cd8289 Compare July 21, 2026 15:19
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from 2225a42 to ea094ce Compare July 21, 2026 15:29
@dougqh
dougqh marked this pull request as ready for review July 21, 2026 16:03
@dougqh
dougqh requested a review from a team as a code owner July 21, 2026 16:03
@dougqh
dougqh requested a review from mhlidd July 21, 2026 16:03
@dd-octo-sts dd-octo-sts Bot added the tag: ai generated Largely based on code generated by an AI or LLM label Jul 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea094ce0bc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java Outdated
Comment thread dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java

@datadog-datadog-prod-us1-2 datadog-datadog-prod-us1-2 Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: PASS

More details

54 adversarial synthetic scenarios — simulating the full CoreTracer.buildSpan() wiring from the PR across 8 core behavioral equivalences and 5 edge cases — all passed. The read-through TagMap path is observationally identical to the old copy-down path for every tested scenario: trace-tag visibility, coreTags/contextualTags precedence override, builder-ledger tombstoning, multi-span parent isolation across config updates, and the version-exclusion change that prevents tombstone allocation on the shared frozen parent.

Was this helpful? React 👍 or 👎

📊 Validated against 54 scenarios · Open Bits AI session

🤖 Datadog Autotest · Commit ea094ce · What is Autotest? · Any feedback? Reach out in #autotest

@dougqh
dougqh force-pushed the dougqh/tagmap-read-through branch 2 times, most recently from ab56044 to 64c42e6 Compare July 21, 2026 17:06
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from ea094ce to 8c7bf14 Compare July 21, 2026 17:13
…plit phase 1)

Attach the trace's merged tracer tags to each span's TagMap as a frozen
read-through parent (via TagMap.createFromParent) at span construction,
instead of copying them into every span. The span sees the shared tags on
read and only stores its own local tags, so the common trace-level bundle
is held once per trace rather than duplicated per span.

- CoreTracer builds the frozen merged-tracer-tags parent once; config
  version is kept out of that bundle.
- DDSpanContext attaches the parent at construction (fixed, no re-parenting).
- Adds TagMapReadThroughBenchmark (copy-down vs read-through, -prof gc).

Stacked on the read-through mechanism (#11789), which builds on the folded
final-class TagMap (#11967).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dougqh
dougqh force-pushed the dougqh/tagmap-read-through-consumer branch from 8c7bf14 to 170eedb Compare July 21, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: core Tracer core tag: ai generated Largely based on code generated by an AI or LLM type: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant