1use crate::map::ValueRef;
2use crate::merge_map::KMergeMap;
3use crate::sorted_disjoint_map::{Priority, PrioritySortedStartsMap};
4use crate::{AssumeSortedStarts, MergeMap, SortedDisjointMap, UnionKMergeMap, UnionMergeMap};
5use alloc::{collections::BinaryHeap, vec};
6use core::cmp::min;
7use core::iter::FusedIterator;
8use core::ops::RangeInclusive;
9use itertools::Itertools;
10
11use crate::Integer;
12use crate::unsorted_priority_map::AssumePrioritySortedStartsMap;
13use crate::unsorted_priority_map::UnsortedPriorityMap;
14
15type SortedStartsInVecMap<T, VR> =
16 AssumePrioritySortedStartsMap<T, VR, vec::IntoIter<Priority<T, VR>>>;
17#[allow(clippy::redundant_pub_crate)]
18pub(crate) type SortedStartsInVec<T> = AssumeSortedStarts<T, vec::IntoIter<RangeInclusive<T>>>;
19
20#[derive(Clone, Debug)]
25#[must_use = "iterators are lazy and do nothing unless consumed"]
26pub struct UnionIterMap<T, VR, SS>
27where
28 T: Integer,
29 VR: ValueRef,
30 SS: PrioritySortedStartsMap<T, VR>,
31{
32 iter: SS,
33 next_item: Option<Priority<T, VR>>,
34 workspace: BinaryHeap<Priority<T, VR>>,
35 gather: Option<(RangeInclusive<T>, VR)>,
36 ready_to_go: Option<(RangeInclusive<T>, VR)>,
37}
38
39impl<T, VR, I> Iterator for UnionIterMap<T, VR, I>
40where
41 T: Integer,
42 VR: ValueRef,
43 I: PrioritySortedStartsMap<T, VR>,
44{
45 type Item = (RangeInclusive<T>, VR);
46
47 fn next(&mut self) -> Option<(RangeInclusive<T>, VR)> {
48 loop {
50 if let Some(value) = self.ready_to_go.take() {
51 return Some(value);
53 }
54
55 if let Some(next_item) = self.next_item.take() {
57 let (next_start, next_end) = next_item.start_and_end();
58
59 let Some(best) = self.workspace.peek() else {
61 self.workspace.push(next_item);
62 self.next_item = self.iter.next();
63 continue; };
65 if next_start == best.start() {
67 if &next_item > best || next_end > best.end() {
69 self.workspace.push(next_item);
70 }
71 self.next_item = self.iter.next();
72 continue; }
74
75 self.next_item = Some(next_item);
77 }
78
79 let Some(best) = self.workspace.peek() else {
81 debug_assert!(self.next_item.is_none());
82 debug_assert!(self.ready_to_go.is_none());
83 return self.gather.take();
84 };
85
86 let next_end = self.next_item.as_ref().map_or_else(
90 || best.end(),
91 |next_item| min(next_item.start().sub_one(), best.end()),
92 );
93
94 if let Some(mut gather) = self.gather.take() {
96 if gather.1.borrow() == best.value().borrow()
97 && (*gather.0.end()).add_one() == best.start()
98 {
99 gather.0 = *gather.0.start()..=next_end;
101 self.gather = Some(gather);
102 } else {
103 self.ready_to_go = Some(gather);
105 self.gather = Some((best.start()..=next_end, best.value().clone()));
106 }
107 } else {
108 self.gather = Some((best.start()..=next_end, best.value().clone()));
110 }
111
112 let mut new_workspace = BinaryHeap::new();
115 while let Some(item) = self.workspace.pop() {
116 let mut item = item;
117 if item.end() <= next_end {
118 continue; }
121 item.set_range(next_end.add_one()..=item.end());
122 let Some(new_best) = new_workspace.peek() else {
123 new_workspace.push(item);
125 continue; };
127 if &item < new_best && item.end() <= new_best.end() {
128 continue; }
132
133 new_workspace.push(item);
136 }
137 self.workspace = new_workspace;
138 } }
140}
141
142impl<T, VR, I> UnionIterMap<T, VR, I>
143where
144 T: Integer,
145 VR: ValueRef,
146 I: PrioritySortedStartsMap<T, VR>,
147{
148 #[inline]
149 pub(crate) fn new(mut iter: I) -> Self {
150 let item = iter.next();
151 Self {
152 iter,
153 next_item: item,
154 workspace: BinaryHeap::new(),
155 gather: None,
156 ready_to_go: None,
157 }
158 }
159}
160
161impl<T, VR, L, R> UnionMergeMap<T, VR, L, R>
162where
163 T: Integer,
164 VR: ValueRef,
165 L: SortedDisjointMap<T, VR>,
166 R: SortedDisjointMap<T, VR>,
167{
168 #[inline]
169 pub(crate) fn new2(left: L, right: R) -> Self {
170 let iter = MergeMap::new(left, right);
171 Self::new(iter)
172 }
173}
174
175impl<T, VR, J> UnionKMergeMap<T, VR, J>
176where
177 T: Integer,
178 VR: ValueRef,
179 J: SortedDisjointMap<T, VR>,
180{
181 #[inline]
182 pub(crate) fn new_k<K>(k: K) -> Self
183 where
184 K: IntoIterator<Item = J>,
185 {
186 let iter = KMergeMap::new(k);
187 Self::new(iter)
188 }
189}
190
191impl<T, VR> FromIterator<(RangeInclusive<T>, VR)>
193 for UnionIterMap<T, VR, SortedStartsInVecMap<T, VR>>
194where
195 T: Integer,
196 VR: ValueRef,
197{
198 fn from_iter<I>(iter: I) -> Self
199 where
200 I: IntoIterator<Item = (RangeInclusive<T>, VR)>,
201 {
202 let iter = iter.into_iter();
203 let iter = UnsortedPriorityMap::new(iter);
204 let iter = iter.sorted_by(|a, b| a.start().cmp(&b.start()));
206 let iter = AssumePrioritySortedStartsMap::new(iter);
207 Self::new(iter)
208 }
209}
210
211impl<T, VR, I> FusedIterator for UnionIterMap<T, VR, I>
212where
213 T: Integer,
214 VR: ValueRef,
215 I: PrioritySortedStartsMap<T, VR> + FusedIterator,
216{
217}