Fix duplicate attribute keys in transform_attributes#2423
Fix duplicate attribute keys in transform_attributes#2423gyanranjanpanda wants to merge 1 commit intoopen-telemetry:mainfrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2423 +/- ##
==========================================
- Coverage 88.39% 88.37% -0.03%
==========================================
Files 603 603
Lines 213326 213567 +241
==========================================
+ Hits 188578 188745 +167
- Misses 24222 24296 +74
Partials 526 526
🚀 New features to boost your workflow:
|
a210873 to
361e6bd
Compare
|
@albertlockett and @ThomsonTan waiting for your feed backl |
albertlockett
left a comment
There was a problem hiding this comment.
Hey @gyanranjanpanda . I appreciate you taking the time to look at this, but I don't think we can accept this PR as is.
Unfortunately, the benchmarks we have for this code on main are currently broken. But when I apply the fix from #2426 and run the benchmark we see that this change introduces significant performance regression:
transform_attributes_dict_keys/single_replace_no_deletes/keys=32,rows=128,rows_per_key=4
time: [5.1300 µs 5.1348 µs 5.1394 µs]
change: [+1027.4% +1031.5% +1035.2%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_single_delete/keys=32,rows=128,rows_per_key=4
time: [5.5027 µs 5.5091 µs 5.5155 µs]
change: [+495.01% +497.37% +499.48%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/no_replace_single_delete/keys=32,rows=128,rows_per_key=4
time: [5.3440 µs 5.3584 µs 5.3746 µs]
change: [+577.41% +580.27% +583.40%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_no_deletes/keys=32,rows=1536,rows_per_key=48
time: [34.015 µs 34.050 µs 34.086 µs]
change: [+4000.2% +4016.4% +4031.3%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_single_delete/keys=32,rows=1536,rows_per_key=48
time: [34.390 µs 34.472 µs 34.562 µs]
change: [+1421.9% +1433.5% +1443.9%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/no_replace_single_delete/keys=32,rows=1536,rows_per_key=48
time: [34.302 µs 34.340 µs 34.379 µs]
change: [+1562.1% +1568.0% +1573.6%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_no_deletes/keys=32,rows=8192,rows_per_key=256
time: [171.62 µs 171.78 µs 171.96 µs]
change: [+6262.2% +6290.6% +6316.2%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_single_delete/keys=32,rows=8192,rows_per_key=256
time: [171.79 µs 171.92 µs 172.06 µs]
change: [+1771.2% +1835.7% +1893.0%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/no_replace_single_delete/keys=32,rows=8192,rows_per_key=256
time: [171.20 µs 171.35 µs 171.49 µs]
change: [+1962.8% +1981.5% +1998.1%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_no_deletes/keys=128,rows=128,rows_per_key=1
time: [4.9566 µs 4.9693 µs 4.9819 µs]
change: [+587.52% +592.02% +597.47%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/single_replace_single_delete/keys=128,rows=128,rows_per_key=1
time: [5.6185 µs 5.6284 µs 5.6377 µs]
change: [+292.54% +294.19% +296.01%] (p = 0.00 < 0.05)
Performance has regressed.
transform_attributes_dict_keys/no_replace_single_delete/keys=128,rows=128,rows_per_key=1
time: [5.2733 µs 5.2831 µs 5.2938 µs]
change: [+385.50% +387.73% +389.92%] (p = 0.00 < 0.05)
Performance has regressed.
While I expect to see some performance regression because we're doing extra work, I feel that such a serious regression in performance warrants some additional investigation into if/how we can do this in a more efficient way.
Please see my comment here which prescribes an approach that I believe will be more performant than what is currently in this PR: #1650 (comment)
361e6bd to
06392eb
Compare
|
thanks for your wonderful guidance i will make sure i could match your expectation |
|
Hey @gyanranjanpanda I wanted to give you a heads up that I am going to be working on #2014 and there may be some significant changes to the transform_attributes code. I will be touching code in transform_keys as well as transform_attributes_impl. I wanted to give you a heads up in case you want to hold off advancing your work until you can better understand the conflicts |
|
Thanks for the heads up! I’ll keep an eye on your changes to #2014 and try to align my work accordingly. If possible, could you share which parts might be most affected so I can avoid overlap? or should i wait after u finished your work i should continue this work |
It's probably easiest to hold off until I finish to avoid conflicts, but I'll leave it up to you. I think I should have the changes I need to make for #2014 done by early next week, if not sooner. For now, I'll show you the in-progress changes: I was imagining that for #1650 you'd need to make changes to |
|
@gyanranjanpanda the changes I mentioned that could cause conflicts have now been merged (see #2442) |
|
i will fix this code as soon as possible while looking your merged pr |
c9e8263 to
e2862b4
Compare
…metry#1650) When renaming attribute key 'x' to 'y', any existing row with key 'y' sharing a parent_id with a row having key 'x' would produce a duplicate. This commit fixes that by: - Adding find_rename_collisions_to_delete_ranges() which uses IdBitmap to efficiently detect these collisions in O(N) time - Generating KeyTransformRange::Delete entries that are merged into the existing transform pipeline in transform_keys() and transform_dictionary_keys() - Fixing an early-return in transform_dictionary_keys() that skipped row-level collision deletes when dictionary values had no deletions - Adding read_parent_ids_as_u32() helper for parent_id column access - Adding test_rename_removes_duplicate_keys integration test Only runs collision detection when parent_ids are plain-encoded (not transport-optimized) to avoid incorrect results from quasi-delta encoded values. Closes open-telemetry#1650
e2862b4 to
2d813af
Compare
Fix Duplicate Attribute Keys in
transform_attributesChanges Made
This PR resolves issue #1650 by ensuring that dictionary keys are deduplicated when transformations such as
renameare applied, as required by the OpenTelemetry specification ("Exported maps MUST contain only unique keys by default").To accomplish this while maintaining strict performance requirements, we replaced the previous
RowConverterdeduplication strategy with a new high-performance, proactive pre-filter:filter_rename_collisionsintotransform_attributes_implinsideotap-dataflow/crates/pdata/src/otap/transform.rs.parent_ids and target keys. It uses theIdBitmaptype to find any existing target keys whoseparent_idmaps back to an old key that will be renamed.arrow::compute::filter_record_batchbefore the actual transform happens.Testing
AttributesProcessorunit tests (test_rename_removes_duplicate_keys) to explicitly verify that renaming an attribute resulting in a collision automatically discards duplicate keys.AttributesTransformPipelineStageinquery-enginetests with a parallel case ensuring OPL/KQL query pipelines (project-rename) properly drop duplicates when resolving duplicates.otap_df_pdatatransform.rstests to properly expect deduplicated keys using this plan-based method.cargo test --workspace --all-features.Validation Results
All tests pass. OTel semantic rules surrounding unique mapped keys map cleanly through down/upstream processors. The
IdBitmapintersection approach completely resolves the multi-thousand percentRowConverterperformance regressions, dropping collision resolution overhead to essentially zero through efficient bitmap operations.