Skip to content

Conversation

@bengl
Copy link
Contributor

@bengl bengl commented Jan 15, 2026

What does this PR do?

A brief description of the change being made with this pull request.

Motivation

What inspired you to submit this pull request?

Additional Notes

Anything else we should know when reviewing?

How to test the change?

Describe here in detail how the change can be validated.

@pr-commenter
Copy link

pr-commenter bot commented Jan 15, 2026

Benchmarks

Comparison

Benchmark execution time: 2026-02-10 20:31:01

Comparing candidate commit a472e65 in PR branch bengl/change-buffer with baseline commit 72e56a3 in branch main.

Found 10 performance improvements and 5 performance regressions! Performance is the same for 42 metrics, 2 unstable metrics.

scenario:benching deserializing traces from msgpack to their internal representation

  • 🟥 execution_time [+11.021ms; +11.689ms] or [+22.297%; +23.647%]

scenario:credit_card/is_card_number/ 378282246310005

  • 🟩 throughput [+555992.411op/s; +593109.732op/s] or [+4.168%; +4.446%]

scenario:credit_card/is_card_number/378282246310005

  • 🟩 execution_time [-3.585µs; -3.384µs] or [-4.967%; -4.688%]
  • 🟩 throughput [+683017.462op/s; +725230.762op/s] or [+4.930%; +5.235%]

scenario:credit_card/is_card_number/x371413321323331

  • 🟥 execution_time [+561.817ns; +578.423ns] or [+9.576%; +9.859%]
  • 🟥 throughput [-15354389.304op/s; -14872415.956op/s] or [-9.007%; -8.725%]

scenario:credit_card/is_card_number_no_luhn/x371413321323331

  • 🟥 execution_time [+559.624ns; +578.746ns] or [+9.537%; +9.863%]
  • 🟥 throughput [-15370319.723op/s; -14814648.260op/s] or [-9.018%; -8.692%]

scenario:normalization/normalize_name/normalize_name/Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Lo...

  • 🟩 execution_time [-20.573µs; -20.460µs] or [-9.955%; -9.901%]
  • 🟩 throughput [+531921.665op/s; +534803.596op/s] or [+10.992%; +11.052%]

scenario:normalization/normalize_name/normalize_name/bad-name

  • 🟩 throughput [+2196803.918op/s; +2280993.086op/s] or [+4.091%; +4.247%]

scenario:normalization/normalize_service/normalize_service/A0000000000000000000000000000000000000000000000000...

  • 🟩 execution_time [-41.449µs; -40.969µs] or [-7.723%; -7.633%]
  • 🟩 throughput [+154060.928op/s; +155819.264op/s] or [+8.269%; +8.363%]

scenario:normalization/normalize_service/normalize_service/Test Conversion 0f Weird !@#$%^&**() Characters

  • 🟩 execution_time [-22.099µs; -22.009µs] or [-11.654%; -11.607%]
  • 🟩 throughput [+692687.379op/s; +695384.349op/s] or [+13.135%; +13.186%]

Candidate

Candidate benchmark details

Group 1

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
normalization/normalize_service/normalize_service/A0000000000000000000000000000000000000000000000000... execution_time 494.565µs 495.522µs ± 1.018µs 495.298µs ± 0.269µs 495.576µs 498.354µs 499.313µs 502.539µs 1.46% 3.614 15.562 0.20% 0.072µs 1 200
normalization/normalize_service/normalize_service/A0000000000000000000000000000000000000000000000000... throughput 1989893.772op/s 2018082.029op/s ± 4115.549op/s 2018985.419op/s ± 1098.110op/s 2020064.175op/s 2021076.652op/s 2021641.411op/s 2021978.911op/s 0.15% -3.587 15.293 0.20% 291.013op/s 1 200
normalization/normalize_service/normalize_service/Data🐨dog🐶 繋がっ⛰てて execution_time 370.145µs 370.780µs ± 0.223µs 370.754µs ± 0.153µs 370.940µs 371.122µs 371.311µs 371.439µs 0.18% 0.117 0.042 0.06% 0.016µs 1 200
normalization/normalize_service/normalize_service/Data🐨dog🐶 繋がっ⛰てて throughput 2692231.157op/s 2697014.788op/s ± 1622.622op/s 2697204.494op/s ± 1110.706op/s 2698131.415op/s 2699463.790op/s 2701172.623op/s 2701642.998op/s 0.16% -0.113 0.042 0.06% 114.737op/s 1 200
normalization/normalize_service/normalize_service/Test Conversion 0f Weird !@#$%^&**() Characters execution_time 167.242µs 167.574µs ± 0.171µs 167.560µs ± 0.088µs 167.632µs 167.863µs 168.032µs 168.765µs 0.72% 2.214 11.383 0.10% 0.012µs 1 200
normalization/normalize_service/normalize_service/Test Conversion 0f Weird !@#$%^&**() Characters throughput 5925400.040op/s 5967522.719op/s ± 6063.946op/s 5968017.257op/s ± 3135.186op/s 5971307.451op/s 5974696.371op/s 5977619.749op/s 5979365.904op/s 0.19% -2.188 11.166 0.10% 428.786op/s 1 200
normalization/normalize_service/normalize_service/[empty string] execution_time 37.113µs 37.235µs ± 0.062µs 37.230µs ± 0.042µs 37.274µs 37.356µs 37.373µs 37.434µs 0.55% 0.506 0.013 0.17% 0.004µs 1 200
normalization/normalize_service/normalize_service/[empty string] throughput 26713691.095op/s 26856301.019op/s ± 44791.950op/s 26860149.803op/s ± 30488.098op/s 26890023.697op/s 26919432.053op/s 26936532.349op/s 26944753.329op/s 0.31% -0.497 -0.002 0.17% 3167.269op/s 1 200
normalization/normalize_service/normalize_service/test_ASCII execution_time 45.638µs 45.789µs ± 0.045µs 45.790µs ± 0.026µs 45.814µs 45.861µs 45.881µs 45.962µs 0.38% -0.059 1.402 0.10% 0.003µs 1 200
normalization/normalize_service/normalize_service/test_ASCII throughput 21757040.578op/s 21839151.899op/s ± 21310.169op/s 21838720.805op/s ± 12210.518op/s 21852511.451op/s 21872775.470op/s 21896807.826op/s 21911335.537op/s 0.33% 0.069 1.399 0.10% 1506.856op/s 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
normalization/normalize_service/normalize_service/A0000000000000000000000000000000000000000000000000... execution_time [495.381µs; 495.663µs] or [-0.028%; +0.028%] None None None
normalization/normalize_service/normalize_service/A0000000000000000000000000000000000000000000000000... throughput [2017511.653op/s; 2018652.404op/s] or [-0.028%; +0.028%] None None None
normalization/normalize_service/normalize_service/Data🐨dog🐶 繋がっ⛰てて execution_time [370.750µs; 370.811µs] or [-0.008%; +0.008%] None None None
normalization/normalize_service/normalize_service/Data🐨dog🐶 繋がっ⛰てて throughput [2696789.908op/s; 2697239.668op/s] or [-0.008%; +0.008%] None None None
normalization/normalize_service/normalize_service/Test Conversion 0f Weird !@#$%^&**() Characters execution_time [167.550µs; 167.598µs] or [-0.014%; +0.014%] None None None
normalization/normalize_service/normalize_service/Test Conversion 0f Weird !@#$%^&**() Characters throughput [5966682.315op/s; 5968363.124op/s] or [-0.014%; +0.014%] None None None
normalization/normalize_service/normalize_service/[empty string] execution_time [37.227µs; 37.244µs] or [-0.023%; +0.023%] None None None
normalization/normalize_service/normalize_service/[empty string] throughput [26850093.286op/s; 26862508.753op/s] or [-0.023%; +0.023%] None None None
normalization/normalize_service/normalize_service/test_ASCII execution_time [45.783µs; 45.796µs] or [-0.014%; +0.014%] None None None
normalization/normalize_service/normalize_service/test_ASCII throughput [21836198.514op/s; 21842105.283op/s] or [-0.014%; +0.014%] None None None

