use crate::{node::child_bit, prefix::mask_from_prefix_len, Prefix};
use super::TrieView;
pub(super) fn is_empty_recursive<'a, V: TrieView<'a>>(mut view: V) -> bool {
if view.data_bitmap() != 0 {
return false;
}
let mut bits = view.child_bitmap();
while bits != 0 {
let bit = bits.trailing_zeros();
bits &= bits - 1;
if !is_empty_recursive(unsafe { view.get_child(bit) }) {
return false;
}
}
true
}
enum DescendResult<V> {
Child(V),
Empty,
NonEmpty,
}
fn descend_checking_empty<'a, V: TrieView<'a>>(
mut view: V,
target_key: <V::P as Prefix>::R,
) -> DescendResult<V> {
if view.data_bitmap() != 0 {
return DescendResult::NonEmpty;
}
let toward = child_bit(view.depth(), target_key);
let mut other_bits = view.child_bitmap() & !(1 << toward);
while other_bits != 0 {
let bit = other_bits.trailing_zeros();
other_bits &= other_bits - 1;
if !is_empty_recursive(unsafe { view.get_child(bit) }) {
return DescendResult::NonEmpty;
}
}
if (view.child_bitmap() >> toward) & 1 == 0 {
return DescendResult::Empty;
}
DescendResult::Child(unsafe { view.get_child(toward) })
}
fn eq_keys_children<'a, L, R>(mut left: L, mut right: R) -> bool
where
L: TrieView<'a>,
R: TrieView<'a, P = L::P>,
{
let l_children = left.child_bitmap();
let r_children = right.child_bitmap();
let mut left_only = l_children & !r_children;
while left_only != 0 {
let bit = left_only.trailing_zeros();
left_only &= left_only - 1;
if !is_empty_recursive(unsafe { left.get_child(bit) }) {
return false;
}
}
let mut right_only = r_children & !l_children;
while right_only != 0 {
let bit = right_only.trailing_zeros();
right_only &= right_only - 1;
if !is_empty_recursive(unsafe { right.get_child(bit) }) {
return false;
}
}
let mut common = l_children & r_children;
while common != 0 {
let bit = common.trailing_zeros();
common &= common - 1;
if !eq_keys_recursive(unsafe { left.get_child(bit) }, unsafe {
right.get_child(bit)
}) {
return false;
}
}
true
}
pub(super) fn eq_keys_recursive<'a, L, R>(mut left: L, mut right: R) -> bool
where
L: TrieView<'a>,
R: TrieView<'a, P = L::P>,
{
while left.depth() != right.depth() {
if left.depth() < right.depth() {
match descend_checking_empty(left, right.key()) {
DescendResult::Child(child) => left = child,
DescendResult::Empty => return is_empty_recursive(right),
DescendResult::NonEmpty => return false,
}
} else {
match descend_checking_empty(right, left.key()) {
DescendResult::Child(child) => right = child,
DescendResult::Empty => return is_empty_recursive(left),
DescendResult::NonEmpty => return false,
}
}
}
let min_prefix_len = left.prefix_len().min(right.prefix_len());
let mask = mask_from_prefix_len(min_prefix_len as u8);
if left.key() & mask != right.key() & mask {
return is_empty_recursive(left) && is_empty_recursive(right);
}
if left.data_bitmap() != right.data_bitmap() {
return false;
}
eq_keys_children(left, right)
}
#[cfg(test)]
mod tests {
use crate::{
trieview::{AsView, TrieView},
Prefix, PrefixMap, PrefixSet,
};
type P = (u32, u8);
fn p(repr: u32, len: u8) -> P {
P::from_repr_len(repr, len)
}
fn map_from(entries: &[(u32, u8, i32)]) -> PrefixMap<P, i32> {
let mut m = PrefixMap::new();
for &(repr, len, val) in entries {
m.insert(p(repr, len), val);
}
m
}
#[test]
fn eq_keys_same_maps() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
assert!(a.view().eq_keys(&b));
}
#[test]
fn eq_keys_same_keys_different_values() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 99), (0x0a010000, 16, 99)]);
assert!(a.view().eq_keys(&b));
}
#[test]
fn eq_keys_different_keys() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1), (0x0b000000, 8, 2)]);
assert!(!a.view().eq_keys(&b));
}
#[test]
fn eq_keys_subset() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1)]);
assert!(!a.view().eq_keys(&b));
assert!(!b.view().eq_keys(&a));
}
#[test]
fn eq_keys_both_empty() {
let a: PrefixMap<P, i32> = PrefixMap::new();
let b: PrefixMap<P, i32> = PrefixMap::new();
assert!(a.view().eq_keys(&b));
}
#[test]
fn eq_keys_one_empty() {
let a = map_from(&[(0x0a000000, 8, 1)]);
let b: PrefixMap<P, i32> = PrefixMap::new();
assert!(!a.view().eq_keys(&b));
}
#[test]
fn eq_keys_map_vs_set() {
let map = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let set: PrefixSet<P> = [p(0x0a000000, 8), p(0x0a010000, 16)].into_iter().collect();
assert!(map.view().eq_keys(&set));
}
#[test]
fn eq_keys_subview_matches_full_map() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2), (0x0b000000, 8, 3)]);
let b = map_from(&[(0x0a000000, 8, 9), (0x0a010000, 16, 9)]);
let a_sub = a.view_at(&p(0x0a000000, 8)).unwrap();
assert!(a_sub.eq_keys(&b));
}
#[test]
fn eq_keys_subviews_different_positions() {
let a = map_from(&[(0x96000000, 7, 0)]);
let b = map_from(&[(0xb6000000, 7, 0)]);
let a_sub = a.view_at(&p(0x90000000, 5)).unwrap();
let b_sub = b.view_at(&p(0xb0000000, 5)).unwrap();
assert!(!a_sub.eq_keys(b_sub));
}
#[test]
fn eq_keys_root_vs_subview_broader_has_extra() {
let a = map_from(&[(0x00000000, 0, 0), (0x00000000, 9, 0)]);
let b = map_from(&[(0x00000000, 9, 0)]);
let b_sub = b.view_at(&p(0x00000000, 1)).unwrap();
assert!(!a.view().eq_keys(b_sub));
}
#[test]
fn eq_keys_empty_difference_vs_empty_map() {
let a = map_from(&[(0xf0000000, 5, 0)]);
let b = map_from(&[(0xf0000000, 5, 0)]);
let c: PrefixMap<P, i32> = PrefixMap::new();
assert!(a.view().difference(&b).eq_keys(&c));
}
#[test]
fn eq_keys_difference_removes_subset() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2), (0x0b000000, 8, 3)]);
let b = map_from(&[(0x0b000000, 8, 10)]);
let c = map_from(&[(0x0a000000, 8, 99), (0x0a010000, 16, 99)]);
assert!(a.view().difference(&b).eq_keys(&c));
}
#[test]
fn eq_keys_difference_with_subviews() {
let a = map_from(&[(0xf0000000, 5, 0)]);
let b = map_from(&[(0xf0000000, 5, 0)]);
let c: PrefixMap<P, i32> = PrefixMap::new();
let a_sub = a.view_at(&p(0x00000000, 0)).unwrap();
let b_sub = b.view_at(&p(0x00000000, 0)).unwrap();
assert!(a_sub.difference(b_sub).eq_keys(&c));
}
#[test]
fn eq_keys_shallower_has_nonempty_sibling() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0b000000, 8, 2)]);
let b = map_from(&[(0x0a000000, 8, 1)]);
let b_sub = b.view_at(&p(0x0a000000, 8)).unwrap();
assert!(!a.view().eq_keys(b_sub));
}
#[test]
fn eq_keys_shallower_no_child_toward_deeper_both_empty() {
let a: PrefixMap<P, i32> = PrefixMap::new();
let b = map_from(&[(0x0a000000, 8, 1)]);
let b_sub = b.view_at(&p(0x0a000000, 8)).unwrap();
assert!(!a.view().eq_keys(b_sub));
}
#[test]
fn eq_by_equal_values() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
assert!(a.view().eq_by(&b, |a, b| a == b));
}
#[test]
fn eq_by_different_values() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 9)]);
assert!(!a.view().eq_by(&b, |a, b| a == b));
}
#[test]
fn eq_by_different_keys() {
let a = map_from(&[(0x0a000000, 8, 1)]);
let b = map_from(&[(0x0b000000, 8, 1)]);
assert!(!a.view().eq_by(&b, |a, b| a == b));
}
#[test]
fn eq_by_different_lengths() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
let b = map_from(&[(0x0a000000, 8, 1)]);
assert!(!a.view().eq_by(&b, |a, b| a == b));
}
#[test]
fn eq_by_custom_comparator() {
let a = map_from(&[(0x0a000000, 8, 10), (0x0a010000, 16, 20)]);
let b = map_from(&[(0x0a000000, 8, 11), (0x0a010000, 16, 21)]);
assert!(a.view().eq_by(&b, |a, b| (b - a) == 1));
}
#[test]
fn eq_by_composed_view() {
let a = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2), (0x0b000000, 8, 3)]);
let b = map_from(&[(0x0b000000, 8, 10)]);
let c = map_from(&[(0x0a000000, 8, 1), (0x0a010000, 16, 2)]);
assert!(a.view().difference(&b).eq_by(&c, |a, b| a == b));
}
}