| 288 | |
| 289 | template <TypeKind Kind> |
| 290 | void implForConstantPrimitiveKey( |
| 291 | const SelectivityVector& rows, |
| 292 | vector_size_t mapSize, |
| 293 | std::vector<VectorPtr>& args, |
| 294 | exec::DecodedArgs& decodedArgs, |
| 295 | VectorPtr& result) const { |
| 296 | using NativeType = typename TypeTraits<Kind>::NativeType; |
| 297 | auto mapResult = result->as<MapVector>(); |
| 298 | auto rawSizes = mapResult->mutableSizes(rows.end())->asMutable<int32_t>(); |
| 299 | auto rawOffsets = |
| 300 | mapResult->mutableOffsets(rows.end())->asMutable<int32_t>(); |
| 301 | |
| 302 | auto& keysResult = mapResult->mapKeys(); |
| 303 | auto& valuesResult = mapResult->mapValues(); |
| 304 | vector_size_t offset = keysResult->size(); |
| 305 | |
| 306 | folly::F14FastMap<NativeType, vector_size_t> keyToArgsIndex; |
| 307 | keyToArgsIndex.reserve(mapSize); |
| 308 | // 1. For constant keys, only one time-consuming duplication is required. |
| 309 | for (vector_size_t i = 0; i < mapSize; i++) { |
| 310 | auto key = |
| 311 | decodedArgs.at(i * 2)->base()->as<ConstantVector<NativeType>>(); |
| 312 | BOLT_USER_CHECK(!key->isNullAt(0), "Cannot use null as map key!"); |
| 313 | if constexpr (Policy == EXCEPTION) { |
| 314 | BOLT_USER_CHECK( |
| 315 | keyToArgsIndex.insert({key->valueAtFast(0), i}).second, |
| 316 | DuplicateKeyExceptionInfo); |
| 317 | } else if constexpr (Policy == FIRST_WIN) { |
| 318 | keyToArgsIndex.insert({key->valueAtFast(0), i}); |
| 319 | } else if constexpr (Policy == LAST_WIN) { |
| 320 | keyToArgsIndex.insert_or_assign(key->valueAtFast(0), i); |
| 321 | } else { |
| 322 | BOLT_UNREACHABLE(); |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | auto mapSizeAfterDedup = keyToArgsIndex.size(); |
| 327 | rows.applyToSelected([&](vector_size_t row) { |
| 328 | rawSizes[row] = mapSizeAfterDedup; |
| 329 | rawOffsets[row] = offset; |
| 330 | offset += mapSizeAfterDedup; |
| 331 | }); |
| 332 | |
| 333 | auto resultKeySize = offset; |
| 334 | keysResult->resize(resultKeySize); |
| 335 | valuesResult->resize(resultKeySize); |
| 336 | auto flatKeysResult = keysResult->as<FlatVector<NativeType>>(); |
| 337 | BOLT_CHECK_NOT_NULL(flatKeysResult); |
| 338 | auto rawKeysResult = flatKeysResult->mutableRawValues(); |
| 339 | |
| 340 | auto beginRow = rows.begin(); |
| 341 | SelectivityVector targetRows(resultKeySize, false); |
| 342 | vector_size_t targetIdx{0}; |
| 343 | std::vector<vector_size_t> toSourceRow(resultKeySize); |
| 344 | |
| 345 | // 2. Copy value and bool type keys to the result map column by column. |
| 346 | // For other types of keys, copy first line from the args to the result |
| 347 | // map, and then directly operate the `rawKeysResult` to memcpy the value of |
nothing calls this directly
no test coverage detected