Group 2

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
benching serializing traces from their internal representation to msgpack execution_time 13.853ms 13.899ms ± 0.029ms 13.893ms ± 0.011ms 13.905ms 13.965ms 14.005ms 14.061ms 1.21% 2.681 9.431 0.21% 0.002ms 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
benching serializing traces from their internal representation to msgpack execution_time [13.895ms; 13.903ms] or [-0.029%; +0.029%] None None None

Group 3

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
benching deserializing traces from msgpack to their internal representation execution_time 60.236ms 60.784ms ± 2.198ms 60.487ms ± 0.092ms 60.598ms 60.885ms 75.138ms 80.477ms 33.05% 8.071 64.599 3.61% 0.155ms 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
benching deserializing traces from msgpack to their internal representation execution_time [60.479ms; 61.088ms] or [-0.501%; +0.501%] None None None

Group 4

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
ip_address/quantize_peer_ip_address_benchmark execution_time 4.972µs 5.039µs ± 0.039µs 5.040µs ± 0.032µs 5.066µs 5.107µs 5.113µs 5.118µs 1.53% 0.140 -1.082 0.78% 0.003µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
ip_address/quantize_peer_ip_address_benchmark execution_time [5.033µs; 5.044µs] or [-0.108%; +0.108%] None None None

Group 5

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
concentrator/add_spans_to_concentrator execution_time 10.684ms 10.713ms ± 0.013ms 10.712ms ± 0.007ms 10.719ms 10.734ms 10.774ms 10.791ms 0.74% 1.973 8.357 0.12% 0.001ms 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
concentrator/add_spans_to_concentrator execution_time [10.712ms; 10.715ms] or [-0.017%; +0.017%] None None None

Group 6

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
tags/replace_trace_tags execution_time 2.318µs 2.369µs ± 0.014µs 2.368µs ± 0.004µs 2.373µs 2.396µs 2.402µs 2.414µs 1.92% -0.558 3.179 0.59% 0.001µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
tags/replace_trace_tags execution_time [2.367µs; 2.370µs] or [-0.082%; +0.082%] None None None

Group 7

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
two way interface execution_time 17.719µs 24.845µs ± 8.881µs 18.081µs ± 0.150µs 32.560µs 40.657µs 41.234µs 68.324µs 277.88% 1.045 1.191 35.65% 0.628µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
two way interface execution_time [23.614µs; 26.076µs] or [-4.954%; +4.954%] None None None

Group 8

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
normalization/normalize_trace/test_trace execution_time 245.811ns 258.452ns ± 14.712ns 250.237ns ± 2.902ns 264.297ns 285.351ns 299.082ns 304.547ns 21.70% 1.348 0.613 5.68% 1.040ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
normalization/normalize_trace/test_trace execution_time [256.413ns; 260.491ns] or [-0.789%; +0.789%] None None None

Group 9

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
single_flag_killswitch/rules-based execution_time 187.038ns 190.105ns ± 2.370ns 189.624ns ± 1.700ns 191.400ns 194.775ns 196.291ns 197.824ns 4.32% 0.892 0.186 1.24% 0.168ns 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
single_flag_killswitch/rules-based execution_time [189.776ns; 190.433ns] or [-0.173%; +0.173%] None None None

Group 10

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
receiver_entry_point/report/2597 execution_time 9.576ms 9.883ms ± 0.091ms 9.891ms ± 0.031ms 9.925ms 9.985ms 10.088ms 10.248ms 3.61% -0.903 3.478 0.91% 0.006ms 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
receiver_entry_point/report/2597 execution_time [9.871ms; 9.896ms] or [-0.127%; +0.127%] None None None

Group 11

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
write only interface execution_time 1.219µs 3.190µs ± 1.426µs 3.032µs ± 0.019µs 3.050µs 3.189µs 13.879µs 14.902µs 391.50% 7.562 57.447 44.60% 0.101µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
write only interface execution_time [2.993µs; 3.388µs] or [-6.197%; +6.197%] None None None

Group 12

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
benching string interning on wordpress profile execution_time 161.086µs 161.652µs ± 0.433µs 161.570µs ± 0.155µs 161.759µs 162.145µs 163.334µs 165.496µs 2.43% 4.483 32.279 0.27% 0.031µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
benching string interning on wordpress profile execution_time [161.592µs; 161.712µs] or [-0.037%; +0.037%] None None None

Group 13

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
profile_add_sample2_frames_x1000 execution_time 530.896µs 531.951µs ± 0.554µs 531.886µs ± 0.272µs 532.165µs 532.675µs 533.211µs 536.660µs 0.90% 3.418 25.269 0.10% 0.039µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
profile_add_sample2_frames_x1000 execution_time [531.874µs; 532.027µs] or [-0.014%; +0.014%] None None None

Group 14

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
profile_add_sample_frames_x1000 execution_time 3.938ms 3.944ms ± 0.007ms 3.943ms ± 0.001ms 3.944ms 3.947ms 3.954ms 4.034ms 2.32% 11.742 152.302 0.17% 0.000ms 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
profile_add_sample_frames_x1000 execution_time [3.943ms; 3.944ms] or [-0.024%; +0.024%] None None None

Group 15

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
sdk_test_data/rules-based execution_time 148.746µs 150.746µs ± 1.612µs 150.525µs ± 0.559µs 151.120µs 152.578µs 157.086µs 164.597µs 9.35% 4.857 34.667 1.07% 0.114µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
sdk_test_data/rules-based execution_time [150.523µs; 150.970µs] or [-0.148%; +0.148%] None None None

