MCPcopy Create free account
hub / github.com/apache/datafusion / group_by_partition_values

Method group_by_partition_values

datafusion/datasource/src/file_groups.rs:492–543  ·  view source on GitHub ↗

ScalarValue has interior mutability but is intentionally used as hash key

(
        self,
        max_target_partitions: usize,
    )

Source from the content-addressed store, hash-verified

490 /// number of unique partition values is less than the target.
491 #[allow(clippy::allow_attributes, clippy::mutable_key_type)] // ScalarValue has interior mutability but is intentionally used as hash key
492 pub fn group_by_partition_values(
493 self,
494 max_target_partitions: usize,
495 ) -> Vec<FileGroup> {
496 if self.is_empty() || max_target_partitions == 0 {
497 return vec![];
498 }
499
500 let mut partition_groups: HashMap<
501 Vec<datafusion_common::ScalarValue>,
502 Vec<PartitionedFile>,
503 > = HashMap::new();
504
505 for file in self.files {
506 partition_groups
507 .entry(file.partition_values.clone())
508 .or_default()
509 .push(file);
510 }
511
512 let num_unique_partitions = partition_groups.len();
513
514 // Sort for deterministic bucket assignment across query executions.
515 let mut sorted_partitions: Vec<_> = partition_groups.into_iter().collect();
516 let sort_options =
517 vec![
518 SortOptions::default();
519 sorted_partitions.first().map(|(k, _)| k.len()).unwrap_or(0)
520 ];
521 sorted_partitions.sort_by(|a, b| {
522 compare_rows(&a.0, &b.0, &sort_options).unwrap_or(Ordering::Equal)
523 });
524
525 if num_unique_partitions <= max_target_partitions {
526 sorted_partitions
527 .into_iter()
528 .map(|(_, files)| FileGroup::new(files))
529 .collect()
530 } else {
531 // Merge into max_target_partitions buckets using round-robin.
532 // This maintains grouping by partition value as we are merging groups which already
533 // contain all values for a partition key.
534 let mut target_groups = vec![vec![]; max_target_partitions];
535
536 for (idx, (_, files)) in sorted_partitions.into_iter().enumerate() {
537 let bucket = idx % max_target_partitions;
538 target_groups[bucket].extend(files);
539 }
540
541 target_groups.into_iter().map(FileGroup::new).collect()
542 }
543 }
544}
545
546impl Index<usize> for FileGroup {

Calls 11

newFunction · 0.85
compare_rowsFunction · 0.85
collectMethod · 0.80
is_emptyMethod · 0.45
pushMethod · 0.45
cloneMethod · 0.45
lenMethod · 0.45
into_iterMethod · 0.45
sort_byMethod · 0.45
mapMethod · 0.45
extendMethod · 0.45