Skip to content

refactor(change-buffer)!: replace slot index with span_id, fix segment isolation#2105

Open
rochdev wants to merge 13 commits into
mainfrom
rochdev/change-buffer-cleanup
Open

refactor(change-buffer)!: replace slot index with span_id, fix segment isolation#2105
rochdev wants to merge 13 commits into
mainfrom
rochdev/change-buffer-cleanup

Conversation

@rochdev

@rochdev rochdev commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

  • Segment isolation bug: When service A → B → A creates two segments sharing the same trace_id, trace-level state (SetTraceOrigin, SetTraceMetaAttr, SetTraceMetricsAttr) was keyed by trace_id, so segment 2's writes overwrote segment 1's values before it was flushed. Fixed by adding segment_id (u64) to Create ops and keying SmallSegmentMap by segment_id instead.
  • Slot index removal: Operations carried a u32 slot_index — a JS-managed array index into four parallel Vecs. JS had to allocate/free slot numbers; reusing a slot prematurely would silently drop a live span; ensure_slot had to grow all four Vecs in lockstep. Replaced with span_id (u64) as the natural key into HashMaps, removing the slot allocation contract entirely.
  • Opcode size: Was u64 because JS wrote via setBigUint64, wasting 6 bytes per op with only 17 opcodes. Reduced to u16.
  • SpanHeader removal: materialize_header was an unused direct-write path where JS wrote span fields into a #[repr(C)] struct in WASM memory, bypassing the change buffer protocol. It had no segment_id field and would have reproduced the isolation bug. Deleted along with span_header.rs.
  • Rename TraceSegment: SmallTraceMap/Trace renamed to SmallSegmentMap/Segment since the map holds per-segment state, not per-trace state.

Test plan

  • cargo test -p libdd-trace-utils --lib --features change-buffer -- change_buffer passes (16 tests including 3 new segment isolation tests)
  • cargo check -p libdd-trace-utils --features change-buffer clean

🤖 Generated with Claude Code

yannham and others added 11 commits June 10, 2026 17:53
Add the main ChangeBufferState<T> struct and its full implementation:
span creation/pooling, change buffer interpretation (opcodes), deferred
tag resolution, span header materialization, flush logic, and string
table management. This is the core state machine that processes batched
span mutations from JS/WASM via a shared memory buffer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… isolation

Segment isolation bug
When service A calls B which calls back to A, both of A's segments
share the same trace_id. The segment-level state map (origin, meta,
metrics) was keyed by trace_id, so SetTraceOrigin/SetTraceMetaAttr/
SetTraceMetricsAttr written for segment 2 would overwrite segment 1's
values before it was flushed. Fix: add segment_id (u64) to the Create
op so each segment gets its own isolated entry in SmallSegmentMap.

Slot index removal
Operations previously carried a u32 slot_index — a JS-managed array
index into parallel Vecs (spans, deferred_meta, deferred_metrics,
segment_ids). JS had to allocate and free slot numbers, silently
reusing a slot would drop a live span, and ensure_slot had to grow all
four Vecs in lockstep on every Create. Replaced with span_id (u64) as
the natural key into HashMaps, removing the slot allocation contract
entirely.

Opcode size
The opcode was encoded as u64 because JS was writing via setBigUint64.
With only 17 opcodes this wastes 6 bytes per op. Reduced to u16.

SpanHeader removal
materialize_header was a direct-write path where JS wrote span fields
into a repr(C) struct in WASM memory, bypassing the change buffer
protocol. It had no segment_id field and would have reproduced the
isolation bug. It was not in use, so deleted along with span_header.rs.

Rename Trace→Segment
SmallTraceMap/Trace renamed to SmallSegmentMap/Segment since the map
holds per-segment state, not per-trace state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kept our implementation (HashMap-keyed by span_id) as it supersedes the
slot-based style improvements in the base branch. Adopted the
SPANS_POOL_MAX_SIZE named constant from the base branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rochdev rochdev marked this pull request as ready for review June 11, 2026 10:22
@rochdev rochdev requested review from a team as code owners June 11, 2026 10:22
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 11, 2026

Copy link
Copy Markdown

Pipelines  Tests

Fix all issues with BitsAI

⚠️ Warnings

🚦 1 Pipeline job failed

semver-check | validate   View in Datadog   GitHub Actions

ℹ️ Info

No other issues found (see more)

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 82.00%
Overall Coverage: 73.48% (+0.45%)

