mrhhsg commented on code in PR #68651:
URL: https://github.com/apache/doris/pull/68651#discussion_r4141255317


##########
be/src/exec/operator/aggregation_sink_operator.cpp:
##########
@@ -579,6 +623,83 @@ void 
AggSinkLocalState::_emplace_into_hash_table(AggregateDataPtr* places,
                _agg_data->method_variant);
 }
 
+// For the agg hashmap<key, value>, the value is a char* type which is exactly 
64 bits.
+// Here we treat it as a uint64 counter: each time the same key is 
encountered, the counter
+// is incremented by 1. This avoids storing the full aggregate state, saving 
memory and computation overhead.
+void AggSinkLocalState::_emplace_into_hash_table_inline_count(ColumnRawPtrs& 
key_columns,
+                                                              uint32_t 
num_rows) {
+    std::visit(Overload {[&](std::monostate& arg) -> void {
+                             throw doris::Exception(ErrorCode::INTERNAL_ERROR,
+                                                    "uninited hash table");
+                         },
+                         [&](auto& agg_method) -> void {
+                             SCOPED_TIMER(_hash_table_compute_timer);
+                             using HashMethodType = 
std::decay_t<decltype(agg_method)>;
+                             using AggState = typename HashMethodType::State;
+                             AggState state(key_columns);
+                             agg_method.init_serialized_keys(key_columns, 
num_rows);
+
+                             auto creator = [&](const auto& ctor, auto& key, 
auto& origin) {
+                                 HashMethodType::try_presis_key_and_origin(
+                                         key, origin, 
Base::_shared_state->agg_arena_pool);
+                                 AggregateDataPtr mapped = nullptr;
+                                 ctor(key, mapped);
+                             };
+
+                             auto creator_for_null_key = [&](auto& mapped) { 
mapped = nullptr; };
+
+                             SCOPED_TIMER(_hash_table_emplace_timer);
+                             lazy_emplace_batch(agg_method, state, num_rows, 
creator,
+                                                creator_for_null_key, 
[&](uint32_t, auto& mapped) {
+                                                    
++reinterpret_cast<UInt64&>(mapped);

Review Comment:
   Fixed in e86c5594e2d. All inline COUNT accesses now go through 
`inline_count_get` / `inline_count_add` (new `exec/operator/inline_count.h`), 
which convert the pointer *value* to and from `uintptr_t` and assign the slot 
back as a pointer, instead of forming a `UInt64&` over the `AggregateDataPtr` 
object: the regular sink update and merge, the regular source output (both 
paths), the streaming update and output, the bucketed sink update, and the 
bucketed source merge and output. Value conversions are well defined under 
`-fstrict-aliasing`, and since the slot is written back through its own type 
the optimizer cannot keep a stale pointer across the update. No behaviour 
change; covered by the existing grouped COUNT(*) cases (`bucketed_hash_agg` 
Test 8 and the agg_strategy / query suites) and the BE aggregation UTs (343 
passed).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to