| 249 | |
| 250 | template <typename T, bool mayHaveNulls> |
| 251 | bool VectorHasher::makeValueIdsDecoded( |
| 252 | const SelectivityVector& rows, |
| 253 | uint64_t* result) { |
| 254 | auto indices = decoded_.indices(); |
| 255 | auto values = decoded_.data<T>(); |
| 256 | bool success = true; |
| 257 | |
| 258 | if (rows.countSelected() <= decoded_.base()->size()) { |
| 259 | // Cache is not beneficial in this case and we don't use them. |
| 260 | auto* nulls = decoded_.nulls(&rows); |
| 261 | rows.applyToSelected([&](vector_size_t row) INLINE_LAMBDA { |
| 262 | makeValueIdForOneRow<T, mayHaveNulls>( |
| 263 | nulls, row, values, indices[row], result, success); |
| 264 | }); |
| 265 | return success; |
| 266 | } |
| 267 | |
| 268 | cachedHashes_.resize(decoded_.base()->size()); |
| 269 | std::fill(cachedHashes_.begin(), cachedHashes_.end(), 0); |
| 270 | |
| 271 | int numCachedHashes = 0; |
| 272 | rows.testSelected([&](vector_size_t row) INLINE_LAMBDA { |
| 273 | if constexpr (mayHaveNulls) { |
| 274 | if (decoded_.isNullAt(row)) { |
| 275 | if (multiplier_ == 1) { |
| 276 | result[row] = 0; |
| 277 | } |
| 278 | return true; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | auto baseIndex = indices[row]; |
| 283 | uint64_t& id = cachedHashes_[baseIndex]; |
| 284 | |
| 285 | if (success) { |
| 286 | if (id == 0) { |
| 287 | T value = values[baseIndex]; |
| 288 | id = valueId(value); |
| 289 | numCachedHashes++; |
| 290 | if (id == kUnmappable) { |
| 291 | analyzeValue(value); |
| 292 | success = false; |
| 293 | } |
| 294 | } |
| 295 | result[row] = multiplier_ == 1 ? id : result[row] + multiplier_ * id; |
| 296 | } else { |
| 297 | if (id == 0) { |
| 298 | id = kUnmappable; |
| 299 | numCachedHashes++; |
| 300 | analyzeValue(values[baseIndex]); |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | return success || numCachedHashes < cachedHashes_.size(); |
| 305 | }); |
| 306 | |
| 307 | return success; |
| 308 | } |
nothing calls this directly
no test coverage detected