Useful? React with 👍 / 👎

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

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 604 documentation warning(s) found

📦 libdd-trace-utils - 604 warning(s)


Updated: 2026-06-11 10:47:24 UTC | Commit: 128cc3c | missing-docs job results

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Clippy Allow Annotation Report

Comparing clippy allow annotations between branches:

Summary by Rule

Rule Base Branch PR Branch Change
unwrap_used 1 0 ✅ -1 (-100.0%)
Total 1 0 ✅ -1 (-100.0%)

Annotation Counts by File

File Base Branch PR Branch Change
libdd-trace-utils/src/change_buffer/mod.rs 1 0 ✅ -1 (-100.0%)

Annotation Stats by Crate

Crate Base Branch PR Branch Change
clippy-annotation-reporter 5 5 No change (0%)
datadog-ffe-ffi 1 1 No change (0%)
datadog-ipc 21 21 No change (0%)
datadog-live-debugger 4 4 No change (0%)
datadog-live-debugger-ffi 10 10 No change (0%)
datadog-profiling-replayer 4 4 No change (0%)
datadog-sidecar 46 46 No change (0%)
libdd-common 13 13 No change (0%)
libdd-common-ffi 12 12 No change (0%)
libdd-data-pipeline 5 5 No change (0%)
libdd-ddsketch 2 2 No change (0%)
libdd-dogstatsd-client 1 1 No change (0%)
libdd-profiling 13 13 No change (0%)
libdd-remote-config 4 4 No change (0%)
libdd-telemetry 20 20 No change (0%)
libdd-tinybytes 4 4 No change (0%)
libdd-trace-normalization 2 2 No change (0%)
libdd-trace-obfuscation 3 3 No change (0%)
libdd-trace-stats 1 1 No change (0%)
libdd-trace-utils 12 11 ✅ -1 (-8.3%)
Total 183 182 ✅ -1 (-0.5%)

About This Report

This report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality.

@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: 29b0d7d5bd

ℹ️ 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 libdd-trace-utils/src/change_buffer/mod.rs Outdated
Comment thread libdd-trace-utils/src/change_buffer/mod.rs Outdated
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 4 issue(s) found, showing only errors (advisories, bans, sources)

📦 libdd-trace-utils - 4 error(s)

Show output
error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:177:1
    │
177 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── (dev) libdd-common v4.2.0
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   └── libdd-trace-utils v8.0.0
      │   │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── libdd-trace-utils v8.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v8.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:199:1
    │
199 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.2.0
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   └── libdd-trace-utils v8.0.0
          │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
          │       └── libdd-trace-utils v8.0.0 (*)
          ├── libdd-common v4.2.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.2.0 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:199:1
    │
199 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.2.0
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   └── libdd-trace-utils v8.0.0
          │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
          │       └── libdd-trace-utils v8.0.0 (*)
          ├── libdd-common v4.2.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.2.0 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:199:1
    │
199 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      └── rustls v0.23.37
          ├── hyper-rustls v0.27.7
          │   └── libdd-common v4.2.0
          │       ├── libdd-capabilities-impl v2.0.0
          │       │   └── libdd-trace-utils v8.0.0
          │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
          │       └── libdd-trace-utils v8.0.0 (*)
          ├── libdd-common v4.2.0 (*)
          └── tokio-rustls v0.26.0
              ├── hyper-rustls v0.27.7 (*)
              └── libdd-common v4.2.0 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-06-11 10:47:28 UTC | Commit: 128cc3c | dependency-check job results

rochdev and others added 2 commits June 11, 2026 12:39
…buffer corruption

Co-locate segment_id with its span in spans: HashMap<u64, (Span<T>, u64)>,
removing the separate segment_ids: HashMap<u64, u64>. This eliminates a
second HashMap lookup on every op that needs the segment_id.

Group the 5 cache state variables in flush_change_buffer into a SpanCache<T>
struct, fixing the too_many_arguments clippy lint on interpret_operation_cached.

Fix a buffer-corruption bug (P1) where BatchSetMeta/BatchSetMetric in the
cached path read the count but skipped the payload loop when
cached_deferred_meta/cached_deferred_metrics was null (e.g. after
materialize_span was called between flushes). The unread bytes were then
decoded as the next op's opcode, corrupting all subsequent ops in the buffer.
The fix moves the null-check inside the loop so bytes are always consumed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rochdev rochdev changed the title refactor(change-buffer): replace slot index with span_id, fix segment isolation refactor(change-buffer)!: replace slot index with span_id, fix segment isolation Jun 11, 2026
@dd-octo-sts