Group 16

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
credit_card/is_card_number/ execution_time 3.899µs 3.914µs ± 0.002µs 3.914µs ± 0.001µs 3.916µs 3.918µs 3.920µs 3.923µs 0.22% -0.783 7.079 0.06% 0.000µs 1 200
credit_card/is_card_number/ throughput 254927102.323op/s 255475883.640op/s ± 154594.963op/s 255488004.847op/s ± 88752.119op/s 255567693.496op/s 255675731.044op/s 255753974.441op/s 256447342.127op/s 0.38% 0.799 7.167 0.06% 10931.515op/s 1 200
credit_card/is_card_number/ 3782-8224-6310-005 execution_time 76.726µs 78.299µs ± 0.788µs 78.184µs ± 0.504µs 78.780µs 79.767µs 80.205µs 81.017µs 3.62% 0.637 0.202 1.00% 0.056µs 1 200
credit_card/is_card_number/ 3782-8224-6310-005 throughput 12343059.922op/s 12772801.994op/s ± 127772.051op/s 12790281.975op/s ± 82992.714op/s 12866195.615op/s 12945162.920op/s 13017011.294op/s 13033323.867op/s 1.90% -0.584 0.100 1.00% 9034.848op/s 1 200
credit_card/is_card_number/ 378282246310005 execution_time 70.702µs 71.876µs ± 0.676µs 71.821µs ± 0.480µs 72.307µs 73.123µs 73.541µs 73.838µs 2.81% 0.509 -0.260 0.94% 0.048µs 1 200
credit_card/is_card_number/ 378282246310005 throughput 13543131.708op/s 13914050.133op/s ± 130179.185op/s 13923416.411op/s ± 93733.324op/s 14017036.652op/s 14110327.222op/s 14127599.735op/s 14143802.379op/s 1.58% -0.468 -0.320 0.93% 9205.058op/s 1 200
credit_card/is_card_number/37828224631 execution_time 3.899µs 3.917µs ± 0.003µs 3.917µs ± 0.002µs 3.919µs 3.923µs 3.924µs 3.925µs 0.20% -0.314 2.295 0.09% 0.000µs 1 200
credit_card/is_card_number/37828224631 throughput 254797523.228op/s 255312403.605op/s ± 228169.741op/s 255304793.956op/s ± 157879.007op/s 255486689.145op/s 255630137.477op/s 255671068.792op/s 256476766.116op/s 0.46% 0.326 2.344 0.09% 16134.037op/s 1 200
credit_card/is_card_number/378282246310005 execution_time 67.273µs 68.695µs ± 0.696µs 68.720µs ± 0.493µs 69.162µs 69.833µs 70.172µs 71.385µs 3.88% 0.324 0.306 1.01% 0.049µs 1 200
credit_card/is_card_number/378282246310005 throughput 14008559.998op/s 14558659.401op/s ± 147013.265op/s 14551882.060op/s ± 104666.064op/s 14674829.893op/s 14788326.305op/s 14855369.354op/s 14864913.571op/s 2.15% -0.259 0.173 1.01% 10395.408op/s 1 200
credit_card/is_card_number/37828224631000521389798 execution_time 53.031µs 53.144µs ± 0.105µs 53.130µs ± 0.022µs 53.156µs 53.193µs 53.231µs 54.159µs 1.94% 8.562 78.657 0.20% 0.007µs 1 200
credit_card/is_card_number/37828224631000521389798 throughput 18464157.261op/s 18816939.098op/s ± 36628.527op/s 18821612.689op/s ± 7924.247op/s 18828361.380op/s 18835997.081op/s 18841955.369op/s 18856951.465op/s 0.19% -8.519 78.111 0.19% 2590.028op/s 1 200
credit_card/is_card_number/x371413321323331 execution_time 6.429µs 6.437µs ± 0.004µs 6.437µs ± 0.003µs 6.440µs 6.444µs 6.448µs 6.450µs 0.20% 0.410 0.109 0.06% 0.000µs 1 200
credit_card/is_card_number/x371413321323331 throughput 155044235.497op/s 155348906.436op/s ± 96410.242op/s 155348571.857op/s ± 66495.637op/s 155418121.753op/s 155494816.081op/s 155534171.399op/s 155550744.226op/s 0.13% -0.407 0.103 0.06% 6817.234op/s 1 200
credit_card/is_card_number_no_luhn/ execution_time 3.897µs 3.915µs ± 0.003µs 3.915µs ± 0.002µs 3.917µs 3.920µs 3.922µs 3.933µs 0.47% 0.201 9.748 0.08% 0.000µs 1 200
credit_card/is_card_number_no_luhn/ throughput 254243579.081op/s 255407017.629op/s ± 202426.827op/s 255435553.623op/s ± 122010.718op/s 255536688.680op/s 255636046.948op/s 255698762.602op/s 256602518.380op/s 0.46% -0.173 9.765 0.08% 14313.738op/s 1 200
credit_card/is_card_number_no_luhn/ 3782-8224-6310-005 execution_time 64.916µs 65.153µs ± 0.171µs 65.095µs ± 0.072µs 65.217µs 65.475µs 65.788µs 65.897µs 1.23% 1.714 3.594 0.26% 0.012µs 1 200
credit_card/is_card_number_no_luhn/ 3782-8224-6310-005 throughput 15175084.010op/s 15348554.291op/s ± 40022.567op/s 15362255.709op/s ± 16925.493op/s 15375209.013op/s 15389995.123op/s 15400730.673op/s 15404579.782op/s 0.28% -1.694 3.491 0.26% 2830.023op/s 1 200
credit_card/is_card_number_no_luhn/ 378282246310005 execution_time 58.259µs 58.952µs ± 0.246µs 58.923µs ± 0.140µs 59.068µs 59.411µs 59.582µs 59.645µs 1.23% 0.462 0.403 0.42% 0.017µs 1 200
credit_card/is_card_number_no_luhn/ 378282246310005 throughput 16765816.748op/s 16963213.053op/s ± 70621.170op/s 16971324.441op/s ± 40350.659op/s 17007838.508op/s 17058013.618op/s 17115519.088op/s 17164774.974op/s 1.14% -0.435 0.389 0.42% 4993.671op/s 1 200
credit_card/is_card_number_no_luhn/37828224631 execution_time 3.895µs 3.915µs ± 0.003µs 3.914µs ± 0.002µs 3.916µs 3.919µs 3.920µs 3.930µs 0.41% -0.551 14.266 0.07% 0.000µs 1 200
credit_card/is_card_number_no_luhn/37828224631 throughput 254427197.610op/s 255447717.449op/s ± 183525.185op/s 255462613.887op/s ± 108068.994op/s 255561054.592op/s 255646951.120op/s 255703819.918op/s 256717732.119op/s 0.49% 0.585 14.383 0.07% 12977.190op/s 1 200
credit_card/is_card_number_no_luhn/378282246310005 execution_time 55.243µs 55.660µs ± 0.195µs 55.615µs ± 0.119µs 55.780µs 56.007µs 56.172µs 56.435µs 1.48% 0.947 1.086 0.35% 0.014µs 1 200
credit_card/is_card_number_no_luhn/378282246310005 throughput 17719413.094op/s 17966562.497op/s ± 62772.085op/s 17980891.708op/s ± 38402.642op/s 18014249.278op/s 18038760.698op/s 18069266.366op/s 18101820.933op/s 0.67% -0.925 1.015 0.35% 4438.657op/s 1 200
credit_card/is_card_number_no_luhn/37828224631000521389798 execution_time 52.821µs 53.103µs ± 0.064µs 53.112µs ± 0.019µs 53.133µs 53.173µs 53.212µs 53.298µs 0.35% -1.831 4.964 0.12% 0.005µs 1 200
credit_card/is_card_number_no_luhn/37828224631000521389798 throughput 18762487.850op/s 18831290.353op/s ± 22660.582op/s 18828089.878op/s ± 6876.096op/s 18834638.625op/s 18886595.717op/s 18911241.654op/s 18931890.770op/s 0.55% 1.844 5.000 0.12% 1602.345op/s 1 200
credit_card/is_card_number_no_luhn/x371413321323331 execution_time 6.429µs 6.437µs ± 0.005µs 6.436µs ± 0.002µs 6.439µs 6.448µs 6.453µs 6.471µs 0.55% 2.372 10.043 0.08% 0.000µs 1 200
credit_card/is_card_number_no_luhn/x371413321323331 throughput 154530641.517op/s 155351626.140op/s ± 124015.592op/s 155379085.975op/s ± 57303.945op/s 155429698.744op/s 155485799.396op/s 155511460.834op/s 155538522.608op/s 0.10% -2.357 9.916 0.08% 8769.227op/s 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
credit_card/is_card_number/ execution_time [3.914µs; 3.915µs] or [-0.008%; +0.008%] None None None
credit_card/is_card_number/ throughput [255454458.265op/s; 255497309.015op/s] or [-0.008%; +0.008%] None None None
credit_card/is_card_number/ 3782-8224-6310-005 execution_time [78.190µs; 78.408µs] or [-0.139%; +0.139%] None None None
credit_card/is_card_number/ 3782-8224-6310-005 throughput [12755094.017op/s; 12790509.972op/s] or [-0.139%; +0.139%] None None None
credit_card/is_card_number/ 378282246310005 execution_time [71.782µs; 71.970µs] or [-0.130%; +0.130%] None None None
credit_card/is_card_number/ 378282246310005 throughput [13896008.550op/s; 13932091.716op/s] or [-0.130%; +0.130%] None None None
credit_card/is_card_number/37828224631 execution_time [3.916µs; 3.917µs] or [-0.012%; +0.012%] None None None
credit_card/is_card_number/37828224631 throughput [255280781.474op/s; 255344025.737op/s] or [-0.012%; +0.012%] None None None
credit_card/is_card_number/378282246310005 execution_time [68.598µs; 68.791µs] or [-0.140%; +0.140%] None None None
credit_card/is_card_number/378282246310005 throughput [14538284.776op/s; 14579034.025op/s] or [-0.140%; +0.140%] None None None
credit_card/is_card_number/37828224631000521389798 execution_time [53.129µs; 53.158µs] or [-0.027%; +0.027%] None None None
credit_card/is_card_number/37828224631000521389798 throughput [18811862.737op/s; 18822015.460op/s] or [-0.027%; +0.027%] None None None
credit_card/is_card_number/x371413321323331 execution_time [6.437µs; 6.438µs] or [-0.009%; +0.009%] None None None
credit_card/is_card_number/x371413321323331 throughput [155335544.903op/s; 155362267.968op/s] or [-0.009%; +0.009%] None None None
credit_card/is_card_number_no_luhn/ execution_time [3.915µs; 3.916µs] or [-0.011%; +0.011%] None None None
credit_card/is_card_number_no_luhn/ throughput [255378963.218op/s; 255435072.040op/s] or [-0.011%; +0.011%] None None None
credit_card/is_card_number_no_luhn/ 3782-8224-6310-005 execution_time [65.130µs; 65.177µs] or [-0.036%; +0.036%] None None None
credit_card/is_card_number_no_luhn/ 3782-8224-6310-005 throughput [15343007.549op/s; 15354101.034op/s] or [-0.036%; +0.036%] None None None
credit_card/is_card_number_no_luhn/ 378282246310005 execution_time [58.918µs; 58.986µs] or [-0.058%; +0.058%] None None None
credit_card/is_card_number_no_luhn/ 378282246310005 throughput [16953425.638op/s; 16973000.468op/s] or [-0.058%; +0.058%] None None None
credit_card/is_card_number_no_luhn/37828224631 execution_time [3.914µs; 3.915µs] or [-0.010%; +0.010%] None None None
credit_card/is_card_number_no_luhn/37828224631 throughput [255422282.623op/s; 255473152.274op/s] or [-0.010%; +0.010%] None None None
credit_card/is_card_number_no_luhn/378282246310005 execution_time [55.633µs; 55.687µs] or [-0.049%; +0.049%] None None None
credit_card/is_card_number_no_luhn/378282246310005 throughput [17957862.890op/s; 17975262.105op/s] or [-0.048%; +0.048%] None None None
credit_card/is_card_number_no_luhn/37828224631000521389798 execution_time [53.094µs; 53.112µs] or [-0.017%; +0.017%] None None None
credit_card/is_card_number_no_luhn/37828224631000521389798 throughput [18828149.815op/s; 18834430.892op/s] or [-0.017%; +0.017%] None None None
credit_card/is_card_number_no_luhn/x371413321323331 execution_time [6.436µs; 6.438µs] or [-0.011%; +0.011%] None None None
credit_card/is_card_number_no_luhn/x371413321323331 throughput [155334438.772op/s; 155368813.509op/s] or [-0.011%; +0.011%] None None None

