moc/moc/range/op/
degrade.rs

1use std::ops::Range;
2
3use crate::idx::Idx;
4use crate::moc::{HasMaxDepth, MOCProperties, NonOverlapping, RangeMOCIterator, ZSorted};
5use crate::qty::MocQty;
6
7/// Performs a `degradation` on the input iterator of ranges.
8pub fn degrade<T, Q, I>(it: I, new_depth: u8) -> DegradeRangeIter<T, Q, I>
9where
10  T: Idx,
11  Q: MocQty<T>,
12  I: RangeMOCIterator<T, Qty = Q>,
13{
14  DegradeRangeIter::new(it, new_depth)
15}
16
17/// Performs a `degradation` on the input iterator of ranges.
18pub struct DegradeRangeIter<T, Q, I>
19where
20  T: Idx,
21  Q: MocQty<T>,
22  I: RangeMOCIterator<T, Qty = Q>,
23{
24  new_depth: u8,
25  //one_at_new_depth: T,
26  rm_bits_mask: T,
27  bits_to_be_rm_mask: T,
28  it: I,
29  curr: Option<Range<T>>,
30}
31
32impl<T, Q, I> DegradeRangeIter<T, Q, I>
33where
34  T: Idx,
35  Q: MocQty<T>,
36  I: RangeMOCIterator<T, Qty = Q>,
37{
38  pub fn new(mut it: I, new_depth: u8) -> DegradeRangeIter<T, Q, I> {
39    if new_depth < it.depth_max() {
40      let shift = Q::shift_from_depth_max(new_depth) as u32;
41      // let one_at_new_depth = T::one().unsigned_shl(shift);
42      let rm_bits_mask = (!T::zero()).unsigned_shl(shift);
43      let bits_to_be_rm_mask = !rm_bits_mask; // If (end & test_end_mask) == 0, do nothing, else + one
44      let mut curr = it.next();
45      if let Some(cr) = &mut curr {
46        degrade_range(
47          cr,
48          /*one_at_new_depth,*/ rm_bits_mask,
49          bits_to_be_rm_mask,
50        )
51      }
52      DegradeRangeIter {
53        new_depth,
54        //one_at_new_depth,
55        rm_bits_mask,
56        bits_to_be_rm_mask,
57        it,
58        curr,
59      }
60    } else {
61      // Do nothing, just change the depth.
62      let new_depth = it.depth_max();
63      let curr = it.next();
64      DegradeRangeIter {
65        new_depth,
66        //one_at_new_depth: T::one(),
67        rm_bits_mask: !T::zero(),
68        bits_to_be_rm_mask: T::zero(),
69        it,
70        curr,
71      }
72    }
73  }
74}
75
76#[inline(always)]
77pub(crate) fn degrade_range<T: Idx>(
78  range: &mut Range<T>,
79  /*one_at_new_depth: T,*/ rm_bits_mask: T,
80  bits_to_be_rm_mask: T,
81) {
82  range.start &= rm_bits_mask;
83  /*if range.end & bits_to_be_rm_mask != T::zero() {
84    range.end = (range.end & rm_bits_mask) + one_at_new_depth;
85  }*/
86  range.end = (range.end + bits_to_be_rm_mask) & rm_bits_mask
87}
88
89impl<T, Q, I> HasMaxDepth for DegradeRangeIter<T, Q, I>
90where
91  T: Idx,
92  Q: MocQty<T>,
93  I: RangeMOCIterator<T, Qty = Q>,
94{
95  fn depth_max(&self) -> u8 {
96    self.new_depth
97  }
98}
99impl<T, Q, I> ZSorted for DegradeRangeIter<T, Q, I>
100where
101  T: Idx,
102  Q: MocQty<T>,
103  I: RangeMOCIterator<T, Qty = Q>,
104{
105}
106impl<T, Q, I> NonOverlapping for DegradeRangeIter<T, Q, I>
107where
108  T: Idx,
109  Q: MocQty<T>,
110  I: RangeMOCIterator<T, Qty = Q>,
111{
112}
113impl<T, Q, I> MOCProperties for DegradeRangeIter<T, Q, I>
114where
115  T: Idx,
116  Q: MocQty<T>,
117  I: RangeMOCIterator<T, Qty = Q>,
118{
119}
120impl<T, Q, I> Iterator for DegradeRangeIter<T, Q, I>
121where
122  T: Idx,
123  Q: MocQty<T>,
124  I: RangeMOCIterator<T, Qty = Q>,
125{
126  type Item = Range<T>;
127
128  fn next(&mut self) -> Option<Self::Item> {
129    if let Some(cr) = &mut self.curr {
130      let mut next = self.it.next();
131      while let Some(nr) = &mut next {
132        degrade_range(
133          nr,
134          /*self.one_at_new_depth,*/ self.rm_bits_mask,
135          self.bits_to_be_rm_mask,
136        );
137        if nr.start > cr.end {
138          break;
139        } else {
140          cr.end = nr.end;
141          next = self.it.next();
142        }
143      }
144      std::mem::replace(&mut self.curr, next)
145    } else {
146      None
147    }
148  }
149
150  /*fn size_hint(&self) -> (usize, Option<usize>) {
151  }*/
152}
153
154impl<T, Q, I> RangeMOCIterator<T> for DegradeRangeIter<T, Q, I>
155where
156  T: Idx,
157  Q: MocQty<T>,
158  I: RangeMOCIterator<T, Qty = Q>,
159{
160  type Qty = Q;
161
162  fn peek_last(&self) -> Option<&Range<T>> {
163    // self.it.peek_last()
164    // TODO: peek last, degrade and store the result to provide it here
165    None
166  }
167}