(&self, logical_indices: &[I])
| 319 | /// If any logical index is out of bounds (>= self.len()), returns an error containing the invalid index. |
| 320 | #[inline] |
| 321 | pub fn get_physical_indices<I>(&self, logical_indices: &[I]) -> Result<Vec<usize>, I> |
| 322 | where |
| 323 | I: ArrowNativeType, |
| 324 | { |
| 325 | let len = self.len(); |
| 326 | let offset = self.offset(); |
| 327 | |
| 328 | let indices_len = logical_indices.len(); |
| 329 | |
| 330 | if indices_len == 0 { |
| 331 | return Ok(vec![]); |
| 332 | } |
| 333 | |
| 334 | // `ordered_indices` store index into `logical_indices` and can be used |
| 335 | // to iterate `logical_indices` in sorted order. |
| 336 | let mut ordered_indices: Vec<usize> = (0..indices_len).collect(); |
| 337 | |
| 338 | // Instead of sorting `logical_indices` directly, sort the `ordered_indices` |
| 339 | // whose values are index of `logical_indices` |
| 340 | ordered_indices.sort_unstable_by(|lhs, rhs| { |
| 341 | logical_indices[*lhs] |
| 342 | .partial_cmp(&logical_indices[*rhs]) |
| 343 | .unwrap() |
| 344 | }); |
| 345 | |
| 346 | // Return early if all the logical indices cannot be converted to physical indices. |
| 347 | let largest_logical_index = logical_indices[*ordered_indices.last().unwrap()].as_usize(); |
| 348 | if largest_logical_index >= len { |
| 349 | return Err(logical_indices[*ordered_indices.last().unwrap()]); |
| 350 | } |
| 351 | |
| 352 | // Skip some physical indices based on offset. |
| 353 | let skip_value = self.get_start_physical_index(); |
| 354 | |
| 355 | let mut physical_indices = vec![0; indices_len]; |
| 356 | |
| 357 | let mut ordered_index = 0_usize; |
| 358 | for (physical_index, run_end) in self.values().iter().enumerate().skip(skip_value) { |
| 359 | // Get the run end index (relative to offset) of current physical index |
| 360 | let run_end_value = run_end.as_usize() - offset; |
| 361 | |
| 362 | // All the `logical_indices` that are less than current run end index |
| 363 | // belongs to current physical index. |
| 364 | while ordered_index < indices_len |
| 365 | && logical_indices[ordered_indices[ordered_index]].as_usize() < run_end_value |
| 366 | { |
| 367 | physical_indices[ordered_indices[ordered_index]] = physical_index; |
| 368 | ordered_index += 1; |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | // If there are input values >= run_ends.last_value then we'll not be able to convert |
| 373 | // all logical indices to physical indices. |
| 374 | if ordered_index < logical_indices.len() { |
| 375 | return Err(logical_indices[ordered_indices[ordered_index]]); |
| 376 | } |
| 377 | Ok(physical_indices) |
| 378 | } |
no test coverage detected