1use alloc::vec::Vec;
4use core::{
5 cmp::Ordering,
6 hash::{BuildHasher, Hash},
7 mem,
8};
9
10use hashbrown::{HashMap, HashSet};
11use indexmap::IndexSet;
12use scratchpads::{Scratchpad, ScratchpadMap};
13
14#[cfg(debug_assertions)]
15use contracts::contract;
16
17#[cfg(feature = "rkyv")]
18use rkyv::{
19 Archive, Deserialize, Serialize,
20 bytecheck::Verify,
21 collections::swiss_table::{ArchivedHashMap, ArchivedHashSet, ArchivedIndexSet},
22 rancor::{Fallible, Source, fail},
23 with::Skip,
24};
25
26#[cfg(feature = "serde")]
27use serde::{
28 Deserialize as SerdeDeserialize, Deserializer as SerdeDeserializer,
29 Serialize as SerdeSerialize, de::Error as _,
30};
31
32use crate::{
33 ActivePathWeave, BookmarkableWeave, DiscreteContentResult, DiscreteContents, DiscreteWeave,
34 IndependentContents, MetadataWeave, Node, SemiIndependentWeave, SortableBookmarkableWeave,
35 SortableWeave, Weave, ancestor_subgraph,
36 contract::valid_topology,
37 dependent::{DependentNode, DependentWeave},
38 descendant_subgraph, longest_candidate_path_to_root, shortest_path_to_ancestor,
39 topological_sort, topological_sort_subgraph,
40};
41
42#[cfg(debug_assertions)]
43use crate::contract::{lacks_duplicates, valid_path, valid_topological_sort};
44
45#[cfg(feature = "rkyv")]
46use crate::{
47 ImmutableActivePathWeave, ImmutableBookmarkableWeave, ImmutableMetadataWeave, ImmutableWeave,
48 archived_ancestor_subgraph, archived_descendant_subgraph,
49 archived_longest_candidate_path_to_root, archived_shortest_path_to_ancestor,
50 archived_topological_sort, archived_topological_sort_subgraph,
51 contract::archived_valid_topology,
52};
53
54#[cfg(any(feature = "serde", feature = "rkyv"))]
55use crate::contract::ValidationError;
56
57#[derive(Default, Debug, Clone)]
58#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
59#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
60#[must_use]
62pub struct IndependentNode<K, T, S>
63where
64 K: Hash + Copy + Eq + Ord,
65 T: IndependentContents,
66 S: BuildHasher + Default + Clone,
67{
68 pub id: K,
70 #[cfg_attr(
72 feature = "serde",
73 serde(bound(
74 serialize = "IndexSet<K, S>: SerdeSerialize",
75 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
76 ))
77 )]
78 pub from: IndexSet<K, S>,
79 #[cfg_attr(
81 feature = "serde",
82 serde(bound(
83 serialize = "IndexSet<K, S>: SerdeSerialize",
84 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
85 ))
86 )]
87 pub to: IndexSet<K, S>,
88 pub active: bool,
92 pub bookmarked: bool,
94 pub contents: T,
96}
97
98#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
99impl<K, T, S> PartialEq for IndependentNode<K, T, S>
100where
101 K: Hash + Copy + Eq + Ord,
102 T: IndependentContents + PartialEq,
103 S: BuildHasher + Default + Clone,
104{
105 #[inline]
106 fn eq(&self, other: &Self) -> bool {
107 self.id == other.id
108 && self.from.len() == other.from.len()
109 && self.to.len() == other.to.len()
110 && self.from.iter().zip(other.from.iter()).all(|(a, b)| a == b)
111 && self.to.iter().zip(other.to.iter()).all(|(a, b)| a == b)
112 && self.active == other.active
113 && self.bookmarked == other.bookmarked
114 && self.contents == other.contents
115 }
116}
117
118#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
119impl<K, T, S> Eq for IndependentNode<K, T, S>
120where
121 K: Hash + Copy + Eq + Ord,
122 T: IndependentContents + Eq,
123 S: BuildHasher + Default + Clone,
124{
125}
126
127impl<K, T, S> IndependentNode<K, T, S>
128where
129 K: Hash + Copy + Eq + Ord,
130 T: IndependentContents,
131 S: BuildHasher + Default + Clone,
132{
133 fn validate(&self) -> bool {
134 self.from.is_disjoint(&self.to)
135 && !self.from.contains(&self.id)
136 && !self.to.contains(&self.id)
137 }
138}
139
140impl<K, T, S> Node<K, T> for IndependentNode<K, T, S>
141where
142 K: Hash + Copy + Eq + Ord,
143 T: IndependentContents,
144 S: BuildHasher + Default + Clone,
145{
146 type From = IndexSet<K, S>;
147 type To = IndexSet<K, S>;
148
149 #[inline]
150 fn id(&self) -> K {
151 self.id
152 }
153 #[inline]
154 fn from(&self) -> &Self::From {
155 &self.from
156 }
157 #[inline]
158 fn to(&self) -> &Self::To {
159 &self.to
160 }
161 #[inline]
162 fn is_active(&self) -> bool {
163 self.active
164 }
165 #[inline]
166 fn contents(&self) -> &T {
167 &self.contents
168 }
169}
170
171impl<K, T, S> From<DependentNode<K, T, S>> for IndependentNode<K, T, S>
172where
173 K: Hash + Copy + Eq + Ord,
174 T: IndependentContents,
175 S: BuildHasher + Default + Clone,
176{
177 #[inline]
178 fn from(value: DependentNode<K, T, S>) -> Self {
179 Self {
180 id: value.id,
181 from: IndexSet::from_iter(value.from),
182 to: value.to,
183 active: value.active,
184 bookmarked: value.bookmarked,
185 contents: value.contents,
186 }
187 }
188}
189
190impl<K, T, S> TryFrom<IndependentNode<K, T, S>> for DependentNode<K, T, S>
191where
192 K: Hash + Copy + Eq + Ord,
193 T: IndependentContents,
194 S: BuildHasher + Default + Clone,
195{
196 type Error = IndependentNode<K, T, S>;
197
198 #[inline]
199 fn try_from(value: IndependentNode<K, T, S>) -> Result<Self, Self::Error> {
200 if value.from.len() < 2 {
201 Ok(Self {
202 id: value.id,
203 from: value.from.into_iter().next(),
204 to: value.to,
205 active: value.active,
206 bookmarked: value.bookmarked,
207 contents: value.contents,
208 })
209 } else {
210 Err(value)
211 }
212 }
213}
214
215#[derive(Default, Debug, Clone)]
219#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
220#[cfg_attr(feature = "serde", derive(SerdeSerialize))]
221#[cfg_attr(feature = "rkyv", rkyv(bytecheck(verify)))]
222#[must_use]
223pub struct IndependentWeave<K, T, M, S>
224where
225 K: Hash + Copy + Eq + Ord,
226 T: IndependentContents,
227 S: BuildHasher + Default + Clone,
228{
229 #[cfg_attr(
230 feature = "serde",
231 serde(bound(
232 serialize = "HashMap<K, IndependentNode<K, T, S>, S>: SerdeSerialize",
233 deserialize = "HashMap<K, IndependentNode<K, T, S>, S>: SerdeDeserialize<'de>"
234 ))
235 )]
236 nodes: HashMap<K, IndependentNode<K, T, S>, S>,
237 #[cfg_attr(
238 feature = "serde",
239 serde(bound(
240 serialize = "IndexSet<K, S>: SerdeSerialize",
241 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
242 ))
243 )]
244 roots: IndexSet<K, S>,
245 #[cfg_attr(
246 feature = "serde",
247 serde(bound(
248 serialize = "HashSet<K, S>: SerdeSerialize",
249 deserialize = "HashSet<K, S>: SerdeDeserialize<'de>"
250 ))
251 )]
252 active: HashSet<K, S>,
253 #[cfg_attr(
254 feature = "serde",
255 serde(bound(
256 serialize = "IndexSet<K, S>: SerdeSerialize",
257 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
258 ))
259 )]
260 bookmarked: IndexSet<K, S>,
261
262 #[cfg_attr(feature = "rkyv", rkyv(with = Skip))]
263 #[cfg_attr(feature = "serde", serde(skip))]
264 scratchpad: Scratchpad,
265
266 pub metadata: M,
268}
269
270#[cfg(feature = "serde")]
271#[derive(SerdeDeserialize)]
272#[serde(rename = "IndependentWeave")]
273struct ProxyIndependentWeave<K, T, M, S>
274where
275 K: Hash + Copy + Eq + Ord,
276 T: IndependentContents,
277 S: BuildHasher + Default + Clone,
278{
279 #[serde(bound(
280 serialize = "HashMap<K, IndependentNode<K, T, S>, S>: SerdeSerialize",
281 deserialize = "HashMap<K, IndependentNode<K, T, S>, S>: SerdeDeserialize<'de>"
282 ))]
283 nodes: HashMap<K, IndependentNode<K, T, S>, S>,
284 #[serde(bound(
285 serialize = "IndexSet<K, S>: SerdeSerialize",
286 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
287 ))]
288 roots: IndexSet<K, S>,
289 #[serde(bound(
290 serialize = "HashSet<K, S>: SerdeSerialize",
291 deserialize = "HashSet<K, S>: SerdeDeserialize<'de>"
292 ))]
293 active: HashSet<K, S>,
294 #[serde(bound(
295 serialize = "IndexSet<K, S>: SerdeSerialize",
296 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
297 ))]
298 bookmarked: IndexSet<K, S>,
299 metadata: M,
300}
301
302#[cfg(feature = "serde")]
303#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
304impl<'de, K, T, M, S> SerdeDeserialize<'de> for IndependentWeave<K, T, M, S>
305where
306 K: Hash + Copy + Eq + Ord + SerdeDeserialize<'de>,
307 T: IndependentContents + SerdeDeserialize<'de>,
308 M: SerdeDeserialize<'de>,
309 S: BuildHasher + Default + Clone,
310{
311 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
312 where
313 D: SerdeDeserializer<'de>,
314 {
315 let proxy = ProxyIndependentWeave::deserialize(deserializer)?;
316 let weave = Self {
317 nodes: proxy.nodes,
318 roots: proxy.roots,
319 active: proxy.active,
320 bookmarked: proxy.bookmarked,
321 scratchpad: Scratchpad::new(),
322 metadata: proxy.metadata,
323 };
324
325 if weave.validate() {
326 Ok(weave)
327 } else {
328 Err(D::Error::custom(ValidationError))
329 }
330 }
331}
332
333#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
334impl<K, T, M, S> PartialEq for IndependentWeave<K, T, M, S>
335where
336 K: Hash + Copy + Eq + Ord,
337 T: IndependentContents + PartialEq,
338 M: PartialEq,
339 S: BuildHasher + Default + Clone,
340{
341 #[inline]
342 fn eq(&self, other: &Self) -> bool {
343 self.roots.len() == other.roots.len()
344 && self.bookmarked.len() == other.bookmarked.len()
345 && self.active == other.active
346 && self
347 .roots
348 .iter()
349 .zip(other.roots.iter())
350 .all(|(a, b)| a == b)
351 && self
352 .bookmarked
353 .iter()
354 .zip(other.bookmarked.iter())
355 .all(|(a, b)| a == b)
356 && self.nodes == other.nodes
357 && self.metadata == other.metadata
358 }
359}
360
361#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
362impl<K, T, M, S> Eq for IndependentWeave<K, T, M, S>
363where
364 K: Hash + Copy + Eq + Ord,
365 T: IndependentContents + Eq,
366 M: Eq,
367 S: BuildHasher + Default + Clone,
368{
369}
370
371impl<K, T, M, S> IndependentWeave<K, T, M, S>
372where
373 K: Hash + Copy + Eq + Ord,
374 T: IndependentContents,
375 S: BuildHasher + Default + Clone,
376{
377 #[cfg_attr(debug_assertions, contract(
379 ensures(ret.nodes.is_empty()),
380 ensures(ret.validate())
381 ))]
382 pub fn with_capacity(capacity: usize, metadata: M) -> Self {
383 Self {
384 nodes: HashMap::with_capacity_and_hasher(capacity, S::default()),
385 roots: IndexSet::with_capacity_and_hasher(capacity, S::default()),
386 active: HashSet::with_capacity_and_hasher(capacity, S::default()),
387 bookmarked: IndexSet::with_capacity_and_hasher(capacity, S::default()),
388 scratchpad: Scratchpad::new(),
389 metadata,
390 }
391 }
392 #[inline]
394 pub fn capacity(&self) -> usize {
395 self.nodes.capacity()
396 }
397 #[cfg_attr(debug_assertions, contract(
399 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
400 ensures(old(self.roots.clone()) == self.roots),
401 ensures(old(self.active.clone()) == self.active),
402 ensures(old(self.bookmarked.clone()) == self.bookmarked),
403 invariant(self.validate())
404 ))]
405 pub fn reserve(&mut self, additional: usize) {
406 self.nodes.reserve(additional);
407 self.roots
408 .reserve(self.nodes.capacity().saturating_sub(self.roots.len()));
409 self.active
410 .reserve(self.nodes.capacity().saturating_sub(self.active.len()));
411 self.bookmarked
412 .reserve(self.nodes.capacity().saturating_sub(self.bookmarked.len()));
413 }
414 #[cfg_attr(debug_assertions, contract(
416 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
417 ensures(old(self.roots.clone()) == self.roots),
418 ensures(old(self.active.clone()) == self.active),
419 ensures(old(self.bookmarked.clone()) == self.bookmarked),
420 invariant(self.validate())
421 ))]
422 pub fn shrink_to(&mut self, min_capacity: usize) {
423 self.nodes.shrink_to(min_capacity);
424 self.roots.shrink_to(min_capacity);
425 self.active.shrink_to(min_capacity);
426 self.bookmarked.shrink_to(min_capacity);
427 }
428 #[allow(
429 clippy::too_many_lines,
430 reason = "Cannot be split into smaller functions"
431 )]
432 #[cfg_attr(debug_assertions, contract(
433 ensures(ret == self.nodes.contains_key(id)),
434 ensures(!ret || value == self.active.contains(id)),
435 ensures(self.validate())
436 ))]
437 fn update_node_activity_in_place(&mut self, id: &K, value: bool) -> bool {
438 let at_end = if let Some(node) = self.nodes.get(id) {
439 if node.active == value {
440 return true;
441 }
442
443 if value {
444 (node.from.is_empty() && self.active.is_empty())
445 || node.from.iter().any(|parent| {
446 self.active.contains(parent)
447 && self.nodes[parent]
448 .to
449 .iter()
450 .all(|child| !self.active.contains(child))
451 })
452 } else {
453 node.to.iter().all(|child| !self.active.contains(child))
454 }
455 } else {
456 return false;
457 };
458
459 let node = self.nodes.get_mut(id).unwrap();
460 node.active = value;
461 if value {
462 self.active.insert(node.id);
463 } else {
464 self.active.remove(id);
465 }
466
467 if at_end {
468 return true;
469 }
470
471 if value {
472 let guard = self.scratchpad.guard();
473 let mut topological = guard.vec_with_capacity(self.nodes.len());
474 let mut scratchpad_map_2 = guard.map_with_capacity(self.nodes.len(), S::default());
475 let mut scratchpad_map_3: ScratchpadMap<'_, K, (usize, usize), S> =
476 guard.map_with_capacity(self.nodes.len(), S::default());
477 let mut scratchpad_set = guard.set(S::default());
478
479 topological_sort(
480 &self.nodes,
481 self.roots.iter().copied(),
482 &mut guard.vec_with_capacity(self.roots.len()),
483 |id| topological.push(id),
484 &mut guard.map_with_capacity(self.nodes.len(), S::default()),
485 );
486
487 for id in topological.iter().copied() {
488 let node = &self.nodes[&id];
489
490 let best_parent = node
491 .from
492 .iter()
493 .map(|id| (id, scratchpad_map_3[id])) .min_by(|(_, a), (_, b)| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
495
496 let (parent, score) = if let Some((parent, mut score)) = best_parent {
497 if node.active {
498 score.1 = score.1.strict_add(1);
499 } else {
500 score.0 = score.0.strict_add(1);
501 }
502
503 (Some(parent), score)
504 } else {
505 (None, if node.active { (0, 1) } else { (1, 0) })
506 };
507
508 if let Some(parent) = parent {
509 scratchpad_map_2.insert(id, *parent); }
511
512 scratchpad_map_3.insert(id, score);
513 }
514
515 let mut current = Some(id);
516
517 while let Some(id) = current {
518 scratchpad_set.insert(*id);
519 current = scratchpad_map_2.get(id);
520 }
521
522 scratchpad_map_2.clear();
523 scratchpad_map_3.clear();
524
525 for id in topological.drain(..).rev() {
526 let node = &self.nodes[&id];
527
528 let best_child = node
529 .to
530 .iter()
531 .map(|id| (id, scratchpad_map_3[id])) .min_by(|(_, a), (_, b)| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
533
534 let (child, score) = if let Some((child, mut score)) = best_child {
535 if node.active {
536 score.1 = score.1.strict_add(1);
537 } else {
538 score.0 = score.0.strict_add(1);
539 }
540
541 (Some(child), score)
542 } else {
543 (None, if node.active { (0, 1) } else { (1, 0) })
544 };
545
546 if let Some(child) = child {
547 scratchpad_map_2.insert(id, *child); }
549
550 scratchpad_map_3.insert(id, score);
551 }
552
553 let mut disjoint = topological;
554
555 let mut current = Some(id);
556
557 while let Some(id) = current {
558 scratchpad_set.insert(*id);
559
560 current = if scratchpad_map_3[id].1 > usize::from(self.nodes[id].active) {
561 scratchpad_map_2.get(id)
562 } else {
563 None
564 };
565 }
566
567 disjoint.extend(
568 self.active
569 .iter()
570 .filter(|id| !scratchpad_set.contains(*id))
571 .copied(),
572 );
573
574 for id in disjoint.drain(..) {
575 self.nodes.get_mut(&id).unwrap().active = false;
576 self.active.remove(&id);
577 }
578
579 disjoint.extend(
580 scratchpad_set
581 .iter()
582 .filter(|id| !self.active.contains(*id))
583 .copied(),
584 );
585
586 for id in disjoint.drain(..) {
587 self.nodes.get_mut(&id).unwrap().active = true;
588 self.active.insert(id);
589 }
590 } else {
591 self.fix_orphaned_activations();
592 }
593
594 true
595 }
596 #[cfg_attr(debug_assertions, contract(
597 ensures(self.validate())
598 ))]
599 fn fix_orphaned_activations(&mut self) {
600 let guard = self.scratchpad.guard();
601
602 let mut topological = guard.vec_with_capacity(self.nodes.len());
603 let mut scratchpad_map = guard.map_with_capacity(self.nodes.len(), S::default());
604
605 topological_sort(
606 &self.nodes,
607 self.roots.iter().copied(),
608 &mut guard.vec_with_capacity(self.roots.len()),
609 |id| topological.push(id),
610 &mut scratchpad_map,
611 );
612
613 scratchpad_map.clear();
614
615 let mut candidate_path = guard.vec_with_capacity(self.active.len());
616
617 longest_candidate_path_to_root(
618 &self.nodes,
619 &topological,
620 &|id| self.active.contains(id),
621 &mut scratchpad_map,
622 |id| candidate_path.push(id),
623 );
624
625 topological.clear();
626 let mut disjoint = topological;
627
628 let mut candidate_path_set = guard.set_with_capacity(candidate_path.len(), S::default());
629 candidate_path_set.extend(candidate_path.drain(..));
630
631 disjoint.extend(
632 self.active
633 .iter()
634 .filter(|id| !candidate_path_set.contains(*id))
635 .copied(),
636 );
637
638 for orphan in disjoint.drain(..) {
639 self.active.remove(&orphan);
640 if let Some(node) = self.nodes.get_mut(&orphan) {
641 node.active = false;
642 }
643 }
644 }
645 #[cfg_attr(debug_assertions, contract(
646 ensures(!ret || value || !self.active.contains(id) || (old(self.active.clone()) == self.active && self.nodes[id].to.iter().any(|id| self.contains_active(id)))),
647 ensures(!ret || !value || self.contains_active(id) && !self.nodes[id].to.iter().any(|id| self.active.contains(id))),
648 ensures(ret || old(self.active.clone()) == self.active),
649 ensures(ret == self.nodes.contains_key(id)),
650 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
651 ensures(old(self.roots.clone()) == self.roots),
652 ensures(old(self.bookmarked.clone()) == self.bookmarked),
653 invariant(self.validate())
654 ))]
655 #[allow(clippy::missing_panics_doc, reason = "Should never panic")]
656 pub fn set_active_dependent_semantics(&mut self, id: &K, value: bool) -> bool {
658 if value {
659 if let Some(node) = self.nodes.get(id) {
660 if node.active && !node.to.iter().any(|id| self.active.contains(id)) {
661 return true;
662 }
663
664 if !node.active
665 && ((node.from.is_empty() && self.active.is_empty())
666 || node.from.iter().any(|parent| {
667 self.active.contains(parent)
668 && self.nodes[parent]
669 .to
670 .iter()
671 .all(|child| !self.active.contains(child))
672 }))
673 {
674 self.nodes.get_mut(id).unwrap().active = true;
675 self.active.insert(*id);
676 return true;
677 }
678 } else {
679 return false;
680 }
681
682 let guard = self.scratchpad.guard();
683 let mut topological = guard.vec_with_capacity(self.nodes.len());
684 let mut scratchpad_map_2 = guard.map_with_capacity(self.nodes.len(), S::default());
685 let mut scratchpad_map_3: ScratchpadMap<'_, K, (usize, usize), S> =
686 guard.map_with_capacity(self.nodes.len(), S::default());
687 let mut scratchpad_set = guard.set(S::default());
688
689 topological_sort(
690 &self.nodes,
691 self.roots.iter().copied(),
692 &mut guard.vec_with_capacity(self.roots.len()),
693 |id| topological.push(id), &mut guard.map_with_capacity(self.nodes.len(), S::default()),
695 );
696
697 for id in topological.drain(..) {
698 let node = &self.nodes[&id];
699
700 let best_parent = node
701 .from
702 .iter()
703 .map(|id| (id, scratchpad_map_3[id])) .min_by(|(_, a), (_, b)| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
705
706 let (parent, score) = if let Some((parent, mut score)) = best_parent {
707 if node.active {
708 score.1 = score.1.strict_add(1);
709 } else {
710 score.0 = score.0.strict_add(1);
711 }
712
713 (Some(parent), score)
714 } else {
715 (None, if node.active { (0, 1) } else { (1, 0) })
716 };
717
718 if let Some(parent) = parent {
719 scratchpad_map_2.insert(id, *parent); }
721
722 scratchpad_map_3.insert(id, score);
723 }
724
725 let mut disjoint = topological;
726
727 let mut current = Some(id);
728
729 while let Some(id) = current {
730 scratchpad_set.insert(*id);
731 current = scratchpad_map_2.get(id);
732 }
733
734 disjoint.extend(
735 self.active
736 .iter()
737 .filter(|id| !scratchpad_set.contains(*id))
738 .copied(),
739 );
740
741 for id in disjoint.drain(..) {
742 self.nodes.get_mut(&id).unwrap().active = false;
743 self.active.remove(&id);
744 }
745
746 disjoint.extend(
747 scratchpad_set
748 .iter()
749 .filter(|id| !self.active.contains(*id))
750 .copied(),
751 );
752
753 for id in disjoint.drain(..) {
754 self.nodes.get_mut(&id).unwrap().active = true;
755 self.active.insert(id);
756 }
757 } else if let Some(node) = self.nodes.get_mut(id) {
758 if !node.active || node.to.iter().any(|id| self.active.contains(id)) {
759 return true;
760 }
761
762 node.active = false;
763 self.active.remove(&node.id);
764 } else {
765 return false;
766 }
767
768 true
769 }
770}
771
772impl<K, T, M, S> From<DependentWeave<K, T, M, S>> for IndependentWeave<K, T, M, S>
773where
774 K: Hash + Copy + Eq + Ord,
775 T: IndependentContents,
776 S: BuildHasher + Default + Clone,
777{
778 fn from(value: DependentWeave<K, T, M, S>) -> Self {
779 let mut output = Self {
780 active: HashSet::with_capacity_and_hasher(value.nodes.capacity(), S::default()),
781 nodes: {
782 let mut map =
783 HashMap::with_capacity_and_hasher(value.nodes.capacity(), S::default());
784 map.extend(value.nodes.into_iter().map(|(id, mut node)| {
785 node.active = false;
786 (id, node.into())
787 }));
788
789 map
790 },
791 roots: value.roots,
792 bookmarked: value.bookmarked,
793 scratchpad: value.scratchpad,
794 metadata: value.metadata,
795 };
796
797 if let Some(active) = value.active {
798 output.set_active(&active, true);
799 }
800
801 debug_assert!(output.validate(), "Converted weave is malformed");
802
803 output
804 }
805}
806
807#[allow(clippy::panic_in_result_fn, reason = "Should never panic")]
808#[allow(clippy::unreachable, reason = "Should never panic")]
809impl<K, T, M, S> TryFrom<IndependentWeave<K, T, M, S>> for DependentWeave<K, T, M, S>
810where
811 K: Hash + Copy + Eq + Ord,
812 T: IndependentContents,
813 S: BuildHasher + Default + Clone,
814{
815 type Error = IndependentWeave<K, T, M, S>;
816
817 fn try_from(value: IndependentWeave<K, T, M, S>) -> Result<Self, Self::Error> {
818 if value.nodes.iter().all(|(_, node)| node.from.len() < 2) {
819 let mut active = None;
820
821 let output = Self {
822 nodes: {
823 let mut map =
824 HashMap::with_capacity_and_hasher(value.nodes.capacity(), S::default());
825 map.extend(value.nodes.into_iter().map(|(id, mut node)| {
826 node.active =
827 node.active && !node.to.iter().any(|id| value.active.contains(id));
828 if node.active {
829 active = Some(id);
830 }
831
832 node.try_into()
833 .map_or_else(|_| unreachable!(), |node| (id, node))
834 }));
835
836 map
837 },
838 roots: value.roots,
839 active,
840 bookmarked: value.bookmarked,
841 scratchpad: value.scratchpad,
842 metadata: value.metadata,
843 };
844
845 debug_assert!(output.validate(), "Converted weave is malformed");
846
847 Ok(output)
848 } else {
849 Err(value)
850 }
851 }
852}
853
854impl<K, T, M, S> Weave<K, IndependentNode<K, T, S>, T> for IndependentWeave<K, T, M, S>
855where
856 K: Hash + Copy + Eq + Ord,
857 T: IndependentContents,
858 S: BuildHasher + Default + Clone,
859{
860 type Nodes = HashMap<K, IndependentNode<K, T, S>, S>;
861 type Roots = IndexSet<K, S>;
862
863 #[inline]
864 fn len(&self) -> usize {
865 self.nodes.len()
866 }
867 #[inline]
868 fn is_empty(&self) -> bool {
869 self.nodes.is_empty()
870 }
871 #[inline]
872 fn nodes(&self) -> &Self::Nodes {
873 &self.nodes
874 }
875 #[inline]
876 fn roots(&self) -> &Self::Roots {
877 &self.roots
878 }
879 #[inline]
880 fn contains(&self, id: &K) -> bool {
881 self.nodes.contains_key(id)
882 }
883 #[inline]
884 fn contains_active(&self, id: &K) -> bool {
885 self.active.contains(id)
886 }
887 #[inline]
888 fn get(&self, id: &K) -> Option<&IndependentNode<K, T, S>> {
889 self.nodes.get(id)
890 }
891 #[inline]
892 fn get_parents(&self, id: &K) -> Option<&IndexSet<K, S>> {
893 self.nodes.get(id).map(|node| &node.from)
894 }
895 #[inline]
896 fn get_children(&self, id: &K) -> Option<&IndexSet<K, S>> {
897 self.nodes.get(id).map(|node| &node.to)
898 }
899 #[inline]
900 fn get_contents(&self, id: &K) -> Option<&T> {
901 self.nodes.get(id).map(|node| &node.contents)
902 }
903 #[cfg_attr(debug_assertions, contract(
904 ensures(output.len() == self.nodes.len()),
905 ensures(valid_topological_sort(&self.nodes, output)),
906 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
907 ensures(old(self.roots.clone()) == self.roots),
908 ensures(old(self.active.clone()) == self.active),
909 ensures(old(self.bookmarked.clone()) == self.bookmarked),
910 invariant(self.validate())
911 ))]
912 fn get_ordered_identifiers(&mut self, output: &mut Vec<K>) {
913 output.clear();
914 output.reserve(self.nodes.len());
915
916 let guard = self.scratchpad.guard();
917
918 topological_sort(
919 &self.nodes,
920 self.roots.iter().copied(),
921 &mut guard.vec_with_capacity(self.roots.len()),
922 |id| output.push(id),
923 &mut guard.map_with_capacity(self.nodes.len(), S::default()),
924 );
925 }
926 #[cfg_attr(debug_assertions, contract(
927 ensures(lacks_duplicates(output)),
928 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
929 ensures(self.nodes.contains_key(id) || output.is_empty()),
930 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
931 ensures(old(self.roots.clone()) == self.roots),
932 ensures(old(self.active.clone()) == self.active),
933 ensures(old(self.bookmarked.clone()) == self.bookmarked),
934 invariant(self.validate())
935 ))]
936 fn get_ordered_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
937 output.clear();
938
939 if self.nodes.contains_key(id) {
940 let guard = self.scratchpad.guard();
941
942 let mut stack = guard.vec();
943 let mut descendants = guard.set(S::default());
944
945 descendant_subgraph(&self.nodes, *id, &mut stack, &mut descendants);
946
947 topological_sort_subgraph(
948 &self.nodes,
949 &|id| descendants.contains(id),
950 *id,
951 &mut stack,
952 |id| output.push(id),
953 &mut guard.map_with_capacity(descendants.len(), S::default()),
954 );
955 }
956 }
957 #[cfg_attr(debug_assertions, contract(
958 ensures(output.len() == self.active.len()),
959 ensures(output.iter().all(|i| self.active.contains(i))),
960 ensures(lacks_duplicates(output)),
961 ensures(valid_path(&self.nodes, output)),
962 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
963 ensures(old(self.roots.clone()) == self.roots),
964 ensures(old(self.active.clone()) == self.active),
965 ensures(old(self.bookmarked.clone()) == self.bookmarked),
966 invariant(self.validate())
967 ))]
968 fn get_active_path(&mut self, output: &mut Vec<K>) {
969 output.clear();
970 output.reserve(self.active.len());
971
972 let guard = self.scratchpad.guard();
973
974 let mut topological_subgraph = guard.vec_with_capacity(self.active.len());
975 let mut scratchpad_map = guard.map_with_capacity(self.active.len(), S::default());
976
977 for root in self
978 .roots
979 .iter()
980 .filter(|id| self.active.contains(*id))
981 .copied()
982 {
983 topological_sort_subgraph(
984 &self.nodes,
985 &|id| self.active.contains(id),
986 root,
987 &mut guard.vec(),
988 |id| topological_subgraph.push(id),
989 &mut scratchpad_map,
990 );
991 }
992
993 scratchpad_map.clear();
994
995 longest_candidate_path_to_root(
996 &self.nodes,
997 &topological_subgraph,
998 &|id| self.active.contains(id),
999 &mut scratchpad_map,
1000 |id| output.push(id),
1001 );
1002 }
1003 #[cfg_attr(debug_assertions, contract(
1004 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
1005 ensures(self.nodes.contains_key(id) || output.is_empty()),
1006 ensures(lacks_duplicates(output)),
1007 ensures(valid_path(&self.nodes, output)),
1008 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1009 ensures(old(self.roots.clone()) == self.roots),
1010 ensures(old(self.active.clone()) == self.active),
1011 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1012 invariant(self.validate())
1013 ))]
1014 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
1015 output.clear();
1016 if !self.nodes.contains_key(id) {
1017 return;
1018 }
1019
1020 let guard = self.scratchpad.guard();
1021 let mut stack = guard.vec();
1022 let mut ancestors = guard.set(S::default());
1023
1024 ancestor_subgraph(&self.nodes, *id, &mut stack, &mut ancestors);
1025
1026 let mut active_topological_subgraph = guard.vec_with_capacity(self.active.len());
1027 let mut scratchpad_map = guard.map_with_capacity(ancestors.len(), S::default());
1028
1029 for root in self
1030 .roots
1031 .iter()
1032 .filter(|id| self.active.contains(*id))
1033 .copied()
1034 {
1035 topological_sort_subgraph(
1036 &self.nodes,
1037 &|id| self.active.contains(id),
1038 root,
1039 &mut stack,
1040 |id| active_topological_subgraph.push(id),
1041 &mut scratchpad_map,
1042 );
1043 }
1044
1045 scratchpad_map.clear();
1046
1047 let mut reversed_path = guard.vec();
1048
1049 longest_candidate_path_to_root(
1050 &self.nodes,
1051 &active_topological_subgraph,
1052 &|id| self.active.contains(id) && ancestors.contains(id),
1053 &mut scratchpad_map,
1054 |id| reversed_path.push(id),
1055 );
1056
1057 ancestors.clear();
1058 let mut scratchpad_set = ancestors;
1059
1060 let mut scratchpad_map_2 = guard.map(S::default());
1061
1062 if let Some(target) = reversed_path.first().copied() {
1063 shortest_path_to_ancestor(
1064 &self.nodes,
1065 id,
1066 &|node| node.id == target,
1067 &mut stack,
1068 &mut scratchpad_map_2,
1069 &mut scratchpad_set,
1070 output,
1071 );
1072
1073 output.reverse();
1074 output.pop();
1075 output.extend_from_slice(&reversed_path);
1076 } else {
1077 shortest_path_to_ancestor(
1078 &self.nodes,
1079 id,
1080 &|node| node.from.is_empty(),
1081 &mut stack,
1082 &mut scratchpad_map_2,
1083 &mut scratchpad_set,
1084 output,
1085 );
1086
1087 output.reverse();
1088 }
1089 }
1090 #[cfg_attr(debug_assertions, contract(
1091 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
1092 ensures(!ret || old(!self.nodes.contains_key(&node.id))),
1093 ensures(!ret || self.nodes.contains_key(&old(node.id))),
1094 ensures(!ret || old(node.active) == self.active.contains(&old(node.id)) || (!old(node.active) && self.active.contains(&old(node.id)) && old(node.to.iter().any(|c| self.active.contains(c))))),
1095 ensures(!ret || old(node.bookmarked) == self.bookmarked.contains(&old(node.id))),
1096 ensures(!ret || old(!node.from.is_empty()) || self.roots.contains(&old(node.id))),
1097 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1098 ensures(ret || old(self.roots.clone()) == self.roots),
1099 ensures(ret || old(self.active.clone()) == self.active),
1100 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
1101 invariant(self.validate())
1102 ))]
1103 fn insert(&mut self, mut node: IndependentNode<K, T, S>) -> bool {
1104 if self.nodes.contains_key(&node.id)
1105 || !node.validate()
1106 || !node.from.iter().all(|id| self.nodes.contains_key(id))
1107 || !node.to.iter().all(|id| self.nodes.contains_key(id))
1108 {
1109 return false;
1110 }
1111
1112 if !node.to.is_empty() && !node.from.is_empty() {
1113 let guard = self.scratchpad.guard();
1114 let mut ancestors = guard.set_with_capacity(node.from.len(), S::default());
1115
1116 for parent in node.from.iter().copied() {
1117 ancestor_subgraph(&self.nodes, parent, &mut guard.vec(), &mut ancestors);
1118 }
1119
1120 if node.to.iter().any(|child| ancestors.contains(child)) {
1121 return false;
1122 }
1123 }
1124
1125 let root_index = if node.from.is_empty() {
1126 node.to
1127 .iter()
1128 .filter_map(|child| self.roots.get_index_of(child))
1129 .min()
1130 } else {
1131 None
1132 };
1133
1134 let mut detached_root = false;
1135
1136 for child in &node.to {
1137 let child = &self.nodes[child];
1138 if child.from.is_empty() {
1139 if child.active {
1140 node.active = true;
1141 }
1142 detached_root = true;
1143 }
1144 }
1145
1146 if detached_root {
1147 self.roots.retain(|id| !node.to.contains(id));
1148 }
1149
1150 let extends_active = node.active
1151 && node.to.is_empty()
1152 && node.from.iter().map(|id| &self.nodes[id]).any(|parent| {
1153 parent.active && parent.to.iter().all(|child| !self.active.contains(child))
1154 });
1155
1156 if node.from.is_empty() {
1157 if let Some(index) = root_index {
1158 self.roots.shift_insert(index, node.id);
1159 } else {
1160 self.roots.insert(node.id);
1161 }
1162 } else {
1163 for parent in &node.from {
1164 let parent = self.nodes.get_mut(parent).unwrap();
1165 parent.to.insert(node.id);
1166 }
1167 }
1168
1169 for child in &node.to {
1170 let child = self.nodes.get_mut(child).unwrap();
1171 child.from.insert(node.id);
1172 }
1173
1174 if node.bookmarked {
1175 self.bookmarked.insert(node.id);
1176 }
1177
1178 let id = node.id;
1179 let active = node.active;
1180
1181 if !extends_active {
1182 node.active = false;
1183 }
1184
1185 self.nodes.insert(node.id, node);
1186
1187 if extends_active {
1188 self.active.insert(id);
1189 } else if active {
1190 self.update_node_activity_in_place(&id, true);
1191 }
1192
1193 true
1194 }
1195 #[cfg_attr(debug_assertions, contract(
1196 ensures(!ret || value == self.contains_active(id)),
1197 ensures(ret || old(self.active.clone()) == self.active),
1198 ensures(ret == self.nodes.contains_key(id)),
1199 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1200 ensures(old(self.roots.clone()) == self.roots),
1201 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1202 invariant(self.validate())
1203 ))]
1204 fn set_active(&mut self, id: &K, value: bool) -> bool {
1205 self.update_node_activity_in_place(id, value)
1206 }
1207 #[cfg_attr(debug_assertions, contract(
1208 ensures(!self.nodes.contains_key(id)),
1209 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
1210 ensures(ret.as_ref().is_none_or(|node| &node.id == id)),
1211 ensures(ret.is_none() || old(self.nodes.len()) > self.nodes.len()),
1212 ensures(ret.is_none() || old(self.active.len()) >= self.active.len()),
1213 ensures(ret.is_none() || old(self.bookmarked.len()) >= self.bookmarked.len()),
1214 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1215 ensures(ret.is_some() || old(self.roots.clone()) == self.roots),
1216 ensures(ret.is_some() || old(self.active.clone()) == self.active),
1217 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
1218 invariant(self.validate())
1219 ))]
1220 fn remove(&mut self, id: &K) -> Option<IndependentNode<K, T, S>> {
1221 let node = self.nodes.remove(id)?;
1222
1223 if node.from.is_empty() {
1224 self.roots.shift_remove(id);
1225 } else {
1226 for parent in &node.from {
1227 if let Some(parent) = self.nodes.get_mut(parent) {
1228 parent.to.shift_remove(id);
1229 }
1230 }
1231 }
1232
1233 let mut removed_active = node.active;
1234 let mut removed_bookmark = node.bookmarked;
1235
1236 if removed_active {
1237 self.active.remove(id);
1238 }
1239
1240 if node.to.is_empty() {
1241 if removed_bookmark {
1242 self.bookmarked.shift_remove(id);
1243 }
1244 if removed_active {
1245 self.fix_orphaned_activations();
1246 }
1247 return Some(node);
1248 }
1249
1250 {
1251 let guard = self.scratchpad.guard();
1252 let mut stack = guard.vec();
1253 let mut removed = guard.vec();
1254 let mut remaining_parents = guard.map_with_capacity(node.to.len(), S::default());
1255
1256 removed.push(*id);
1257
1258 for child in node.to.iter().rev().copied() {
1259 let remaining = remaining_parents
1260 .entry(child)
1261 .or_insert_with(|| self.nodes[&child].from.len());
1262 *remaining = remaining.strict_sub(1);
1263
1264 if *remaining == 0 {
1265 stack.push(child);
1266 }
1267 }
1268
1269 while let Some(id) = stack.pop() {
1270 let node = self.nodes.remove(&id).unwrap();
1271 removed.push(id);
1272
1273 removed_bookmark |= node.bookmarked;
1274 if node.active {
1275 self.active.remove(&id);
1276 removed_active = true;
1277 }
1278
1279 for child in node.to.iter().rev().copied() {
1280 let remaining = remaining_parents
1281 .entry(child)
1282 .or_insert_with(|| self.nodes[&child].from.len());
1283 *remaining = remaining.strict_sub(1);
1284
1285 if *remaining == 0 {
1286 stack.push(child);
1287 }
1288 }
1289 }
1290
1291 if removed.len() == 1 {
1292 for (child, _) in remaining_parents {
1293 if let Some(child) = self.nodes.get_mut(&child) {
1294 child.from.shift_remove(id);
1295 }
1296 }
1297 if removed_bookmark {
1298 self.bookmarked.shift_remove(id);
1299 }
1300 } else {
1301 let mut removed_set = guard.set_with_capacity(removed.len(), S::default());
1302 removed_set.extend(removed);
1303
1304 for (child, remaining) in remaining_parents {
1305 if remaining > 0
1306 && let Some(child) = self.nodes.get_mut(&child)
1307 {
1308 child.from.retain(|parent| !removed_set.contains(parent));
1309 }
1310 }
1311
1312 if removed_bookmark {
1313 self.bookmarked.retain(|id| !removed_set.contains(id));
1314 }
1315 }
1316 }
1317
1318 if removed_active {
1319 self.fix_orphaned_activations();
1320 }
1321
1322 Some(node)
1323 }
1324 #[cfg_attr(debug_assertions, contract(
1325 ensures(!self.nodes.contains_key(id)),
1326 ensures(ret == old(self.nodes.contains_key(id))),
1327 ensures(!ret || old(self.nodes.len()) > self.nodes.len()),
1328 ensures(!ret || old(self.active.len()) >= self.active.len()),
1329 ensures(!ret || old(self.bookmarked.len()) >= self.bookmarked.len()),
1330 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1331 ensures(ret || old(self.roots.clone()) == self.roots),
1332 ensures(ret || old(self.active.clone()) == self.active),
1333 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
1334 invariant(self.validate())
1335 ))]
1336 fn remove_tracked(
1337 &mut self,
1338 id: &K,
1339 mut on_removal: impl FnMut(IndependentNode<K, T, S>),
1340 ) -> bool {
1341 let Some(node) = self.nodes.remove(id) else {
1342 return false;
1343 };
1344
1345 if node.from.is_empty() {
1346 self.roots.shift_remove(id);
1347 } else {
1348 for parent in &node.from {
1349 if let Some(parent) = self.nodes.get_mut(parent) {
1350 parent.to.shift_remove(id);
1351 }
1352 }
1353 }
1354
1355 let mut removed_active = node.active;
1356 let mut removed_bookmark = node.bookmarked;
1357
1358 if removed_active {
1359 self.active.remove(id);
1360 }
1361
1362 if node.to.is_empty() {
1363 if removed_bookmark {
1364 self.bookmarked.shift_remove(id);
1365 }
1366 if removed_active {
1367 self.fix_orphaned_activations();
1368 }
1369 on_removal(node);
1370 return true;
1371 }
1372
1373 {
1374 let guard = self.scratchpad.guard();
1375 let mut stack = guard.vec();
1376 let mut removed = guard.vec();
1377 let mut remaining_parents = guard.map_with_capacity(node.to.len(), S::default());
1378
1379 removed.push(*id);
1380
1381 for child in node.to.iter().rev().copied() {
1382 let remaining = remaining_parents
1383 .entry(child)
1384 .or_insert_with(|| self.nodes[&child].from.len());
1385 *remaining = remaining.strict_sub(1);
1386
1387 if *remaining == 0 {
1388 stack.push(child);
1389 }
1390 }
1391
1392 on_removal(node);
1393
1394 while let Some(id) = stack.pop() {
1395 let node = self.nodes.remove(&id).unwrap();
1396 removed.push(id);
1397
1398 removed_bookmark |= node.bookmarked;
1399 if node.active {
1400 self.active.remove(&id);
1401 removed_active = true;
1402 }
1403
1404 for child in node.to.iter().rev().copied() {
1405 let remaining = remaining_parents
1406 .entry(child)
1407 .or_insert_with(|| self.nodes[&child].from.len());
1408 *remaining = remaining.strict_sub(1);
1409
1410 if *remaining == 0 {
1411 stack.push(child);
1412 }
1413 }
1414
1415 on_removal(node);
1416 }
1417
1418 if removed.len() == 1 {
1419 for (child, _) in remaining_parents {
1420 if let Some(child) = self.nodes.get_mut(&child) {
1421 child.from.shift_remove(id);
1422 }
1423 }
1424 if removed_bookmark {
1425 self.bookmarked.shift_remove(id);
1426 }
1427 } else {
1428 let mut removed_set = guard.set_with_capacity(removed.len(), S::default());
1429 removed_set.extend(removed);
1430
1431 for (child, remaining) in remaining_parents {
1432 if remaining > 0
1433 && let Some(child) = self.nodes.get_mut(&child)
1434 {
1435 child.from.retain(|parent| !removed_set.contains(parent));
1436 }
1437 }
1438
1439 if removed_bookmark {
1440 self.bookmarked.retain(|id| !removed_set.contains(id));
1441 }
1442 }
1443 }
1444
1445 if removed_active {
1446 self.fix_orphaned_activations();
1447 }
1448
1449 true
1450 }
1451 #[cfg_attr(debug_assertions, contract(
1452 ensures(self.nodes.is_empty()),
1453 ensures(self.validate())
1454 ))]
1455 fn clear(&mut self) {
1456 self.nodes.clear();
1457 self.roots.clear();
1458 self.active.clear();
1459 self.bookmarked.clear();
1460 }
1461}
1462
1463impl<K, T, M, S> IndependentWeave<K, T, M, S>
1464where
1465 K: Hash + Copy + Eq + Ord,
1466 T: IndependentContents,
1467 S: BuildHasher + Default + Clone,
1468{
1469 pub fn validate(&self) -> bool {
1471 self.roots
1472 .iter()
1473 .all(move |value| self.nodes.contains_key(value))
1474 && self
1475 .active
1476 .iter()
1477 .all(move |value| self.nodes.contains_key(value))
1478 && self
1479 .bookmarked
1480 .iter()
1481 .all(move |value| self.nodes.contains_key(value))
1482 && self.nodes.iter().all(|(key, value)| {
1483 value.validate()
1484 && value.id == *key
1485 && value
1486 .from
1487 .iter()
1488 .all(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
1489 && value
1490 .to
1491 .iter()
1492 .all(|v| self.nodes.get(v).is_some_and(|p| p.from.contains(key)))
1493 && value.from.is_empty() == self.roots.contains(key)
1494 && value.active == self.active.contains(key)
1495 && value.bookmarked == self.bookmarked.contains(key)
1496 })
1497 && valid_topology(&self.nodes, &self.roots, &self.active)
1498 }
1499}
1500
1501impl<K, T, M, S> MetadataWeave<K, IndependentNode<K, T, S>, T, M> for IndependentWeave<K, T, M, S>
1502where
1503 K: Hash + Copy + Eq + Ord,
1504 T: IndependentContents,
1505 S: BuildHasher + Default + Clone,
1506{
1507 #[inline]
1508 fn metadata(&self) -> &M {
1509 &self.metadata
1510 }
1511 #[cfg_attr(debug_assertions, contract(
1512 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1513 ensures(old(self.roots.clone()) == self.roots),
1514 ensures(old(self.active.clone()) == self.active),
1515 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1516 invariant(self.validate())
1517 ))]
1518 #[inline]
1519 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
1520 callback(&mut self.metadata)
1521 }
1522}
1523
1524impl<K, T, M, S> BookmarkableWeave<K, IndependentNode<K, T, S>, T> for IndependentWeave<K, T, M, S>
1525where
1526 K: Hash + Copy + Eq + Ord,
1527 T: IndependentContents,
1528 S: BuildHasher + Default + Clone,
1529{
1530 type Bookmarks = IndexSet<K, S>;
1531
1532 #[inline]
1533 fn bookmarks(&self) -> &Self::Bookmarks {
1534 &self.bookmarked
1535 }
1536 #[inline]
1537 fn contains_bookmark(&self, id: &K) -> bool {
1538 self.bookmarked.contains(id)
1539 }
1540 #[cfg_attr(debug_assertions, contract(
1541 ensures(!ret || value == self.bookmarked.contains(id)),
1542 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
1543 ensures(ret == self.nodes.contains_key(id)),
1544 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1545 ensures(old(self.roots.clone()) == self.roots),
1546 ensures(old(self.active.clone()) == self.active),
1547 invariant(self.validate())
1548 ))]
1549 fn set_bookmarked(&mut self, id: &K, value: bool) -> bool {
1550 match self.nodes.get_mut(id) {
1551 Some(node) => {
1552 node.bookmarked = value;
1553 if value {
1554 self.bookmarked.insert(node.id);
1555 } else {
1556 self.bookmarked.shift_remove(id);
1557 }
1558
1559 true
1560 }
1561 None => false,
1562 }
1563 }
1564}
1565
1566impl<K, T, M, S> SortableWeave<K, IndependentNode<K, T, S>, T> for IndependentWeave<K, T, M, S>
1567where
1568 K: Hash + Copy + Eq + Ord,
1569 T: IndependentContents,
1570 S: BuildHasher + Default + Clone,
1571{
1572 #[cfg_attr(debug_assertions, contract(
1573 ensures(ret == self.nodes.contains_key(id)),
1574 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
1575 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1576 ensures(old(self.roots.clone()) == self.roots),
1577 ensures(old(self.active.clone()) == self.active),
1578 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1579 invariant(self.validate())
1580 ))]
1581 fn sort_children_by(
1582 &mut self,
1583 id: &K,
1584 mut cmp: impl FnMut(&IndependentNode<K, T, S>, &IndependentNode<K, T, S>) -> Ordering,
1585 ) -> bool {
1586 if let Some(node) = self.nodes.get_mut(id) {
1587 let mut set = mem::take(&mut node.to);
1588
1589 {
1590 let guard = self.scratchpad.guard();
1591 let mut nodes = guard
1592 .arena()
1593 .alloc_iter_exact(set.drain(..).map(|id| &self.nodes[&id]));
1594 nodes.sort_by(|a, b| cmp(*a, *b));
1595
1596 set.extend(nodes.into_iter().map(|node| node.id));
1597 }
1598
1599 self.nodes.get_mut(id).unwrap().to = set;
1600
1601 true
1602 } else {
1603 false
1604 }
1605 }
1606 #[cfg_attr(debug_assertions, contract(
1607 ensures(ret == self.nodes.contains_key(id)),
1608 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
1609 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1610 ensures(old(self.roots.clone()) == self.roots),
1611 ensures(old(self.active.clone()) == self.active),
1612 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1613 invariant(self.validate())
1614 ))]
1615 fn sort_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
1616 if let Some(node) = self.nodes.get_mut(id) {
1617 node.to.sort_by(cmp);
1618
1619 true
1620 } else {
1621 false
1622 }
1623 }
1624 #[cfg_attr(debug_assertions, contract(
1625 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1626 ensures(old(self.roots.clone()) == self.roots),
1627 ensures(old(self.active.clone()) == self.active),
1628 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1629 invariant(self.validate())
1630 ))]
1631 fn sort_roots_by(
1632 &mut self,
1633 mut cmp: impl FnMut(&IndependentNode<K, T, S>, &IndependentNode<K, T, S>) -> Ordering,
1634 ) {
1635 let guard = self.scratchpad.guard();
1636
1637 let mut nodes = guard
1638 .arena()
1639 .alloc_iter_exact(self.roots.iter().map(|id| &self.nodes[id]));
1640 nodes.sort_by(|a, b| cmp(*a, *b));
1641
1642 self.roots.clear();
1643 self.roots.extend(nodes.into_iter().map(|node| node.id));
1644 }
1645 #[cfg_attr(debug_assertions, contract(
1646 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1647 ensures(old(self.roots.clone()) == self.roots),
1648 ensures(old(self.active.clone()) == self.active),
1649 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1650 invariant(self.validate())
1651 ))]
1652 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1653 self.roots.sort_by(cmp);
1654 }
1655}
1656
1657impl<K, T, M, S> SortableBookmarkableWeave<K, IndependentNode<K, T, S>, T>
1658 for IndependentWeave<K, T, M, S>
1659where
1660 K: Hash + Copy + Eq + Ord,
1661 T: IndependentContents,
1662 S: BuildHasher + Default + Clone,
1663{
1664 #[cfg_attr(debug_assertions, contract(
1665 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1666 ensures(old(self.roots.clone()) == self.roots),
1667 ensures(old(self.active.clone()) == self.active),
1668 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1669 invariant(self.validate())
1670 ))]
1671 fn sort_bookmarks_by(
1672 &mut self,
1673 mut cmp: impl FnMut(&IndependentNode<K, T, S>, &IndependentNode<K, T, S>) -> Ordering,
1674 ) {
1675 self.bookmarked
1676 .sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
1677 }
1678 #[cfg_attr(debug_assertions, contract(
1679 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1680 ensures(old(self.roots.clone()) == self.roots),
1681 ensures(old(self.active.clone()) == self.active),
1682 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1683 invariant(self.validate())
1684 ))]
1685 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
1686 self.bookmarked.sort_by(cmp);
1687 }
1688}
1689
1690impl<K, T, M, S> ActivePathWeave<K, IndependentNode<K, T, S>, T> for IndependentWeave<K, T, M, S>
1691where
1692 K: Hash + Copy + Eq + Ord,
1693 T: IndependentContents,
1694 S: BuildHasher + Default + Clone,
1695{
1696 type Active = HashSet<K, S>;
1697
1698 #[inline]
1699 fn active(&self) -> &Self::Active {
1700 &self.active
1701 }
1702 #[cfg_attr(debug_assertions, contract(
1703 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1704 ensures(old(self.roots.clone()) == self.roots),
1705 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1706 invariant(self.validate())
1707 ))]
1708 fn set_active_path(&mut self, active: impl Iterator<Item = K>) {
1709 self.active.iter().for_each(|active| {
1710 self.nodes.get_mut(active).unwrap().active = false;
1711 });
1712 self.active.clear();
1713 self.active
1714 .extend(active.filter(|id| self.nodes.contains_key(id)));
1715 self.active.iter().for_each(|active| {
1716 self.nodes.get_mut(active).unwrap().active = true;
1717 });
1718 self.fix_orphaned_activations();
1719 }
1720}
1721
1722impl<K, T, M, S> DiscreteWeave<K, IndependentNode<K, T, S>, T> for IndependentWeave<K, T, M, S>
1723where
1724 K: Hash + Copy + Eq + Ord,
1725 T: IndependentContents + DiscreteContents,
1726 S: BuildHasher + Default + Clone,
1727{
1728 #[cfg_attr(debug_assertions, contract(
1729 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
1730 ensures(!ret || self.nodes.contains_key(id)),
1731 ensures(!ret || self.nodes.contains_key(&new_id)),
1732 ensures(!ret || old(!self.nodes.contains_key(&new_id))),
1733 ensures(!ret || self.nodes[id].to.contains(&new_id) && self.nodes[id].to.len() == 1),
1734 ensures(!ret || self.nodes[&new_id].from.contains(id) && self.nodes[&new_id].from.len() == 1),
1735 ensures(!ret || old(self.nodes.get(id).map(|n| n.to.clone())).unwrap() == self.nodes[&new_id].to),
1736 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1737 ensures(ret || old(self.active.clone()) == self.active),
1738 ensures(old(self.roots.clone()) == self.roots),
1739 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1740 invariant(self.validate())
1741 ))]
1742 fn split(&mut self, id: &K, at: usize, new_id: K) -> bool {
1743 if self.nodes.contains_key(&new_id) || *id == new_id {
1744 return false;
1745 }
1746
1747 if let Some(mut node) = self.nodes.remove(id) {
1748 match node.contents.split(at) {
1749 DiscreteContentResult::Two(left, right) => {
1750 let left_node = IndependentNode {
1751 id: node.id,
1752 from: node.from,
1753 to: IndexSet::from_iter([new_id]),
1754 active: node.active,
1755 bookmarked: node.bookmarked,
1756 contents: left,
1757 };
1758
1759 node.from = IndexSet::from_iter([node.id]);
1760 node.id = new_id;
1761 node.contents = right;
1762 node.active = false;
1763 node.bookmarked = false;
1764
1765 for child in &node.to {
1766 let child = self.nodes.get_mut(child).unwrap();
1767 let index = child.from.get_index_of(&left_node.id).unwrap();
1768
1769 assert!(
1770 child.from.replace_index(index, node.id).is_ok(),
1771 "Should be unreachable"
1772 );
1773
1774 if child.active && left_node.active {
1775 node.active = true;
1776 self.active.insert(node.id);
1777 }
1778 }
1779
1780 self.nodes.insert(left_node.id, left_node);
1781 self.nodes.insert(node.id, node);
1782
1783 true
1784 }
1785 DiscreteContentResult::One(content) => {
1786 node.contents = content;
1787 self.nodes.insert(node.id, node);
1788 false
1789 }
1790 }
1791 } else {
1792 false
1793 }
1794 }
1795 #[cfg_attr(debug_assertions, contract(
1796 ensures(ret.is_none() || old(self.nodes.len()) - 1 == self.nodes.len()),
1797 ensures(ret.is_none() || !self.nodes.contains_key(id)),
1798 ensures(ret.is_none() || old(self.nodes.contains_key(id))),
1799 ensures(ret.is_none() || !old(self.contains_active(id)) || old(self.contains_active(id)) && self.contains_active(&ret.unwrap())),
1800 ensures(ret.is_none() || old(self.nodes.get(id).and_then(|n| n.from.first()).and_then(|p| self.nodes.get(p)).map(|p| p.active)).unwrap() == self.nodes[&ret.unwrap()].active),
1801 ensures(ret.is_none() || old(self.nodes.get(id).and_then(|n| n.from.first()).and_then(|p| self.nodes.get(p)).map(|p| p.from.clone())).unwrap() == self.nodes[&ret.unwrap()].from),
1802 ensures(ret.is_none() || old(self.nodes.get(id).map(|node| node.to.clone())).unwrap() == self.nodes[&ret.unwrap()].to),
1803 ensures(ret.is_none() || old(self.nodes.get(id).map(|node| node.from.len() == 1)).unwrap()),
1804 ensures(ret.is_none() || ret.unwrap() == old(self.nodes.get(id).and_then(|node| node.from.first().copied())).unwrap()),
1805 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1806 ensures(ret.is_some() || old(self.active.clone()) == self.active),
1807 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
1808 ensures(old(self.roots.clone()) == self.roots),
1809 invariant(self.validate())
1810 ))]
1811 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
1812 if let Some(mut node) = self.nodes.remove(id) {
1813 if node.from.len() != 1 {
1814 self.nodes.insert(node.id, node);
1815 return None;
1816 }
1817
1818 if let Some(mut parent) = node.from.first().and_then(|id| self.nodes.remove(id)) {
1819 if parent.to.len() > 1 {
1820 self.nodes.insert(parent.id, parent);
1821 self.nodes.insert(node.id, node);
1822 return None;
1823 }
1824
1825 match parent.contents.merge(node.contents) {
1826 DiscreteContentResult::Two(left, right) => {
1827 parent.contents = left;
1828 node.contents = right;
1829 self.nodes.insert(parent.id, parent);
1830 self.nodes.insert(node.id, node);
1831 None
1832 }
1833 DiscreteContentResult::One(content) => {
1834 parent.contents = content;
1835 parent.to = node.to;
1836
1837 for child in &parent.to {
1838 let child = self.nodes.get_mut(child).unwrap();
1839 let index = child.from.get_index_of(&node.id).unwrap();
1840
1841 assert!(
1842 child.from.replace_index(index, parent.id).is_ok(),
1843 "Should be unreachable"
1844 );
1845 }
1846
1847 let parent_id = parent.id;
1848
1849 if node.bookmarked && !parent.bookmarked {
1850 parent.bookmarked = true;
1851 assert!(
1852 self.bookmarked
1853 .replace_index(
1854 self.bookmarked.get_index_of(&node.id).unwrap(),
1855 parent.id,
1856 )
1857 .is_ok(),
1858 "Should be unreachable"
1859 );
1860 } else if node.bookmarked {
1861 self.bookmarked.shift_remove(&node.id);
1862 }
1863
1864 self.nodes.insert(parent.id, parent);
1865 self.active.remove(&node.id);
1866
1867 Some(parent_id)
1868 }
1869 }
1870 } else {
1871 self.nodes.insert(node.id, node);
1872 None
1873 }
1874 } else {
1875 None
1876 }
1877 }
1878}
1879
1880impl<K, T, M, S> SemiIndependentWeave<K, IndependentNode<K, T, S>, T>
1881 for IndependentWeave<K, T, M, S>
1882where
1883 K: Hash + Copy + Eq + Ord,
1884 T: IndependentContents,
1885 S: BuildHasher + Default + Clone,
1886{
1887 #[cfg_attr(debug_assertions, contract(
1888 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
1889 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1890 ensures(old(self.roots.clone()) == self.roots),
1891 ensures(old(self.active.clone()) == self.active),
1892 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1893 invariant(self.validate())
1894 ))]
1895 #[inline]
1896 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1897 self.nodes
1898 .get_mut(id)
1899 .map(|node| callback(&mut node.contents))
1900 }
1901}
1902
1903impl<K, T, M, S> crate::IndependentWeave<K, IndependentNode<K, T, S>, T>
1904 for IndependentWeave<K, T, M, S>
1905where
1906 K: Hash + Copy + Eq + Ord,
1907 T: IndependentContents,
1908 S: BuildHasher + Default + Clone,
1909{
1910 #[cfg_attr(debug_assertions, contract(
1911 ensures(!ret || self.nodes[id].from.iter().copied().collect::<HashSet<_>>() == new_parents.iter().copied().collect::<HashSet<_>>()),
1912 ensures(ret || old(self.nodes.get(id).map(|node| node.from.clone())).as_ref() == self.nodes.get(id).map(|node| &node.from)),
1913 ensures(ret || old(self.roots.clone()) == self.roots),
1914 ensures(ret || old(self.active.clone()) == self.active),
1915 ensures(old(self.nodes.get(id).map(|node| node.to.clone())).as_ref() == self.nodes.get(id).map(|node| &node.to)),
1916 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1917 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1918 ensures(old(self.active.contains(id)) == self.active.contains(id)),
1919 invariant(self.validate())
1920 ))]
1921 fn move_to(&mut self, id: &K, new_parents: &[K]) -> bool {
1922 if new_parents
1923 .iter()
1924 .any(|new_parent| !self.nodes.contains_key(new_parent))
1925 {
1926 return false;
1927 }
1928
1929 if let Some(node) = self.nodes.get(id)
1930 && !node.to.is_empty()
1931 && !new_parents.is_empty()
1932 {
1933 let guard = self.scratchpad.guard();
1934 let mut descendants = guard.set_with_capacity(node.to.len(), S::default());
1935
1936 for child in node.to.iter().copied() {
1937 descendant_subgraph(&self.nodes, child, &mut guard.vec(), &mut descendants);
1938 }
1939
1940 if new_parents
1941 .iter()
1942 .any(|new_parent| descendants.contains(new_parent))
1943 {
1944 return false;
1945 }
1946 }
1947
1948 let new_parents: IndexSet<K, S> = new_parents.iter().copied().collect();
1949
1950 if new_parents.contains(id) {
1951 return false;
1952 }
1953
1954 if let Some(node) = self.nodes.get_mut(id) {
1955 let old_parents = mem::take(&mut node.from);
1956
1957 for old_parent in &old_parents {
1958 if !new_parents.contains(old_parent)
1959 && let Some(old_parent) = self.nodes.get_mut(old_parent)
1960 {
1961 old_parent.to.shift_remove(id);
1962 }
1963 }
1964
1965 for new_parent in &new_parents {
1966 if !old_parents.contains(new_parent)
1967 && let Some(new_parent) = self.nodes.get_mut(new_parent)
1968 {
1969 new_parent.to.insert(*id);
1970 }
1971 }
1972 } else {
1973 return false;
1974 }
1975
1976 let node = self.nodes.get_mut(id).unwrap();
1977 node.from = new_parents;
1978
1979 if node.from.is_empty() {
1980 self.roots.insert(node.id);
1981 } else {
1982 self.roots.shift_remove(&node.id);
1983 }
1984
1985 if node.active {
1986 node.active = false;
1987 self.active.remove(id);
1988 self.update_node_activity_in_place(id, true);
1989 }
1990
1991 true
1992 }
1993}
1994
1995#[cfg(feature = "rkyv")]
1996impl<K, T, S> ArchivedIndependentNode<K, T, S>
1997where
1998 K: Archive + Hash + Copy + Eq + Ord,
1999 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2000 T: Archive + IndependentContents,
2001 S: BuildHasher + Default + Clone,
2002{
2003 #[inline]
2004 fn validate(&self) -> bool {
2005 (if self.from.len() <= self.to.len() {
2006 self.from.iter().all(|v| !self.to.contains(v))
2007 } else {
2008 self.to.iter().all(|v| !self.from.contains(v))
2009 }) && !self.from.contains(&self.id)
2010 && !self.to.contains(&self.id)
2011 }
2012}
2013
2014#[cfg(feature = "rkyv")]
2015impl<K, T, S> Node<K::Archived, T::Archived> for ArchivedIndependentNode<K, T, S>
2016where
2017 K: Archive + Hash + Copy + Eq + Ord,
2018 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2019 T: Archive + IndependentContents,
2020 S: BuildHasher + Default + Clone,
2021{
2022 type From = ArchivedIndexSet<K::Archived>;
2023 type To = ArchivedIndexSet<K::Archived>;
2024
2025 #[inline]
2026 fn id(&self) -> K::Archived {
2027 self.id
2028 }
2029 #[inline]
2030 fn from(&self) -> &Self::From {
2031 &self.from
2032 }
2033 #[inline]
2034 fn to(&self) -> &Self::To {
2035 &self.to
2036 }
2037 #[inline]
2038 fn is_active(&self) -> bool {
2039 self.active
2040 }
2041 #[inline]
2042 fn contents(&self) -> &T::Archived {
2043 &self.contents
2044 }
2045}
2046
2047#[cfg(feature = "rkyv")]
2048impl<K, T, M, S> ArchivedIndependentWeave<K, T, M, S>
2049where
2050 K: Archive + Hash + Copy + Eq + Ord,
2051 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2052 T: Archive + IndependentContents,
2053 M: Archive,
2054 S: BuildHasher + Default + Clone,
2055{
2056 fn validate(&self) -> bool {
2057 self.roots
2058 .iter()
2059 .all(move |value| self.nodes.contains_key(value))
2060 && self
2061 .active
2062 .iter()
2063 .all(move |value| self.nodes.contains_key(value))
2064 && self
2065 .bookmarked
2066 .iter()
2067 .all(move |value| self.nodes.contains_key(value))
2068 && self.nodes.iter().all(|(key, value)| {
2069 value.validate()
2070 && value.id == *key
2071 && value
2072 .from
2073 .iter()
2074 .all(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
2075 && value
2076 .to
2077 .iter()
2078 .all(|v| self.nodes.get(v).is_some_and(|p| p.from.contains(key)))
2079 && value.from.is_empty() == self.roots.contains(key)
2080 && value.active == self.active.contains(key)
2081 && value.bookmarked == self.bookmarked.contains(key)
2082 })
2083 && archived_valid_topology(&self.nodes, &self.roots, &self.active)
2084 }
2085}
2086
2087#[cfg(feature = "rkyv")]
2088unsafe impl<K, T, M, S, C> Verify<C> for ArchivedIndependentWeave<K, T, M, S>
2091where
2092 K: Archive + Hash + Copy + Eq + Ord,
2093 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2094 T: Archive + IndependentContents,
2095 M: Archive,
2096 S: BuildHasher + Default + Clone,
2097 C: Fallible + ?Sized,
2098 C::Error: Source,
2099{
2100 fn verify(&self, _context: &mut C) -> Result<(), C::Error> {
2101 if !self.validate() {
2102 fail!(ValidationError)
2103 }
2104
2105 Ok(())
2106 }
2107}
2108
2109#[cfg(feature = "rkyv")]
2110impl<K, T, M, S> ImmutableWeave<K::Archived, ArchivedIndependentNode<K, T, S>, T::Archived>
2111 for ArchivedIndependentWeave<K, T, M, S>
2112where
2113 K: Archive + Hash + Copy + Eq + Ord,
2114 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2115 T: Archive + IndependentContents,
2116 M: Archive,
2117 S: BuildHasher + Default + Clone,
2118{
2119 type Nodes = ArchivedHashMap<K::Archived, ArchivedIndependentNode<K, T, S>>;
2120 type Roots = ArchivedIndexSet<K::Archived>;
2121
2122 #[inline]
2123 fn len(&self) -> usize {
2124 self.nodes.len()
2125 }
2126 #[inline]
2127 fn is_empty(&self) -> bool {
2128 self.nodes.is_empty()
2129 }
2130 #[inline]
2131 fn nodes(&self) -> &Self::Nodes {
2132 &self.nodes
2133 }
2134 #[inline]
2135 fn roots(&self) -> &Self::Roots {
2136 &self.roots
2137 }
2138 #[inline]
2139 fn contains(&self, id: &K::Archived) -> bool {
2140 self.nodes.contains_key(id)
2141 }
2142 #[inline]
2143 fn contains_active(&self, id: &K::Archived) -> bool {
2144 self.active.contains(id)
2145 }
2146 #[inline]
2147 fn get(&self, id: &K::Archived) -> Option<&ArchivedIndependentNode<K, T, S>> {
2148 self.nodes.get(id)
2149 }
2150 #[inline]
2151 fn get_parents(&self, id: &K::Archived) -> Option<&ArchivedIndexSet<K::Archived>> {
2152 self.nodes.get(id).map(|node| &node.from)
2153 }
2154 #[inline]
2155 fn get_children(&self, id: &K::Archived) -> Option<&ArchivedIndexSet<K::Archived>> {
2156 self.nodes.get(id).map(|node| &node.to)
2157 }
2158 #[inline]
2159 fn get_contents(&self, id: &K::Archived) -> Option<&T::Archived> {
2160 self.nodes.get(id).map(|node| &node.contents)
2161 }
2162 fn get_ordered_identifiers(&self, output: &mut Vec<K::Archived>) {
2163 output.clear();
2164 output.reserve(self.nodes.len());
2165
2166 let mut scratchpad = Scratchpad::new();
2167 let guard = scratchpad.guard();
2168
2169 archived_topological_sort(
2170 &self.nodes,
2171 &self.roots,
2172 &mut guard.vec_with_capacity(self.roots.len()),
2173 |id| output.push(id),
2174 &mut guard.map_with_capacity(self.nodes.len(), S::default()),
2175 );
2176 }
2177 fn get_ordered_identifiers_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
2178 output.clear();
2179
2180 if self.nodes.contains_key(id) {
2181 let mut scratchpad = Scratchpad::new();
2182 let guard = scratchpad.guard();
2183
2184 let mut stack = guard.vec();
2185 let mut descendants = guard.set(S::default());
2186
2187 archived_descendant_subgraph(&self.nodes, *id, &mut stack, &mut descendants);
2188
2189 archived_topological_sort_subgraph(
2190 &self.nodes,
2191 &|id| descendants.contains(id),
2192 *id,
2193 &mut stack,
2194 |id| output.push(id),
2195 &mut guard.map_with_capacity(descendants.len(), S::default()),
2196 );
2197 }
2198 }
2199 fn get_active_path(&self, output: &mut Vec<K::Archived>) {
2200 output.clear();
2201 output.reserve(self.active.len());
2202
2203 let mut scratchpad = Scratchpad::new();
2204 let guard = scratchpad.guard();
2205
2206 let mut topological_subgraph = guard.vec_with_capacity(self.active.len());
2207 let mut scratchpad_map = guard.map_with_capacity(self.active.len(), S::default());
2208
2209 for root in self
2210 .roots
2211 .iter()
2212 .filter(|id| self.active.contains(*id))
2213 .copied()
2214 {
2215 archived_topological_sort_subgraph(
2216 &self.nodes,
2217 &|id| self.active.contains(id),
2218 root,
2219 &mut guard.vec(),
2220 |id| topological_subgraph.push(id),
2221 &mut scratchpad_map,
2222 );
2223 }
2224
2225 scratchpad_map.clear();
2226
2227 archived_longest_candidate_path_to_root(
2228 &self.nodes,
2229 &topological_subgraph,
2230 &|id| self.active.contains(id),
2231 &mut scratchpad_map,
2232 |id| output.push(id),
2233 );
2234 }
2235 fn get_path_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
2236 output.clear();
2237 if !self.nodes.contains_key(id) {
2238 return;
2239 }
2240
2241 let mut scratchpad = Scratchpad::new();
2242 let guard = scratchpad.guard();
2243 let mut stack = guard.vec();
2244 let mut ancestors = guard.set(S::default());
2245
2246 archived_ancestor_subgraph(&self.nodes, *id, &mut stack, &mut ancestors);
2247
2248 let mut active_topological_subgraph = guard.vec_with_capacity(self.active.len());
2249 let mut scratchpad_map = guard.map_with_capacity(ancestors.len(), S::default());
2250
2251 for root in self
2252 .roots
2253 .iter()
2254 .filter(|id| self.active.contains(*id))
2255 .copied()
2256 {
2257 archived_topological_sort_subgraph(
2258 &self.nodes,
2259 &|id| self.active.contains(id),
2260 root,
2261 &mut stack,
2262 |id| active_topological_subgraph.push(id),
2263 &mut scratchpad_map,
2264 );
2265 }
2266
2267 scratchpad_map.clear();
2268
2269 let mut reversed_path = guard.vec();
2270
2271 archived_longest_candidate_path_to_root(
2272 &self.nodes,
2273 &active_topological_subgraph,
2274 &|id| self.active.contains(id) && ancestors.contains(id),
2275 &mut scratchpad_map,
2276 |id| reversed_path.push(id),
2277 );
2278
2279 ancestors.clear();
2280 let mut scratchpad_set = ancestors;
2281
2282 let mut scratchpad_map_2 = guard.map(S::default());
2283
2284 if let Some(target) = reversed_path.first().copied() {
2285 archived_shortest_path_to_ancestor(
2286 &self.nodes,
2287 id,
2288 &|node| node.id == target,
2289 &mut stack,
2290 &mut scratchpad_map_2,
2291 &mut scratchpad_set,
2292 output,
2293 );
2294
2295 output.reverse();
2296 output.pop();
2297 output.extend_from_slice(&reversed_path);
2298 } else {
2299 archived_shortest_path_to_ancestor(
2300 &self.nodes,
2301 id,
2302 &|node| node.from.is_empty(),
2303 &mut stack,
2304 &mut scratchpad_map_2,
2305 &mut scratchpad_set,
2306 output,
2307 );
2308
2309 output.reverse();
2310 }
2311 }
2312}
2313
2314#[cfg(feature = "rkyv")]
2315impl<K, T, M, S>
2316 ImmutableMetadataWeave<K::Archived, ArchivedIndependentNode<K, T, S>, T::Archived, M::Archived>
2317 for ArchivedIndependentWeave<K, T, M, S>
2318where
2319 K: Archive + Hash + Copy + Eq + Ord,
2320 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2321 T: Archive + IndependentContents,
2322 M: Archive,
2323 S: BuildHasher + Default + Clone,
2324{
2325 #[inline]
2326 fn metadata(&self) -> &M::Archived {
2327 &self.metadata
2328 }
2329}
2330
2331#[cfg(feature = "rkyv")]
2332impl<K, T, M, S>
2333 ImmutableBookmarkableWeave<K::Archived, ArchivedIndependentNode<K, T, S>, T::Archived>
2334 for ArchivedIndependentWeave<K, T, M, S>
2335where
2336 K: Archive + Hash + Copy + Eq + Ord,
2337 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2338 T: Archive + IndependentContents,
2339 M: Archive,
2340 S: BuildHasher + Default + Clone,
2341{
2342 type Bookmarks = ArchivedIndexSet<K::Archived>;
2343
2344 #[inline]
2345 fn bookmarks(&self) -> &Self::Bookmarks {
2346 &self.bookmarked
2347 }
2348 #[inline]
2349 fn contains_bookmark(&self, id: &K::Archived) -> bool {
2350 self.bookmarked.contains(id)
2351 }
2352}
2353
2354#[cfg(feature = "rkyv")]
2355impl<K, T, M, S>
2356 ImmutableActivePathWeave<K::Archived, ArchivedIndependentNode<K, T, S>, T::Archived>
2357 for ArchivedIndependentWeave<K, T, M, S>
2358where
2359 K: Archive + Hash + Copy + Eq + Ord,
2360 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
2361 T: Archive + IndependentContents,
2362 M: Archive,
2363 S: BuildHasher + Default + Clone,
2364{
2365 type Active = ArchivedHashSet<K::Archived>;
2366
2367 #[inline]
2368 fn active(&self) -> &Self::Active {
2369 &self.active
2370 }
2371}