Specialized value extractor for ColumnString, with optional Nullable support. Two-pass approach: first pass computes offsets, total chars size, and fills null map; second pass re-iterates matched_positions to copy string data.
| 276 | /// Two-pass approach: first pass computes offsets, total chars size, and fills null map; |
| 277 | /// second pass re-iterates matched_positions to copy string data. |
| 278 | void extractValuesString( |
| 279 | const ColumnString & values_column, |
| 280 | ColumnString & result, |
| 281 | const PaddedPODArray<size_t> & matched_positions, |
| 282 | const NullMap * src_null_map = nullptr, |
| 283 | NullMap * dst_null_map = nullptr) |
| 284 | { |
| 285 | const auto & src_chars = values_column.getChars(); |
| 286 | const auto & src_offsets = values_column.getOffsets(); |
| 287 | auto & dst_chars = result.getChars(); |
| 288 | auto & dst_offsets = result.getOffsets(); |
| 289 | |
| 290 | size_t old_offsets_size = dst_offsets.size(); |
| 291 | size_t num_rows = matched_positions.size(); |
| 292 | |
| 293 | dst_offsets.resize(old_offsets_size + num_rows); |
| 294 | if (dst_null_map) |
| 295 | dst_null_map->resize(dst_null_map->size() + num_rows); |
| 296 | |
| 297 | /// First pass: compute result offsets, total chars size, and fill null map. |
| 298 | /// total_chars_size must start from the existing chars size because |
| 299 | /// ColumnString offsets are absolute positions into the chars array. |
| 300 | size_t old_chars_size = dst_chars.size(); |
| 301 | size_t total_chars_size = old_chars_size; |
| 302 | for (size_t i = 0; i < num_rows; ++i) |
| 303 | { |
| 304 | size_t pos = matched_positions[i]; |
| 305 | if (pos != KEY_NOT_FOUND) |
| 306 | { |
| 307 | total_chars_size += src_offsets[pos] - src_offsets[ssize_t(pos) - 1]; |
| 308 | if (dst_null_map) |
| 309 | (*dst_null_map)[old_offsets_size + i] = (*src_null_map)[pos]; |
| 310 | } |
| 311 | else |
| 312 | { |
| 313 | if (dst_null_map) |
| 314 | (*dst_null_map)[old_offsets_size + i] = static_cast<UInt8>(1); |
| 315 | } |
| 316 | dst_offsets[old_offsets_size + i] = total_chars_size; |
| 317 | } |
| 318 | |
| 319 | /// Second pass: resize chars once and copy string data. |
| 320 | dst_chars.resize(total_chars_size); |
| 321 | size_t current_offset = old_chars_size; |
| 322 | for (size_t i = 0; i < num_rows; ++i) |
| 323 | { |
| 324 | size_t pos = matched_positions[i]; |
| 325 | if (pos != KEY_NOT_FOUND) |
| 326 | { |
| 327 | size_t src_offset = src_offsets[ssize_t(pos) - 1]; |
| 328 | size_t src_size = src_offsets[pos] - src_offset; |
| 329 | memcpy(&dst_chars[current_offset], &src_chars[src_offset], src_size); |
| 330 | current_offset += src_size; |
| 331 | } |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /// Specialized value extractor for ColumnFixedString, with optional Nullable support. |
no test coverage detected