dd-octo-sts Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 7.70 MB 7.70 MB 0% (0 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 83.68 MB 83.68 MB +0% (+5.29 KB) 👌
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 94.79 MB 94.78 MB -0% (-3.00 KB) 👌
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.34 MB 10.34 MB -0% (-96 B) 👌
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 24.82 MB 24.83 MB +.06% (+16.00 KB) 🔍
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 86.89 KB 86.89 KB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 180.80 MB 180.83 MB +.01% (+24.00 KB) 🔍
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 925.69 MB 925.68 MB -0% (-12.17 KB) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 8.09 MB 8.09 MB -0% (-512 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 86.89 KB 86.89 KB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 23.93 MB 23.93 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 47.78 MB 47.78 MB -0% (-1.09 KB) 👌
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 21.52 MB 21.52 MB +0% (+512 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 88.26 KB 88.26 KB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 184.92 MB 184.90 MB --.01% (-24.00 KB) 💪
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 918.57 MB 918.35 MB --.02% (-219.24 KB) 💪
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 6.24 MB 6.24 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 88.26 KB 88.26 KB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 25.66 MB 25.66 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 45.41 MB 45.41 MB +0% (+946 B) 👌
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 74.60 MB 74.60 MB -0% (-2.61 KB) 👌
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 8.58 MB 8.58 MB 0% (0 B) 👌
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 90.02 MB 90.02 MB +0% (+1.80 KB) 👌
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.44 MB 10.44 MB +.04% (+4.36 KB) 🔍

/// trigger a rehash — i.e. before every Create op.
struct SpanCache<T: TraceData> {
span_id: u64,
span_ptr: *mut Span<T>,

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.

Having *mut pointers here seems a little scary in terms of ensuring stacked borrows etc when they're used

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.

I agree. I got rid of them in the upstream PR, using an index instead. I'm not sure saving one vec indexing is worth the unsafe business.

change_buffer,
spans: Vec::with_capacity(256),
traces: SmallTraceMap::default(),
spans: HashMap::with_capacity(256),

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.

why 256?

pub fn flush_chunk(
&mut self,
slot_indices: &[u32],
span_ids: Vec<u64>,

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.

Should this be a slice?

let (mut span, segment_id) = self
.spans
.remove(span_id)
.ok_or(ChangeBufferError::SpanNotFound(*span_id))?;

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.

If this fails, we stop removing the other spans. Is that what we want?

self.materialize_deferred_tags(*span_id, &mut span);

chunk_trace_id = Some(span.trace_id);
if let Some(entry) = seen_segment_ids

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.

Is this data-structure small enough that iter_mut.find is faster than keeping a set?

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.

This whole seen_segment_ids has been removed upstream in the end.

Comment on lines +871 to +877
// Segment 1 — span_id=1: origin → "origin-A" (string id 0)
w.op(OP_CREATE, 1); // span_id=1 in header
w.u128(TRACE_ID);
w.u64(1); // segment_id=1
w.u64(0); // parent_id
w.op(OP_SET_TRACE_ORIGIN, 1);
w.u32(0); // string_id → "origin-A"

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.

Should this have a helper function?


impl BufWriter {
fn new() -> Self {
let mut data = Vec::with_capacity(256);

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.

why 256?

let key_id: u32 = self.get_num_arg(index)?;
let val: f64 = self.get_num_arg(index)?;
deferred_metrics_at(&mut self.deferred_metrics, slot)?.insert(key_id, val);
if let Some(dm) = self.deferred_metrics.get_mut(&op.span_id) {

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.

I'd probably use .entry here, but YMMV

deferred_meta_at(&mut self.deferred_meta, slot)?.insert(key_id, val_id);
if !cache.deferred_meta.is_null() {
// SAFETY: pointer into self.deferred_meta, valid per function contract.
unsafe { &mut *cache.deferred_meta }.insert(key_id, val_id);

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.

Are we guaranteed to enforce stacked-borrows here?

}
}
}
OpCode::Create | OpCode::CreateSpan | OpCode::CreateSpanFull => unreachable!(),

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.

do we want to have a potential panic here?

Base automatically changed from yannham/change-buffer-state to main June 12, 2026 14:00
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot requested a review from a team as a code owner June 12, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants