1use super::RangeRef;
2use crate::base::CellRef;
3use crate::calc::eval::Area;
4use std::collections::BTreeSet;
5use std::hash::{BuildHasherDefault, Hasher};
6
7#[derive(Default, Clone, Copy)]
9pub struct FxHasher(u64);
10
11impl Hasher for FxHasher {
12 fn finish(&self) -> u64 {
13 self.0
14 }
15 fn write(&mut self, bytes: &[u8]) {
16 for b in bytes {
17 self.write_u64(*b as u64);
18 }
19 }
20 fn write_u64(&mut self, i: u64) {
21 self.0 = (self.0.rotate_left(5) ^ i).wrapping_mul(0x51_7c_c1_b7_27_22_0a_95);
22 }
23 fn write_u32(&mut self, i: u32) {
24 self.write_u64(i as u64);
25 }
26 fn write_usize(&mut self, i: usize) {
27 self.write_u64(i as u64);
28 }
29}
30
31pub(super) type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasherDefault<FxHasher>>;
32
33pub(super) type HashSet<K> = std::collections::HashSet<K, BuildHasherDefault<FxHasher>>;
34
35pub type Key = (usize, CellRef);
36
37#[derive(Clone, Debug, Default)]
38pub(super) struct Node {
39 pub(super) areas: Vec<Area>,
40 pub(super) dynamic: bool,
41}
42
43const WIDE: u32 = 64;
45
46const PENDING: usize = 32;
48
49#[derive(Clone, Debug)]
57pub(super) struct Intervals<T> {
58 items: Vec<(u32, u32, T)>,
60 dead: Vec<bool>,
61 dead_count: usize,
62 max_end: Vec<u32>,
65 pending: BTreeSet<(u32, u32, T)>,
67}
68
69impl<T> Default for Intervals<T> {
70 fn default() -> Self {
71 Intervals { items: Vec::new(), dead: Vec::new(), dead_count: 0, max_end: Vec::new(), pending: BTreeSet::new() }
72 }
73}
74
75impl<T: Copy + Ord> Intervals<T> {
76 pub(super) fn is_empty(&self) -> bool {
77 self.items.len() == self.dead_count && self.pending.is_empty()
78 }
79
80 pub(super) fn insert(&mut self, r0: u32, r1: u32, t: T) {
81 let it = (r0, r1, t);
82 if let Ok(i) = self.items.binary_search(&it) {
83 if let Some(d) = self.dead.get_mut(i)
84 && *d
85 {
86 *d = false;
87 self.dead_count -= 1;
88 }
89 return;
90 }
91 self.pending.insert(it);
92 }
93
94 pub(super) fn remove(&mut self, r0: u32, r1: u32, t: T) {
95 let it = (r0, r1, t);
96 if let Ok(i) = self.items.binary_search(&it) {
97 if let Some(d) = self.dead.get_mut(i)
98 && !*d
99 {
100 *d = true;
101 self.dead_count += 1;
102 }
103 return;
104 }
105 self.pending.remove(&it);
106 }
107
108 pub(super) fn settle(&mut self) {
110 if self.pending.len() <= PENDING && self.dead_count <= (self.items.len() / 2).max(PENDING) {
111 return;
112 }
113 let mut all: Vec<(u32, u32, T)> = Vec::with_capacity(self.items.len() - self.dead_count + self.pending.len());
114 all.extend(self.items.iter().zip(&self.dead).filter(|(_, d)| !**d).map(|(it, _)| *it));
115 all.extend(std::mem::take(&mut self.pending));
116 all.sort();
118 all.dedup();
119 let size = all.len().next_power_of_two();
120 let mut max_end = vec![0; 2 * size];
121 if let Some(leaves) = max_end.get_mut(size..) {
122 for (slot, it) in leaves.iter_mut().zip(&all) {
123 *slot = it.1;
124 }
125 }
126 for i in (1..size).rev() {
127 let m = max_end.get(2 * i).copied().unwrap_or(0).max(max_end.get(2 * i + 1).copied().unwrap_or(0));
128 if let Some(slot) = max_end.get_mut(i) {
129 *slot = m;
130 }
131 }
132 self.dead = vec![false; all.len()];
133 self.dead_count = 0;
134 self.items = all;
135 self.max_end = max_end;
136 }
137
138 pub(super) fn query(&self, a: u32, b: u32, f: &mut dyn FnMut(&T)) -> usize {
141 for it in &self.pending {
142 if it.0 <= b && it.1 >= a {
143 f(&it.2);
144 }
145 }
146 let p = self.items.partition_point(|it| it.0 <= b);
148 if p == 0 {
149 return 0;
150 }
151 self.walk(1, 0, self.max_end.len() / 2, p, a, f)
152 }
153
154 pub(super) fn query_untaken(&self, a: u32, b: u32, taken: &mut Vec<bool>, f: &mut dyn FnMut(&T) -> bool) {
160 for it in &self.pending {
161 if it.0 <= b && it.1 >= a {
162 f(&it.2);
163 }
164 }
165 let p = self.items.partition_point(|it| it.0 <= b);
166 if p == 0 {
167 return;
168 }
169 if taken.len() != self.max_end.len() {
170 *taken = vec![false; self.max_end.len()];
171 }
172 self.walk_untaken(1, 0, self.max_end.len() / 2, p, a, taken, f);
173 }
174
175 #[allow(clippy::too_many_arguments)]
177 fn walk_untaken(&self, node: usize, lo: usize, hi: usize, p: usize, a: u32, taken: &mut [bool], f: &mut dyn FnMut(&T) -> bool) -> bool {
178 if taken.get(node).copied().unwrap_or(true) {
179 return true;
180 }
181 if lo >= p || self.max_end.get(node).is_none_or(|m| *m < a) {
182 return false;
183 }
184 let done = if hi - lo <= 1 {
185 match (self.items.get(lo), self.dead.get(lo)) {
186 (Some(it), Some(false)) if it.1 >= a => f(&it.2),
187 (Some(_), Some(true)) => true,
188 _ => false,
189 }
190 } else {
191 let mid = lo + (hi - lo) / 2;
192 let left = self.walk_untaken(2 * node, lo, mid, p, a, taken, f);
193 let right = self.walk_untaken(2 * node + 1, mid, hi, p, a, taken, f);
194 left && right
195 };
196 if done && let Some(slot) = taken.get_mut(node) {
197 *slot = true;
198 }
199 done
200 }
201
202 fn walk(&self, node: usize, lo: usize, hi: usize, p: usize, a: u32, f: &mut dyn FnMut(&T)) -> usize {
203 if lo >= p || self.max_end.get(node).is_none_or(|m| *m < a) {
204 return 1;
205 }
206 if hi - lo <= 1 {
207 if let (Some(it), Some(false)) = (self.items.get(lo), self.dead.get(lo))
208 && it.1 >= a
209 {
210 f(&it.2);
211 }
212 return 1;
213 }
214 let mid = lo + (hi - lo) / 2;
215 1 + self.walk(2 * node, lo, mid, p, a, f) + self.walk(2 * node + 1, mid, hi, p, a, f)
216 }
217}
218
219#[derive(Default)]
221pub(super) struct Taken {
222 cols: HashMap<(usize, u32), Vec<bool>>,
223 wide: HashMap<usize, Vec<bool>>,
224}
225
226#[derive(Clone, Debug, Default)]
227pub struct Graph {
228 pub(super) nodes: HashMap<Key, Node>,
229 cell_deps: HashMap<Key, HashSet<Key>>,
231 col_deps: HashMap<(usize, u32), Intervals<Key>>,
233 wide_deps: HashMap<usize, Intervals<(u32, u32, Key)>>,
235 pub(super) dynamic: HashSet<Key>,
236 unsettled_cols: HashSet<(usize, u32)>,
238 unsettled_wide: HashSet<usize>,
239}
240
241type Entries = (Vec<Key>, Vec<(usize, u32, u32, u32)>, Vec<(usize, RangeRef)>);
243
244impl Graph {
245 pub fn len(&self) -> usize {
246 self.nodes.len()
247 }
248 pub fn is_empty(&self) -> bool {
249 self.nodes.is_empty()
250 }
251
252 fn entries(areas: &[Area]) -> Entries {
255 let (mut cells, mut cols, mut wide) = (Vec::new(), Vec::new(), Vec::new());
256 for a in areas {
257 if a.range.is_single() {
258 cells.push((a.sheet, a.range.start));
259 } else if a.range.width() > WIDE {
260 wide.push((a.sheet, a.range));
261 } else {
262 for c in a.range.start.col..=a.range.end.col {
263 cols.push((a.sheet, c, a.range.start.row, a.range.end.row));
264 }
265 }
266 }
267 cells.sort_unstable();
268 cells.dedup();
269 cols.sort_unstable();
270 cols.dedup();
271 wide.sort_unstable_by_key(|(s, r)| (*s, r.start, r.end));
272 wide.dedup();
273 (cells, cols, wide)
274 }
275
276 pub(super) fn insert(&mut self, k: Key, node: Node) {
277 self.remove(k);
278 let (cells, cols, wide) = Self::entries(&node.areas);
279 for c in cells {
280 self.cell_deps.entry(c).or_default().insert(k);
281 }
282 for (s, c, r0, r1) in cols {
283 self.col_deps.entry((s, c)).or_default().insert(r0, r1, k);
284 self.unsettled_cols.insert((s, c));
285 }
286 for (s, r) in wide {
287 self.wide_deps.entry(s).or_default().insert(r.start.row, r.end.row, (r.start.col, r.end.col, k));
288 self.unsettled_wide.insert(s);
289 }
290 if node.dynamic {
291 self.dynamic.insert(k);
292 }
293 self.nodes.insert(k, node);
294 }
295
296 pub(super) fn remove(&mut self, k: Key) {
297 let Some(old) = self.nodes.remove(&k) else { return };
298 let (cells, cols, wide) = Self::entries(&old.areas);
299 for c in cells {
300 if let Some(v) = self.cell_deps.get_mut(&c) {
301 v.remove(&k);
302 if v.is_empty() {
303 self.cell_deps.remove(&c);
304 }
305 }
306 }
307 for (s, c, r0, r1) in cols {
308 if let Some(v) = self.col_deps.get_mut(&(s, c)) {
309 v.remove(r0, r1, k);
310 self.unsettled_cols.insert((s, c));
311 }
312 }
313 for (s, r) in wide {
314 if let Some(v) = self.wide_deps.get_mut(&s) {
315 v.remove(r.start.row, r.end.row, (r.start.col, r.end.col, k));
316 self.unsettled_wide.insert(s);
317 }
318 }
319 self.dynamic.remove(&k);
320 }
321
322 pub(super) fn settle(&mut self) {
325 for key in std::mem::take(&mut self.unsettled_cols) {
326 if let Some(v) = self.col_deps.get_mut(&key) {
327 v.settle();
328 if v.is_empty() {
329 self.col_deps.remove(&key);
330 }
331 }
332 }
333 for key in std::mem::take(&mut self.unsettled_wide) {
334 if let Some(v) = self.wide_deps.get_mut(&key) {
335 v.settle();
336 if v.is_empty() {
337 self.wide_deps.remove(&key);
338 }
339 }
340 }
341 }
342
343 pub fn dependents(&self, sheet: usize, c: CellRef, out: &mut Vec<Key>) {
345 if let Some(v) = self.cell_deps.get(&(sheet, c)) {
346 out.extend(v.iter().copied());
347 }
348 if let Some(v) = self.col_deps.get(&(sheet, c.col)) {
349 v.query(c.row, c.row, &mut |k| out.push(*k));
350 }
351 if let Some(v) = self.wide_deps.get(&sheet) {
352 v.query(c.row, c.row, &mut |(c0, c1, k)| {
353 if *c0 <= c.col && c.col <= *c1 {
354 out.push(*k);
355 }
356 });
357 }
358 }
359
360 pub(super) fn dependents_untaken(&self, sheet: usize, c: CellRef, taken: &mut Taken, out: &mut Vec<Key>) {
365 if let Some(v) = self.cell_deps.get(&(sheet, c)) {
366 out.extend(v.iter().copied());
367 }
368 if let Some(v) = self.col_deps.get(&(sheet, c.col)) {
369 v.query_untaken(c.row, c.row, taken.cols.entry((sheet, c.col)).or_default(), &mut |k| {
370 out.push(*k);
371 true
372 });
373 }
374 if let Some(v) = self.wide_deps.get(&sheet) {
375 v.query_untaken(c.row, c.row, taken.wide.entry(sheet).or_default(), &mut |(c0, c1, k)| {
377 let hit = *c0 <= c.col && c.col <= *c1;
378 if hit {
379 out.push(*k);
380 }
381 hit
382 });
383 }
384 }
385
386 pub fn dependents_of_range(&self, sheet: usize, range: RangeRef, out: &mut Vec<Key>) {
388 if range.count() <= 4096 {
389 for c in range.iter() {
390 if let Some(v) = self.cell_deps.get(&(sheet, c)) {
391 out.extend(v.iter().copied());
392 }
393 }
394 } else {
395 for ((s, c), v) in &self.cell_deps {
396 if *s == sheet && range.contains(*c) {
397 out.extend(v.iter().copied());
398 }
399 }
400 }
401 let (r0, r1) = (range.start.row, range.end.row);
402 if (range.width() as usize) <= self.col_deps.len() {
403 for col in range.start.col..=range.end.col {
404 if let Some(v) = self.col_deps.get(&(sheet, col)) {
405 v.query(r0, r1, &mut |k| out.push(*k));
406 }
407 }
408 } else {
409 for ((s, col), v) in &self.col_deps {
410 if *s == sheet && range.start.col <= *col && *col <= range.end.col {
411 v.query(r0, r1, &mut |k| out.push(*k));
412 }
413 }
414 }
415 if let Some(v) = self.wide_deps.get(&sheet) {
416 v.query(r0, r1, &mut |(c0, c1, k)| {
417 if *c0 <= range.end.col && range.start.col <= *c1 {
418 out.push(*k);
419 }
420 });
421 }
422 }
423
424 pub fn precedents_of(&self, k: Key) -> Vec<Area> {
426 self.nodes.get(&k).map(|n| n.areas.clone()).unwrap_or_default()
427 }
428}