Group 17

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
sql/obfuscate_sql_string execution_time 89.753µs 89.916µs ± 0.222µs 89.890µs ± 0.036µs 89.930µs 90.041µs 90.172µs 92.851µs 3.29% 11.649 150.531 0.25% 0.016µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
sql/obfuscate_sql_string execution_time [89.885µs; 89.947µs] or [-0.034%; +0.034%] None None None

Group 18

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
normalization/normalize_name/normalize_name/Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Lo... execution_time 185.616µs 186.139µs ± 0.247µs 186.115µs ± 0.167µs 186.300µs 186.556µs 186.696µs 187.081µs 0.52% 0.513 0.271 0.13% 0.017µs 1 200
normalization/normalize_name/normalize_name/Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Lo... throughput 5345292.534op/s 5372348.257op/s ± 7113.977op/s 5373008.343op/s ± 4804.950op/s 5377348.725op/s 5383113.677op/s 5384196.076op/s 5387458.616op/s 0.27% -0.505 0.251 0.13% 503.034op/s 1 200
normalization/normalize_name/normalize_name/bad-name execution_time 17.791µs 17.876µs ± 0.047µs 17.868µs ± 0.030µs 17.900µs 17.970µs 17.999µs 18.070µs 1.13% 0.978 1.201 0.26% 0.003µs 1 200
normalization/normalize_name/normalize_name/bad-name throughput 55340703.413op/s 55941619.781op/s ± 147150.511op/s 55965814.767op/s ± 93256.782op/s 56035790.411op/s 56134060.038op/s 56185939.773op/s 56209522.649op/s 0.44% -0.961 1.146 0.26% 10405.112op/s 1 200
normalization/normalize_name/normalize_name/good execution_time 10.449µs 10.513µs ± 0.031µs 10.509µs ± 0.019µs 10.530µs 10.567µs 10.591µs 10.660µs 1.44% 0.892 2.430 0.29% 0.002µs 1 200
normalization/normalize_name/normalize_name/good throughput 93806144.947op/s 95122390.694op/s ± 279846.706op/s 95157327.410op/s ± 172908.514op/s 95306049.742op/s 95499824.137op/s 95679866.371op/s 95706434.029op/s 0.58% -0.860 2.305 0.29% 19788.150op/s 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
normalization/normalize_name/normalize_name/Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Lo... execution_time [186.104µs; 186.173µs] or [-0.018%; +0.018%] None None None
normalization/normalize_name/normalize_name/Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Long-.Too-Lo... throughput [5371362.328op/s; 5373334.186op/s] or [-0.018%; +0.018%] None None None
normalization/normalize_name/normalize_name/bad-name execution_time [17.869µs; 17.882µs] or [-0.037%; +0.037%] None None None
normalization/normalize_name/normalize_name/bad-name throughput [55921226.135op/s; 55962013.427op/s] or [-0.036%; +0.036%] None None None
normalization/normalize_name/normalize_name/good execution_time [10.509µs; 10.517µs] or [-0.041%; +0.041%] None None None
normalization/normalize_name/normalize_name/good throughput [95083606.632op/s; 95161174.756op/s] or [-0.041%; +0.041%] None None None

