use super::*;
pub(super) fn compute_visibility_bitmaps(
seg_order: &[u64],
segments: &mut rustc_hash::FxHashMap<u64, ColdSegment>,
reusable_seen: &mut rustc_hash::FxHashSet<i64>,
) {
if segments.len() <= 1 {
for cs in segments.values_mut() {
cs.visible = None;
}
return;
}
reusable_seen.clear();
let total: usize = segments.values().map(|cs| cs.volume.meta.row_count).sum();
if reusable_seen.capacity() < total {
reusable_seen.reserve(total * 8 / 7 + 16 - reusable_seen.capacity());
}
for &seg_id in seg_order.iter().rev() {
if let Some(cs) = segments.get_mut(&seg_id) {
let rc = cs.volume.meta.row_count;
if rc == 0 {
cs.visible = None;
continue;
}
let num_words = rc.div_ceil(64);
let mut bits = vec![!0u64; num_words];
let trailing = rc % 64;
if trailing != 0 {
bits[num_words - 1] &= (1u64 << trailing) - 1;
}
let mut has_overlap = false;
for i in 0..rc {
if !reusable_seen.insert(cs.volume.meta.row_ids.at(i)) {
bits[i >> 6] &= !(1u64 << (i & 63));
has_overlap = true;
}
}
cs.visible = if has_overlap {
Some(Arc::new(bits))
} else {
None
};
}
}
if reusable_seen.capacity() > total * 2 + 1024 {
*reusable_seen = rustc_hash::FxHashSet::with_capacity_and_hasher(total, Default::default());
} else {
reusable_seen.clear();
}
}
pub(super) fn selected_ranges_are_isolated(
selected_segment_ids: &FxHashSet<u64>,
segments: &rustc_hash::FxHashMap<u64, ColdSegment>,
require_internal_disjointness: bool,
) -> bool {
let mut selected_ranges = Vec::with_capacity(selected_segment_ids.len());
for segment_id in selected_segment_ids {
let Some(segment) = segments.get(segment_id) else {
return false;
};
if segment.volume.meta.row_count == 0 {
continue;
}
let Some((minimum, maximum)) = segment
.volume
.meta
.row_ids
.first()
.zip(segment.volume.meta.row_ids.last())
else {
return false;
};
selected_ranges.push((minimum, maximum));
}
selected_ranges.sort_unstable_by_key(|(minimum, maximum)| (*minimum, *maximum));
if require_internal_disjointness
&& selected_ranges
.windows(2)
.any(|ranges| ranges[0].1 >= ranges[1].0)
{
return false;
}
for (segment_id, segment) in segments {
if selected_segment_ids.contains(segment_id) || segment.volume.meta.row_count == 0 {
continue;
}
let Some((minimum, maximum)) = segment
.volume
.meta
.row_ids
.first()
.zip(segment.volume.meta.row_ids.last())
else {
return false;
};
if selected_ranges
.iter()
.any(|(selected_minimum, selected_maximum)| {
*selected_minimum <= maximum && minimum <= *selected_maximum
})
{
return false;
}
}
true
}