Module mmtk::util::rust_util::rev_group

source ·
Expand description

This module provides an iterator that groups adjacent items with the same key.

It gives all Iterator + Clone iterators a new method: .revisitable_group_by. It is similar to Itertools::group_by, but it lets the user know the length of each group before iterating through the group. Implementation-wise, it eagerly finds all items with the same key, and then lets the user traverse the same range of items again using a pre-cloned iterator. This is why it is named “revisitable” group-by.

This is useful for the memory mapper to coalesce the mmap call for adjacent chunks that have the same MapState. The memory mapper needs to know the size of each group to compute the memory range the group of MapState covers in order to call mmap, and then traverse the group of MapState again to update them.

The .revisitable_group_by method takes a closure for computing the keys of each item. Adjacent items with the same key will be put into the same group.

The following example groups adjacent even or odd numbers together.

let nums = [1, 3, 5, 2, 4, 6, 7, 9];
for group in nums.iter().revisitable_group_by(|x| *x % 2) {
    println!("key: {}, len: {}", group.key, group.len);
    for x in group {
        println!("  x: {}", *x);
    }
}

It should form three groups, [1, 3, 5], [2, 4, 6] and [7, 9], with the keys being 1, 0 and 1, respectively.

It can be used with the .flatten() method to make groups across the boundaries of several iterable items.

let slice_of_slices: &[&[i32]] = &[&[10, 20], &[30, 40, 11, 21], &[31, 12, 22]];
let result = slice_of_slices.iter().copied().flatten().copied()
    .revisitable_group_by(|x| x % 10)
    .map(|group| group.collect::<Vec<_>>())
    .collect::<Vec<_>>();
assert_eq!(
    result,
    vec![vec![10, 20, 30, 40], vec![11, 21, 31], vec![12, 22]],
);

Structs§

Traits§