Group 19

cpu_model git_commit_sha git_commit_date git_branch
Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz a472e65 1770754444 bengl/change-buffer
scenario metric min mean ± sd median ± mad p75 p95 p99 max peak_to_median_ratio skewness kurtosis cv sem runs sample_size
redis/obfuscate_redis_string execution_time 34.756µs 35.407µs ± 0.953µs 34.960µs ± 0.116µs 35.208µs 37.423µs 37.483µs 38.810µs 11.01% 1.672 1.110 2.68% 0.067µs 1 200
scenario metric 95% CI mean Shapiro-Wilk pvalue Ljung-Box pvalue (lag=1) Dip test pvalue
redis/obfuscate_redis_string execution_time [35.275µs; 35.539µs] or [-0.373%; +0.373%] None None None

Baseline

Omitted due to size.

@codecov-commenter
Copy link

codecov-commenter commented Jan 15, 2026

Codecov Report

❌ Patch coverage is 0% with 233 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.93%. Comparing base (51c8cb4) to head (5a6f809).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1453      +/-   ##
==========================================
- Coverage   71.29%   70.93%   -0.36%     
==========================================
  Files         416      418       +2     
  Lines       66872    67233     +361     
==========================================
+ Hits        47676    47694      +18     
- Misses      19196    19539     +343     
Components Coverage Δ
libdd-crashtracker 61.42% <ø> (+0.19%) ⬆️
libdd-crashtracker-ffi 16.74% <ø> (+1.66%) ⬆️
libdd-alloc 98.73% <ø> (ø)
libdd-data-pipeline 86.02% <ø> (+0.27%) ⬆️
libdd-data-pipeline-ffi 77.63% <ø> (+0.62%) ⬆️
libdd-common 80.84% <ø> (ø)
libdd-common-ffi 74.19% <ø> (ø)
libdd-telemetry 60.22% <ø> (-0.04%) ⬇️
libdd-telemetry-ffi 21.17% <ø> (ø)
libdd-dogstatsd-client 83.75% <ø> (ø)
datadog-ipc 82.62% <ø> (+<0.01%) ⬆️
libdd-profiling 80.67% <ø> (+0.01%) ⬆️
libdd-profiling-ffi 62.46% <ø> (ø)
datadog-sidecar 35.37% <ø> (-1.01%) ⬇️
datdog-sidecar-ffi 11.26% <ø> (-2.12%) ⬇️
spawn-worker 55.18% <ø> (ø)
libdd-tinybytes 92.44% <ø> (ø)
libdd-trace-normalization 82.33% <ø> (ø)
libdd-trace-obfuscation 94.17% <ø> (ø)
libdd-trace-protobuf 61.18% <ø> (ø)
libdd-trace-utils 86.90% <0.00%> (-3.00%) ⬇️
datadog-tracer-flare 59.74% <ø> (ø)
libdd-log 75.57% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bengl bengl force-pushed the bengl/change-buffer branch from ae7b0d1 to 4c76607 Compare January 16, 2026 20:19
@dd-octo-sts
Copy link

dd-octo-sts bot commented Jan 16, 2026

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 8.00 MB 8.00 MB 0% (0 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 91.81 MB 91.81 MB 0% (0 B) 👌
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 106.16 MB 106.16 MB 0% (0 B) 👌
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.37 MB 10.37 MB 0% (0 B) 👌
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 24.71 MB 24.71 MB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 76.33 KB 76.33 KB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 164.56 MB 164.58 MB +0% (+16.00 KB) 👌
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 811.95 MB 811.95 MB +0% (+1.20 KB) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 9.31 MB 9.31 MB +0% (+512 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 76.33 KB 76.33 KB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 22.93 MB 22.93 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 48.32 MB 48.32 MB -0% (-1.72 KB) 👌
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 20.82 MB 20.82 MB -0% (-512 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 77.50 KB 77.50 KB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 168.40 MB 168.41 MB +0% (+8.00 KB) 👌
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 798.69 MB 798.69 MB +0% (+1.62 KB) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 7.03 MB 7.03 MB -0% (-512 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 77.50 KB 77.50 KB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 24.48 MB 24.48 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 44.00 MB 44.00 MB -0% (-1.24 KB) 👌
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 79.91 MB 79.91 MB 0% (0 B) 👌
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 9.51 MB 9.51 MB 0% (0 B) 👌
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 99.86 MB 99.86 MB 0% (0 B) 👌
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 11.08 MB 11.08 MB 0% (0 B) 👌

trace_span_counts: HashMap<u128, usize>,
tracer_service: T,
tracer_language: T,
pid: f64,
Copy link
Contributor

Choose a reason for hiding this comment

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

Aren't PIDs integers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not in trace exporter's config 🤷

Copy link
Contributor

@ekump ekump Feb 3, 2026

Choose a reason for hiding this comment

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

Is this what you're referring to? Because we send it as a metric, which has to be f64?

Would it be better to do the conversion to f64 internally and not expose that implementation detail in the public API? Going from u32 to f64 should be cheap in Rust.

This is non-blocking. It's not a hill I need to die on.


impl From<u64> for OpCode {
fn from(val: u64) -> Self {
unsafe { std::mem::transmute(val) }
Copy link
Contributor

Choose a reason for hiding this comment

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

This is UB if someone sends an invalid opcode. Could you use try_from instead?

Something like...

impl TryFrom<u64> for OpCode {
    type Error = anyhow::Error;
    fn try_from(val: u64) -> Result<Self, Self::Error> {
        match val {
            0 => Ok(OpCode::Create),
            ...
            _ => Err(anyhow!("invalid opcode: {}", val))
        }
    }
}

You'll need to update BufferedOperation::from_buf and flush_change_buffer to handle the Result, but both of those functions return Results anyway, so that shouldn't be a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like to keep the transmute and just bounds-check it in the try_from. SGTY?

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason to do bound-check + transmute rather than exhaust matching?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The main reason is to avoid having all the OpCodes listed out in two places. Maybe I can macro that away? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe using a crate like num_enum or num_traits?

use crate::span::{Span, SpanText};

#[derive(Clone, Copy)]
pub struct ChangeBuffer(*const u8);
Copy link
Contributor

@ekump ekump Jan 21, 2026

Choose a reason for hiding this comment

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

Instead of a raw pointer, can the buffer be &mut [u8]? If we can do that, I think you can move the unsafe code to the FFI layer / caller where it better belongs. The caller would need to do something like

let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
let change_buffer = ChangeBuffer::new(slice); 

If we can do that, then we won't need the unsafe code in get_num_raw where every read has the potential for UB if we get the pointer math wrong. I think you'd also be able to get rid of the unsafe Send and Sync definitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is lifetimes. In napi.rs, the Buffer object we get from Node.js will have a lifetime as long as the function call. That said, the informal promise is that the Buffer will persist on the JS side forever, as good as 'static. Raw pointers allowed me to get around that.

I think I can take it a step further and convert that back to a slice with new ownership so that we can avoid all the unsafe. I'll give it a try.

.insert(T::from_static_str("_dd.rule_psr"), rule);
}
if let Some(rule) = trace.sampling_limit_decision {
span.metrics.insert(T::from_static_str("_dd.;_psr"), rule);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is _dd.;_psr correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct.


impl From<u64> for OpCode {
fn from(val: u64) -> Self {
unsafe { std::mem::transmute(val) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason to do bound-check + transmute rather than exhaust matching?

@hoolioh
Copy link
Contributor

hoolioh commented Jan 27, 2026

This is more of a general comment. Since trace-utils is too crowded and we talked about refactoring it. Would it make sense to place this implmentation in a new crate? I don't say that I has to happen now. Maybe in a later PR when we split trace-utils.

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

📚 Documentation Check Results

⚠️ 459 documentation warning(s) found

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


Updated: 2026-02-10 20:15:40 UTC | Commit: b6b7a7c | missing-docs job results

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

🔒 Cargo Deny Results

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

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

Show output
error[vulnerability]: Integer overflow in `BytesMut::reserve`
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:49:1
   │
49 │ bytes 1.8.0 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
   │
   ├ ID: RUSTSEC-2026-0007
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0007
   ├ In the unique reclaim path of `BytesMut::reserve`, the condition
     ```rs
     if v_capacity >= new_cap + offset
     ```
     uses an unchecked addition. When `new_cap + offset` overflows `usize` in release builds, this condition may incorrectly pass, causing `self.cap` to be set to a value that exceeds the actual allocated capacity. Subsequent APIs such as `spare_capacity_mut()` then trust this corrupted `cap` value and may create out-of-bounds slices, leading to UB.
     
     This behavior is observable in release builds (integer overflow wraps), whereas debug builds panic due to overflow checks.
     
     ## PoC
     
     ```rs
     use bytes::*;
     
     fn main() {
         let mut a = BytesMut::from(&b"hello world"[..]);
         let mut b = a.split_off(5);
     
         // Ensure b becomes the unique owner of the backing storage
         drop(a);
     
         // Trigger overflow in new_cap + offset inside reserve
         b.reserve(usize::MAX - 6);
     
         // This call relies on the corrupted cap and may cause UB & HBO
         b.put_u8(b'h');
     }
     ```
     
     # Workarounds
     
     Users of `BytesMut::reserve` are only affected if integer overflow checks are configured to wrap. When integer overflow is configured to panic, this issue does not apply.
   ├ Announcement: https://github.com/advisories/GHSA-434x-w66g-qw3r
   ├ Solution: Upgrade to >=1.11.1 (try `cargo update -p bytes`)
   ├ bytes v1.8.0
     ├── h2 v0.4.6
     │   └── hyper v1.6.0
     │       ├── httpmock v0.8.0-alpha.1
     │       │   └── libdd-trace-utils v1.0.0
     │       │       └── (dev) libdd-trace-utils v1.0.0 (*)
     │       ├── hyper-rustls v0.27.3
     │       │   └── libdd-common v1.1.0
     │       │       └── libdd-trace-utils v1.0.0 (*)
     │       ├── hyper-util v0.1.17
     │       │   ├── httpmock v0.8.0-alpha.1 (*)
     │       │   ├── hyper-rustls v0.27.3 (*)
     │       │   └── libdd-common v1.1.0 (*)
     │       ├── libdd-common v1.1.0 (*)
     │       └── libdd-trace-utils v1.0.0 (*)
     ├── headers v0.4.0
     │   └── httpmock v0.8.0-alpha.1 (*)
     ├── http v1.1.0
     │   ├── h2 v0.4.6 (*)
     │   ├── headers v0.4.0 (*)
     │   ├── headers-core v0.3.0
     │   │   └── headers v0.4.0 (*)
     │   ├── http-body v1.0.1
     │   │   ├── http-body-util v0.1.2
     │   │   │   ├── httpmock v0.8.0-alpha.1 (*)
     │   │   │   ├── libdd-common v1.1.0 (*)
     │   │   │   └── libdd-trace-utils v1.0.0 (*)
     │   │   ├── hyper v1.6.0 (*)
     │   │   ├── hyper-util v0.1.17 (*)
     │   │   └── libdd-common v1.1.0 (*)
     │   ├── http-body-util v0.1.2 (*)
     │   ├── httpmock v0.8.0-alpha.1 (*)
     │   ├── hyper v1.6.0 (*)
     │   ├── hyper-rustls v0.27.3 (*)
     │   ├── hyper-util v0.1.17 (*)
     │   ├── libdd-common v1.1.0 (*)
     │   └── libdd-trace-utils v1.0.0 (*)
     ├── http-body v1.0.1 (*)
     ├── http-body-util v0.1.2 (*)
     ├── httpmock v0.8.0-alpha.1 (*)
     ├── hyper v1.6.0 (*)
     ├── hyper-util v0.1.17 (*)
     ├── libdd-trace-utils v1.0.0 (*)
     ├── prost v0.14.3
     │   ├── libdd-trace-protobuf v1.0.0
     │   │   ├── libdd-trace-normalization v1.0.0
     │   │   │   └── libdd-trace-utils v1.0.0 (*)
     │   │   └── libdd-trace-utils v1.0.0 (*)
     │   └── libdd-trace-utils v1.0.0 (*)
     ├── tokio v1.49.0
     │   ├── h2 v0.4.6 (*)
     │   ├── httpmock v0.8.0-alpha.1 (*)
     │   ├── hyper v1.6.0 (*)
     │   ├── hyper-rustls v0.27.3 (*)
     │   ├── hyper-util v0.1.17 (*)
     │   ├── (dev) libdd-common v1.1.0 (*)
     │   ├── (dev) libdd-trace-protobuf v1.0.0 (*)
     │   ├── (dev) libdd-trace-utils v1.0.0 (*)
     │   ├── tokio-rustls v0.26.0
     │   │   ├── hyper-rustls v0.27.3 (*)
     │   │   └── libdd-common v1.1.0 (*)
     │   └── tokio-util v0.7.12
     │       └── h2 v0.4.6 (*)
     └── tokio-util v0.7.12 (*)

error[vulnerability]: Lenient `hyper` header parsing of `Content-Length` could allow request smuggling
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:132:1
    │
132 │ hyper 0.10.16 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2021-0078
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0078
    ├ `hyper`'s HTTP header parser accepted, according to RFC 7230, illegal contents inside `Content-Length` headers.
      Due to this, upstream HTTP proxies that ignore the header may still forward them along if it chooses to ignore the error.
      
      To be vulnerable, `hyper` must be used as an HTTP/1 server and using an HTTP proxy upstream that ignores the header's contents
      but still forwards it. Due to all the factors that must line up, an attack exploiting this vulnerability is unlikely.
    ├ Announcement: https://github.com/hyperium/hyper/security/advisories/GHSA-f3pg-qwvg-p99c
    ├ Solution: Upgrade to >=0.14.10 (try `cargo update -p hyper`)
    ├ hyper v0.10.16
      ├── iron v0.6.1
      │   └── multipart v0.18.0
      │       └── (dev) libdd-common v1.1.0
      │           └── libdd-trace-utils v1.0.0
      │               └── (dev) libdd-trace-utils v1.0.0 (*)
      ├── multipart v0.18.0 (*)
      └── nickel v0.11.0
          └── multipart v0.18.0 (*)

error[vulnerability]: Integer overflow in `hyper`'s parsing of the `Transfer-Encoding` header leads to data loss
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:132:1
    │
132 │ hyper 0.10.16 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2021-0079
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0079
    ├ When decoding chunk sizes that are too large, `hyper`'s code would encounter an integer overflow. Depending on the situation,
      this could lead to data loss from an incorrect total size, or in rarer cases, a request smuggling attack.
      
      To be vulnerable, you must be using `hyper` for any HTTP/1 purpose, including as a client or server, and consumers must send
      requests or responses that specify a chunk size greater than 18 exabytes. For a possible request smuggling attack to be possible,
      any upstream proxies must accept a chunk size greater than 64 bits.
    ├ Announcement: https://github.com/hyperium/hyper/security/advisories/GHSA-5h46-h7hh-c6x9
    ├ Solution: Upgrade to >=0.14.10 (try `cargo update -p hyper`)
    ├ hyper v0.10.16
      ├── iron v0.6.1
      │   └── multipart v0.18.0
      │       └── (dev) libdd-common v1.1.0
      │           └── libdd-trace-utils v1.0.0
      │               └── (dev) libdd-trace-utils v1.0.0 (*)
      ├── multipart v0.18.0 (*)
      └── nickel v0.11.0
          └── multipart v0.18.0 (*)

error[vulnerability]: `idna` accepts Punycode labels that do not produce any non-ASCII when decoded
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:148:1
    │
148 │ idna 0.1.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2024-0421
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2024-0421
    ├ `idna` 0.5.0 and earlier accepts Punycode labels that do not produce any non-ASCII output, which means that either ASCII labels or the empty root label can be masked such that they appear unequal without IDNA processing or when processed with a different implementation and equal when processed with `idna` 0.5.0 or earlier.
      
      Concretely, `example.org` and `xn--example-.org` become equal after processing by `idna` 0.5.0 or earlier. Also, `example.org.xn--` and `example.org.` become equal after processing by `idna` 0.5.0 or earlier.
      
      In applications using `idna` (but not in `idna` itself) this may be able to lead to privilege escalation when host name comparison is part of a privilege check and the behavior is combined with a client that resolves domains with such labels instead of treating them as errors that preclude DNS resolution / URL fetching and with the attacker managing to introduce a DNS entry (and TLS certificate) for an `xn--`-masked name that turns into the name of the target when processed by `idna` 0.5.0 or earlier.
      
      ## Remedy
      
      Upgrade to `idna` 1.0.3 or later, if depending on `idna` directly, or to `url` 2.5.4 or later, if depending on `idna` via `url`. (This issue was fixed in `idna` 1.0.0, but versions earlier than 1.0.3 are not recommended for other reasons.)
      
      When upgrading, please take a moment to read about [alternative Unicode back ends for `idna`](https://docs.rs/crate/idna_adapter/latest).
      
      If you are using Rust earlier than 1.81 in combination with SQLx 0.8.2 or earlier, please also read an [issue](https://github.com/servo/rust-url/issues/992) about combining them with `url` 2.5.4 and `idna` 1.0.3.
      
      ## Additional information
      
      This issue resulted from `idna` 0.5.0 and earlier implementing the UTS 46 specification literally on this point and the specification having this bug. The specification bug has been fixed in [revision 33 of UTS 46](https://www.unicode.org/reports/tr46/tr46-33.html#Modifications).
      
      ## Acknowledgements
      
      Thanks to kageshiron for recognizing the security implications of this behavior.
    ├ Announcement: https://bugzilla.mozilla.org/show_bug.cgi?id=1887898
    ├ Solution: Upgrade to >=1.0.0 (try `cargo update -p idna`)
    ├ idna v0.1.5
      └── url v1.7.2
          ├── hyper v0.10.16
          │   ├── iron v0.6.1
          │   │   └── multipart v0.18.0
          │   │       └── (dev) libdd-common v1.1.0
          │   │           └── libdd-trace-utils v1.0.0
          │   │               └── (dev) libdd-trace-utils v1.0.0 (*)
          │   ├── multipart v0.18.0 (*)
          │   └── nickel v0.11.0
          │       └── multipart v0.18.0 (*)
          ├── iron v0.6.1 (*)
          ├── nickel v0.11.0 (*)
          └── tiny_http v0.6.4
              └── multipart v0.18.0 (*)

error[unmaintained]: multipart is Unmaintained
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:186:1
    │
186 │ multipart 0.18.0 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
    │
    ├ ID: RUSTSEC-2023-0050
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2023-0050
    ├ The `multipart` crate is unmaintained. The author has archived the github
      repository.
      
      Alternatives:
      
      - [multer](https://crates.io/crates/multer)
      - [multiparty](https://crates.io/crates/multiparty)
    ├ Solution: No safe upgrade is available!
    ├ multipart v0.18.0
      └── (dev) libdd-common v1.1.0
          └── libdd-trace-utils v1.0.0
              └── (dev) libdd-trace-utils v1.0.0 (*)

error[vulnerability]: Potential segfault in the time crate
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:301:1
    │
301 │ time 0.1.45 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2020-0071
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2020-0071
    ├ ### Impact
      
      The affected functions set environment variables without synchronization. On Unix-like operating systems, this can crash in multithreaded programs. Programs may segfault due to dereferencing a dangling pointer if an environment variable is read in a different thread than the affected functions. This may occur without the user's knowledge, notably in the Rust standard library or third-party libraries.
      
      The affected functions from time 0.2.7 through 0.2.22 are:
      
      - `time::UtcOffset::local_offset_at`
      - `time::UtcOffset::try_local_offset_at`
      - `time::UtcOffset::current_local_offset`
      - `time::UtcOffset::try_current_local_offset`
      - `time::OffsetDateTime::now_local`
      - `time::OffsetDateTime::try_now_local`
      
      The affected functions in time 0.1 (all versions) are:
      
      - `time::at_utc`
      - `time::at`
      - `time::now`
      - `time::tzset`
      
      Non-Unix targets (including Windows and wasm) are unaffected.
      
      ### Patches
      
      Pending a proper fix, the internal method that determines the local offset has been modified to always return `None` on the affected operating systems. This has the effect of returning an `Err` on the `try_*` methods and `UTC` on the non-`try_*` methods.
      
      Users and library authors with time in their dependency tree should perform `cargo update`, which will pull in the updated, unaffected code.
      
      Users of time 0.1 do not have a patch and should upgrade to an unaffected version: time 0.2.23 or greater or the 0.3 series.
      
      ### Workarounds
      
      A possible workaround for crates affected through the transitive dependency in `chrono`, is to avoid using the default `oldtime` feature dependency of the `chrono` crate by disabling its `default-features` and manually specifying the required features instead.
      
      #### Examples:
      
      `Cargo.toml`:  
      
      ```toml
      chrono = { version = "0.4", default-features = false, features = ["serde"] }
      ```
      
      ```toml
      chrono = { version = "0.4.22", default-features = false, features = ["clock"] }
      ```
      
      Commandline:  
      
      ```bash
      cargo add chrono --no-default-features -F clock
      ```
      
      Sources:  
       - [chronotope/chrono#602 (comment)](https://github.com/chronotope/chrono/issues/602#issuecomment-1242149249)  
       - [vityafx/serde-aux#21](https://github.com/vityafx/serde-aux/issues/21)
    ├ Announcement: https://github.com/time-rs/time/issues/293
    ├ Solution: Upgrade to >=0.2.23 (try `cargo update -p time`)
    ├ time v0.1.45
      ├── hyper v0.10.16
      │   ├── iron v0.6.1
      │   │   └── multipart v0.18.0
      │   │       └── (dev) libdd-common v1.1.0
      │   │           └── libdd-trace-utils v1.0.0
      │   │               └── (dev) libdd-trace-utils v1.0.0 (*)
      │   ├── multipart v0.18.0 (*)
      │   └── nickel v0.11.0
      │       └── multipart v0.18.0 (*)
      └── nickel v0.11.0 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-02-10 20:18:54 UTC | Commit: b6b7a7c | dependency-check job results

@bengl bengl force-pushed the bengl/change-buffer branch from 5d9d55b to 210da31 Compare January 29, 2026 19:50
@@ -0,0 +1,397 @@
use std::collections::HashMap;

use anyhow::{anyhow, bail, Result};
Copy link
Contributor

Choose a reason for hiding this comment

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

Personal opinion about anyhow. I think it's good for either prototyping things or using it in standalone binaries. On the other hand using it in libraries has its downsides, the main one being bubbling errors up to the caller, hence difficulting the SDKs consuming our libraries to do proper error handling. That said, I think that is not a problem right now and we can talk about it in subsequent PRs.

Copy link
Contributor

@ekump ekump Feb 3, 2026

Choose a reason for hiding this comment

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

non-blocking: +1. I don't think anyhow should be used in the public API for a library. But I'm ok with a TODO comment and taking care of it in the future.


impl From<u64> for OpCode {
fn from(val: u64) -> Self {
unsafe { std::mem::transmute(val) }
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe using a crate like num_enum or num_traits?

let slice = self.as_slice();
let bytes = slice.get(*index..*index + size)
.ok_or(anyhow!("read_u64 out of bounds: offset={}, len={}", *index, self.len))?;
let array: [u8; 8] = bytes.try_into()
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is generic over T. What happens if T isn't 8 bytes, like u32 or u128?

Do you need to convert bytes into array here? I don't think we lose any error fidelity because I don't think it's possible for try_into to fail here? We have the size, and slice.get() uses size to get exactly the correct bytes.

You could just pass bytes directly with: Ok(T::from_bytes(bytes)).

pub fn flush_change_buffer(&mut self) -> Result<()> {
let mut index = 0;
let mut count = self.change_buffer.read::<u64>(&mut index)?;
index += 8;
Copy link
Contributor

Choose a reason for hiding this comment

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

I might be misunderstanding, but doesn't the index get incremented in read? Won't this double increment the index?

Assuming I'm setting it up correctly this test would expose the double increment and the size issue in Read.

#[cfg(test)]
mod tests {
    use super::*;
    use libdd_tinybytes::BytesString;

    #[test]
    fn test_flush_change_buffer_single_create() {
        // Buffer: [count=1, opcode=Create(0), span_id, trace_id, parent_id]
        let mut buf = vec![];
        buf.extend_from_slice(&1u64.to_le_bytes()); // count = 1
        buf.extend_from_slice(&0u64.to_le_bytes()); // opcode = Create
        buf.extend_from_slice(&123u64.to_le_bytes()); // span_id
        buf.extend_from_slice(&456u128.to_le_bytes()); // trace_id
        buf.extend_from_slice(&0u64.to_le_bytes()); // parent_id

        let change_buffer =
            unsafe { ChangeBuffer::from_raw_parts(buf.as_ptr(), buf.len()) };
        let mut state = ChangeBufferState::<BytesString>::new(
            change_buffer,
            BytesString::from_static("service"),
            BytesString::from_static("rust"),
            1234.0,
        );

        state.flush_change_buffer().unwrap();

        let span = state.get_span(&123).unwrap();
        assert_eq!(span.span_id, 123);
        assert_eq!(span.trace_id, 456);
    }
}

Also, I just realized the change buffer has no unit tests.


pub mod span;

pub mod change_buffer;
Copy link
Contributor

Choose a reason for hiding this comment

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

non-blocking: Should we put the change_buffer behind an optional feature for now while it's still experimental?

@github-actions
Copy link

Clippy Allow Annotation Report

Comparing clippy allow annotations between branches:

  • Base Branch: origin/main
  • PR Branch: origin/bengl/change-buffer

Summary by Rule

Rule Base Branch PR Branch Change

Annotation Counts by File

File Base Branch PR Branch Change

Annotation Stats by Crate

Crate Base Branch PR Branch Change
clippy-annotation-reporter 5 0 ✅ -5 (-100.0%)
datadog-ffe-ffi 1 1 No change (0%)
datadog-ipc 27 27 No change (0%)
datadog-live-debugger 6 6 No change (0%)
datadog-live-debugger-ffi 10 10 No change (0%)
datadog-profiling-replayer 4 4 No change (0%)
datadog-remote-config 3 3 No change (0%)
datadog-sidecar 59 62 ⚠️ +3 (+5.1%)
libdd-common 10 10 No change (0%)
libdd-common-ffi 12 12 No change (0%)
libdd-crashtracker 12 12 No change (0%)
libdd-data-pipeline 6 7 ⚠️ +1 (+16.7%)
libdd-ddsketch 2 2 No change (0%)
libdd-dogstatsd-client 1 1 No change (0%)
libdd-profiling 13 13 No change (0%)
libdd-telemetry 19 19 No change (0%)
libdd-tinybytes 4 4 No change (0%)
libdd-trace-normalization 2 2 No change (0%)
libdd-trace-obfuscation 9 9 No change (0%)
libdd-trace-utils 15 17 ⚠️ +2 (+13.3%)
Total 220 221 ⚠️ +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.

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.

4 participants