1use alloc::{boxed::Box, vec::Vec};
4use core::{
5 cmp::Ordering,
6 hash::{BuildHasher, Hash},
7};
8
9use contracts::contract;
10use hashbrown::{HashMap, HashSet};
11use indexmap::IndexSet;
12
13#[cfg(feature = "rkyv")]
14use rkyv::{
15 Archive, Deserialize, Serialize,
16 bytecheck::Verify,
17 collections::swiss_table::{ArchivedHashMap, ArchivedIndexSet},
18 option::ArchivedOption,
19 rancor::{Fallible, Source, fail},
20 with::Skip,
21};
22
23#[cfg(feature = "serde")]
24use serdev::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
25
26use crate::{
27 ActiveSingularWeave, BookmarkableWeave, DeduplicatableContents, DeduplicatableWeave,
28 DiscreteContentResult, DiscreteContents, DiscreteWeave, IndependentContents, MetadataWeave,
29 Node, SemiIndependentWeave, SortableBookmarkableWeave, SortableWeave, Weave,
30 contract::{lacks_duplicates, valid_path, valid_topological_sort},
31};
32
33#[cfg(feature = "rkyv")]
34use crate::{
35 ImmutableActiveSingularWeave, ImmutableBookmarkableWeave, ImmutableMetadataWeave,
36 ImmutableSortableWeave, ImmutableWeave,
37};
38
39#[cfg(any(feature = "serde", feature = "rkyv"))]
40use crate::contract::ValidationError;
41
42#[cfg(feature = "loro")]
43pub mod loro;
44
45#[cfg(feature = "legacy")]
46#[deprecated]
47pub mod legacy_dependent;
48
49#[derive(Default, Debug, Clone)]
50#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
51#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
52#[must_use]
54pub struct DependentNode<K, T, S>
55where
56 K: Hash + Copy + Eq + Ord,
57 S: BuildHasher + Default + Clone,
58{
59 pub id: K,
61 pub from: Option<K>,
63 #[cfg_attr(
65 feature = "serde",
66 serde(bound(
67 serialize = "IndexSet<K, S>: SerdeSerialize",
68 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
69 ))
70 )]
71 pub to: IndexSet<K, S>,
72 pub active: bool,
76 pub bookmarked: bool,
78 pub contents: T,
80}
81
82#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
83impl<K, T, S> PartialEq for DependentNode<K, T, S>
84where
85 K: Hash + Copy + Eq + Ord,
86 T: PartialEq,
87 S: BuildHasher + Default + Clone,
88{
89 #[inline]
90 fn eq(&self, other: &Self) -> bool {
91 self.id == other.id
92 && self.from == other.from
93 && self.to.len() == other.to.len()
94 && self.to.iter().zip(other.to.iter()).all(|(a, b)| a == b)
95 && self.active == other.active
96 && self.bookmarked == other.bookmarked
97 && self.contents == other.contents
98 }
99}
100
101#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
102impl<K, T, S> Eq for DependentNode<K, T, S>
103where
104 K: Hash + Copy + Eq + Ord,
105 T: Eq,
106 S: BuildHasher + Default + Clone,
107{
108}
109
110impl<K, T, S> DependentNode<K, T, S>
111where
112 K: Hash + Copy + Eq + Ord,
113 S: BuildHasher + Default + Clone,
114{
115 #[inline]
116 fn validate(&self) -> bool {
117 self.from.is_none_or(|from| !self.to.contains(&from))
118 && self.from != Some(self.id)
119 && !self.to.contains(&self.id)
120 }
121}
122
123impl<K, T, S> Node<K, T> for DependentNode<K, T, S>
124where
125 K: Hash + Copy + Eq + Ord,
126 S: BuildHasher + Default + Clone,
127{
128 type From = Option<K>;
129 type To = IndexSet<K, S>;
130
131 #[inline]
132 fn id(&self) -> K {
133 self.id
134 }
135 #[inline]
136 fn from(&self) -> &Self::From {
137 &self.from
138 }
139 #[inline]
140 fn to(&self) -> &Self::To {
141 &self.to
142 }
143 #[inline]
144 fn is_active(&self) -> bool {
145 self.active
146 }
147 #[inline]
148 fn contents(&self) -> &T {
149 &self.contents
150 }
151}
152
153#[derive(Default, Debug, Clone)]
155#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
156#[cfg_attr(feature = "serde", derive(SerdeSerialize, SerdeDeserialize))]
157#[cfg_attr(feature = "rkyv", rkyv(bytecheck(verify)))]
158#[cfg_attr(
159 feature = "serde",
160 serde(validate = r#"|p| ValidationError::from_bool(p.validate())"#)
161)]
162#[must_use]
163pub struct DependentWeave<K, T, M, S>
164where
165 K: Hash + Copy + Eq + Ord,
166 S: BuildHasher + Default + Clone,
167{
168 #[cfg_attr(
169 feature = "serde",
170 serde(bound(
171 serialize = "HashMap<K, DependentNode<K, T, S>, S>: SerdeSerialize",
172 deserialize = "HashMap<K, DependentNode<K, T, S>, S>: SerdeDeserialize<'de>"
173 ))
174 )]
175 pub(super) nodes: HashMap<K, DependentNode<K, T, S>, S>,
176 #[cfg_attr(
177 feature = "serde",
178 serde(bound(
179 serialize = "IndexSet<K, S>: SerdeSerialize",
180 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
181 ))
182 )]
183 pub(super) roots: IndexSet<K, S>,
184 pub(super) active: Option<K>,
185 #[cfg_attr(
186 feature = "serde",
187 serde(bound(
188 serialize = "IndexSet<K, S>: SerdeSerialize",
189 deserialize = "IndexSet<K, S>: SerdeDeserialize<'de>"
190 ))
191 )]
192 pub(super) bookmarked: IndexSet<K, S>,
193
194 #[cfg_attr(feature = "rkyv", rkyv(with = Skip))]
195 #[cfg_attr(feature = "serde", serde(skip))]
196 pub(super) scratchpad: Vec<K>,
197
198 pub metadata: M,
200}
201
202#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
203impl<K, T, M, S> PartialEq for DependentWeave<K, T, M, S>
204where
205 K: Hash + Copy + Eq + Ord,
206 T: PartialEq,
207 M: PartialEq,
208 S: BuildHasher + Default + Clone,
209{
210 #[inline]
211 fn eq(&self, other: &Self) -> bool {
212 self.roots.len() == other.roots.len()
213 && self.bookmarked.len() == other.bookmarked.len()
214 && self.active == other.active
215 && self
216 .roots
217 .iter()
218 .zip(other.roots.iter())
219 .all(|(a, b)| a == b)
220 && self
221 .bookmarked
222 .iter()
223 .zip(other.bookmarked.iter())
224 .all(|(a, b)| a == b)
225 && self.nodes == other.nodes
226 && self.metadata == other.metadata
227 }
228}
229
230#[allow(clippy::missing_trait_methods, reason = "Conflicting lint")]
231impl<K, T, M, S> Eq for DependentWeave<K, T, M, S>
232where
233 K: Hash + Copy + Eq + Ord,
234 T: Eq,
235 M: Eq,
236 S: BuildHasher + Default + Clone,
237{
238}
239
240impl<K, T, M, S> DependentWeave<K, T, M, S>
241where
242 K: Hash + Copy + Eq + Ord,
243 S: BuildHasher + Default + Clone,
244{
245 #[contract(
247 ensures(ret.nodes.is_empty()),
248 ensures(ret.validate())
249 )]
250 pub fn with_capacity(capacity: usize, metadata: M) -> Self {
251 Self {
252 nodes: HashMap::with_capacity_and_hasher(capacity, S::default()),
253 roots: IndexSet::with_capacity_and_hasher(capacity, S::default()),
254 active: None,
255 bookmarked: IndexSet::with_capacity_and_hasher(capacity, S::default()),
256 scratchpad: Vec::with_capacity(capacity),
257 metadata,
258 }
259 }
260 #[inline]
262 pub fn capacity(&self) -> usize {
263 self.nodes.capacity()
264 }
265 #[contract(
267 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
268 ensures(old(self.roots.clone()) == self.roots),
269 ensures(old(self.active) == self.active),
270 ensures(old(self.bookmarked.clone()) == self.bookmarked),
271 invariant(self.validate())
272 )]
273 pub fn reserve(&mut self, additional: usize) {
274 self.nodes.reserve(additional);
275 self.roots
276 .reserve(self.nodes.capacity().saturating_sub(self.roots.len()));
277 self.bookmarked
278 .reserve(self.nodes.capacity().saturating_sub(self.bookmarked.len()));
279 self.scratchpad
280 .reserve(self.nodes.capacity().saturating_sub(self.scratchpad.len()));
281 }
282 #[contract(
284 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
285 ensures(old(self.roots.clone()) == self.roots),
286 ensures(old(self.active) == self.active),
287 ensures(old(self.bookmarked.clone()) == self.bookmarked),
288 invariant(self.validate())
289 )]
290 pub fn shrink_to(&mut self, min_capacity: usize) {
291 self.nodes.shrink_to(min_capacity);
292 self.roots.shrink_to(min_capacity);
293 self.bookmarked.shrink_to(min_capacity);
294 self.scratchpad.shrink_to(min_capacity);
295 }
296 fn siblings<'a>(
297 &'a self,
298 node: &'a DependentNode<K, T, S>,
299 ) -> Box<dyn Iterator<Item = &'a DependentNode<K, T, S>> + 'a> {
300 match &node.from {
301 Some(parent) => Box::new(self.nodes.get(parent).into_iter().flat_map(|parent| {
302 parent
303 .to
304 .iter()
305 .copied()
306 .filter(|id| *id != node.id)
307 .filter_map(|id| self.nodes.get(&id))
308 })),
309 None => Box::new(
310 self.roots
311 .iter()
312 .copied()
313 .filter(|id| *id != node.id)
314 .filter_map(|id| self.nodes.get(&id)),
315 ),
316 }
317 }
318}
319
320impl<K, T, M, S> Weave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
321where
322 K: Hash + Copy + Eq + Ord,
323 S: BuildHasher + Default + Clone,
324{
325 type Nodes = HashMap<K, DependentNode<K, T, S>, S>;
326 type Roots = IndexSet<K, S>;
327
328 #[inline]
329 fn len(&self) -> usize {
330 self.nodes.len()
331 }
332 #[inline]
333 fn is_empty(&self) -> bool {
334 self.nodes.is_empty()
335 }
336 #[inline]
337 fn nodes(&self) -> &Self::Nodes {
338 &self.nodes
339 }
340 #[inline]
341 fn roots(&self) -> &Self::Roots {
342 &self.roots
343 }
344 #[inline]
345 fn contains(&self, id: &K) -> bool {
346 self.nodes.contains_key(id)
347 }
348 #[inline]
349 fn contains_active(&self, id: &K) -> bool {
350 self.active == Some(*id)
351 }
352 #[inline]
353 fn get_node(&self, id: &K) -> Option<&DependentNode<K, T, S>> {
354 self.nodes.get(id)
355 }
356 #[contract(
357 ensures(output.len() == self.nodes.len()),
358 ensures(valid_topological_sort(&self.nodes, output)),
359 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
360 ensures(old(self.roots.clone()) == self.roots),
361 ensures(old(self.active) == self.active),
362 ensures(old(self.bookmarked.clone()) == self.bookmarked),
363 invariant(self.validate())
364 )]
365 fn get_ordered_node_identifiers(&mut self, output: &mut Vec<K>) {
366 output.clear();
367
368 for root in &self.roots {
369 topological_sort(&self.nodes, *root, &mut self.scratchpad, output);
370 }
371 }
372 #[contract(
373 ensures(lacks_duplicates(output)),
374 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
375 ensures(self.nodes.contains_key(id) || output.is_empty()),
376 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
377 ensures(old(self.roots.clone()) == self.roots),
378 ensures(old(self.active) == self.active),
379 ensures(old(self.bookmarked.clone()) == self.bookmarked),
380 invariant(self.validate())
381 )]
382 fn get_ordered_node_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
383 output.clear();
384
385 if self.nodes.contains_key(id) {
386 topological_sort(&self.nodes, *id, &mut self.scratchpad, output);
387 }
388 }
389 #[contract(
390 ensures(self.active == output.first().copied()),
391 ensures(lacks_duplicates(output)),
392 ensures(valid_path(&self.nodes, output)),
393 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
394 ensures(old(self.roots.clone()) == self.roots),
395 ensures(old(self.active) == self.active),
396 ensures(old(self.bookmarked.clone()) == self.bookmarked),
397 invariant(self.validate())
398 )]
399 fn get_active_path(&mut self, output: &mut Vec<K>) {
400 output.clear();
401
402 if let Some(active) = self.active {
403 path_to_root(&self.nodes, active, output);
404 }
405 }
406 #[contract(
407 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
408 ensures(self.nodes.contains_key(id) || output.is_empty()),
409 ensures(lacks_duplicates(output)),
410 ensures(valid_path(&self.nodes, output)),
411 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
412 ensures(old(self.roots.clone()) == self.roots),
413 ensures(old(self.active) == self.active),
414 ensures(old(self.bookmarked.clone()) == self.bookmarked),
415 invariant(self.validate())
416 )]
417 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
418 output.clear();
419
420 if self.nodes.contains_key(id) {
421 path_to_root(&self.nodes, *id, output);
422 }
423 }
424 #[contract(
425 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
426 ensures(!ret || old(!self.nodes.contains_key(&node.id))),
427 ensures(!ret || self.nodes.contains_key(&old(node.id))),
428 ensures(!ret || old(node.active) == (self.active == Some(old(node.id)))),
429 ensures(!ret || old(node.bookmarked) == self.bookmarked.contains(&old(node.id))),
430 ensures(!ret || old(node.from.is_some()) || self.roots.contains(&old(node.id))),
431 ensures(!ret || old(node.from.is_none()) || old(self.roots.clone()) == self.roots),
432 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
433 ensures(ret || old(self.roots.clone()) == self.roots),
434 ensures(ret || old(self.active) == self.active),
435 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
436 invariant(self.validate())
437 )]
438 fn add_node(&mut self, node: DependentNode<K, T, S>) -> bool {
439 if self.nodes.contains_key(&node.id) || !node.validate() || !node.to.is_empty() {
440 return false;
441 }
442
443 if let Some(from) = node.from {
444 match self.nodes.get_mut(&from) {
445 Some(parent) => {
446 parent.to.insert(node.id);
447 }
448 None => return false,
449 }
450 } else {
451 self.roots.insert(node.id);
452 }
453
454 if node.active {
455 if let Some(active) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
456 active.active = false;
457 }
458
459 self.active = Some(node.id);
460 }
461
462 if node.bookmarked {
463 self.bookmarked.insert(node.id);
464 }
465
466 self.nodes.insert(node.id, node);
467
468 true
469 }
470 #[contract(
471 ensures(!ret || value == self.contains_active(id)),
472 ensures(ret || old(self.active) == self.active),
473 ensures(ret == self.nodes.contains_key(id)),
474 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
475 ensures(old(self.roots.clone()) == self.roots),
476 ensures(old(self.bookmarked.clone()) == self.bookmarked),
477 invariant(self.validate())
478 )]
479 fn set_node_active_status(&mut self, id: &K, value: bool) -> bool {
480 match self.nodes.get_mut(id) {
481 Some(node) => {
482 node.active = value;
483
484 if value {
485 if self.active != Some(node.id)
486 && let Some(active) = self.active.and_then(|id| self.nodes.get_mut(&id))
487 {
488 active.active = false;
489 }
490
491 self.active = Some(*id);
492 } else if self.active == Some(node.id) {
493 self.active = None;
494 }
495
496 true
497 }
498 None => false,
499 }
500 }
501 #[contract(
502 ensures(!self.nodes.contains_key(id)),
503 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
504 ensures(ret.as_ref().is_none_or(|node| &node.id == id)),
505 ensures(ret.is_none() || old(self.nodes.len()) > self.nodes.len()),
506 ensures(ret.is_none() || old(self.bookmarked.len()) >= self.bookmarked.len()),
507 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
508 ensures(ret.is_some() || old(self.roots.clone()) == self.roots),
509 ensures(ret.is_some() || old(self.active) == self.active),
510 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
511 invariant(self.validate())
512 )]
513 fn remove_node(&mut self, id: &K) -> Option<DependentNode<K, T, S>> {
514 let mut removed_node = None;
515 let mut removed_active = false;
516
517 self.scratchpad.push(*id);
518
519 while let Some(id) = self.scratchpad.pop() {
520 if let Some(node) = self.nodes.remove(&id) {
521 if node.from.is_none() {
522 self.roots.shift_remove(&id);
523 }
524 if node.bookmarked {
525 self.bookmarked.shift_remove(&id);
526 }
527 if node.active {
528 self.active = None;
529 removed_active = true;
530 }
531
532 if let Some(parent) = node.from.and_then(|id| self.nodes.get_mut(&id)) {
533 parent.to.shift_remove(&id);
534 }
535 self.scratchpad.extend(node.to.iter().rev().copied());
536
537 if removed_node.is_none() {
538 removed_node = Some(node);
539 }
540 }
541 }
542
543 if let Some(removed) = removed_node {
544 if removed_active {
545 self.active = removed.from;
546
547 if let Some(node) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
548 node.active = true;
549 }
550 }
551 Some(removed)
552 } else {
553 None
554 }
555 }
556 #[contract(
557 ensures(!self.nodes.contains_key(id)),
558 ensures(ret == old(self.nodes.contains_key(id))),
559 ensures(!ret || old(self.nodes.len()) > self.nodes.len()),
560 ensures(!ret || old(self.bookmarked.len()) >= self.bookmarked.len()),
561 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
562 ensures(ret || old(self.roots.clone()) == self.roots),
563 ensures(ret || old(self.active) == self.active),
564 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
565 invariant(self.validate())
566 )]
567 fn remove_node_tracked(
568 &mut self,
569 id: &K,
570 mut on_removal: impl FnMut(DependentNode<K, T, S>),
571 ) -> bool {
572 let removed_node_parent = self.nodes.get(id).map(|node| node.from);
573 let mut removed_active = false;
574
575 self.scratchpad.push(*id);
576
577 while let Some(id) = self.scratchpad.pop() {
578 if let Some(node) = self.nodes.remove(&id) {
579 if node.from.is_none() {
580 self.roots.shift_remove(&id);
581 }
582 if node.bookmarked {
583 self.bookmarked.shift_remove(&id);
584 }
585 if node.active {
586 self.active = None;
587 removed_active = true;
588 }
589
590 if let Some(parent) = node.from.and_then(|id| self.nodes.get_mut(&id)) {
591 parent.to.shift_remove(&id);
592 }
593 self.scratchpad.extend(node.to.iter().rev().copied());
594
595 on_removal(node);
596 }
597 }
598
599 if let Some(parent) = removed_node_parent {
600 if removed_active {
601 self.active = parent;
602
603 if let Some(node) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
604 node.active = true;
605 }
606 }
607 true
608 } else {
609 false
610 }
611 }
612 #[contract(
613 ensures(self.nodes.is_empty()),
614 ensures(self.validate())
615 )]
616 fn remove_all_nodes(&mut self) {
617 self.nodes.clear();
618 self.roots.clear();
619 self.active = None;
620 self.bookmarked.clear();
621 }
622}
623
624impl<K, T, M, S> DependentWeave<K, T, M, S>
625where
626 K: Hash + Copy + Eq + Ord,
627 S: BuildHasher + Default + Clone,
628{
629 pub fn validate(&self) -> bool {
631 let mut scratchpad = Vec::with_capacity(self.nodes.len());
632 let mut scratchpad_set = HashSet::with_capacity_and_hasher(self.nodes.len(), S::default());
633
634 self.scratchpad.is_empty()
635 && self
636 .roots
637 .iter()
638 .all(move |value| self.nodes.contains_key(value))
639 && self
640 .active
641 .as_ref()
642 .is_none_or(|active| self.nodes.contains_key(active))
643 && self
644 .bookmarked
645 .iter()
646 .all(move |value| self.nodes.contains_key(value))
647 && self.nodes.iter().all(|(key, value)| {
648 value.validate()
649 && value.id == *key
650 && value
651 .from
652 .as_ref()
653 .is_none_or(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
654 && value.to.iter().all(|v| {
655 self.nodes
656 .get(v)
657 .is_some_and(|p| p.from.as_ref() == Some(key))
658 })
659 && value.from.is_none() == self.roots.contains(key)
660 && value.active == (self.active == Some(*key))
661 && value.bookmarked == self.bookmarked.contains(key)
662 })
663 && !detect_cycles(
664 &self.nodes,
665 self.roots.iter().copied(),
666 &mut scratchpad,
667 &mut scratchpad_set,
668 )
669 }
670}
671
672impl<K, T, M, S> MetadataWeave<K, DependentNode<K, T, S>, T, M> for DependentWeave<K, T, M, S>
673where
674 K: Hash + Copy + Eq + Ord,
675 S: BuildHasher + Default + Clone,
676{
677 #[inline]
678 fn metadata(&self) -> &M {
679 &self.metadata
680 }
681 #[contract(
682 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
683 ensures(old(self.roots.clone()) == self.roots),
684 ensures(old(self.active) == self.active),
685 ensures(old(self.bookmarked.clone()) == self.bookmarked),
686 invariant(self.validate())
687 )]
688 #[inline]
689 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
690 callback(&mut self.metadata)
691 }
692}
693
694impl<K, T, M, S> BookmarkableWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
695where
696 K: Hash + Copy + Eq + Ord,
697 S: BuildHasher + Default + Clone,
698{
699 type Bookmarks = IndexSet<K, S>;
700
701 #[inline]
702 fn bookmarks(&self) -> &Self::Bookmarks {
703 &self.bookmarked
704 }
705 #[inline]
706 fn contains_bookmark(&self, id: &K) -> bool {
707 self.bookmarked.contains(id)
708 }
709 #[contract(
710 ensures(!ret || value == self.bookmarked.contains(id)),
711 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
712 ensures(ret == self.nodes.contains_key(id)),
713 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
714 ensures(old(self.roots.clone()) == self.roots),
715 ensures(old(self.active) == self.active),
716 invariant(self.validate())
717 )]
718 fn set_node_bookmarked_status(&mut self, id: &K, value: bool) -> bool {
719 match self.nodes.get_mut(id) {
720 Some(node) => {
721 node.bookmarked = value;
722 if value {
723 self.bookmarked.insert(node.id);
724 } else {
725 self.bookmarked.shift_remove(id);
726 }
727
728 true
729 }
730 None => false,
731 }
732 }
733}
734
735impl<K, T, M, S> SortableWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
736where
737 K: Hash + Copy + Eq + Ord,
738 S: BuildHasher + Default + Clone,
739{
740 #[contract(
741 ensures(output.len() == self.nodes.len()),
742 ensures(valid_topological_sort(&self.nodes, output)),
743 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
744 ensures(old(self.roots.clone()) == self.roots),
745 ensures(old(self.active) == self.active),
746 ensures(old(self.bookmarked.clone()) == self.bookmarked),
747 invariant(self.validate())
748 )]
749 fn get_ordered_node_identifiers_mirrored(&mut self, output: &mut Vec<K>) {
750 output.clear();
751
752 for root in &self.roots {
753 topological_sort_mirrored(&self.nodes, *root, &mut self.scratchpad, output);
754 }
755 }
756 #[contract(
757 ensures(lacks_duplicates(output)),
758 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
759 ensures(self.nodes.contains_key(id) || output.is_empty()),
760 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
761 ensures(old(self.roots.clone()) == self.roots),
762 ensures(old(self.active) == self.active),
763 ensures(old(self.bookmarked.clone()) == self.bookmarked),
764 invariant(self.validate())
765 )]
766 fn get_ordered_node_identifiers_mirrored_from(&mut self, id: &K, output: &mut Vec<K>) {
767 output.clear();
768
769 if self.nodes.contains_key(id) {
770 topological_sort_mirrored(&self.nodes, *id, &mut self.scratchpad, output);
771 }
772 }
773 #[contract(
774 ensures(ret == self.nodes.contains_key(id)),
775 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
776 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
777 ensures(old(self.roots.clone()) == self.roots),
778 ensures(old(self.active) == self.active),
779 ensures(old(self.bookmarked.clone()) == self.bookmarked),
780 invariant(self.validate())
781 )]
782 fn sort_node_children_by(
783 &mut self,
784 id: &K,
785 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
786 ) -> bool {
787 if let Some(mut node) = self.nodes.remove(id) {
788 node.to.sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
789 self.nodes.insert(node.id, node);
790
791 true
792 } else {
793 false
794 }
795 }
796 #[contract(
797 ensures(ret == self.nodes.contains_key(id)),
798 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
799 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
800 ensures(old(self.roots.clone()) == self.roots),
801 ensures(old(self.active) == self.active),
802 ensures(old(self.bookmarked.clone()) == self.bookmarked),
803 invariant(self.validate())
804 )]
805 fn sort_node_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
806 if let Some(node) = self.nodes.get_mut(id) {
807 node.to.sort_by(cmp);
808
809 true
810 } else {
811 false
812 }
813 }
814 #[contract(
815 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
816 ensures(old(self.roots.clone()) == self.roots),
817 ensures(old(self.active) == self.active),
818 ensures(old(self.bookmarked.clone()) == self.bookmarked),
819 invariant(self.validate())
820 )]
821 fn sort_roots_by(
822 &mut self,
823 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
824 ) {
825 self.roots
826 .sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
827 }
828 #[contract(
829 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
830 ensures(old(self.roots.clone()) == self.roots),
831 ensures(old(self.active) == self.active),
832 ensures(old(self.bookmarked.clone()) == self.bookmarked),
833 invariant(self.validate())
834 )]
835 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
836 self.roots.sort_by(cmp);
837 }
838}
839
840impl<K, T, M, S> SortableBookmarkableWeave<K, DependentNode<K, T, S>, T>
841 for DependentWeave<K, T, M, S>
842where
843 K: Hash + Copy + Eq + Ord,
844 S: BuildHasher + Default + Clone,
845{
846 #[contract(
847 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
848 ensures(old(self.roots.clone()) == self.roots),
849 ensures(old(self.active) == self.active),
850 ensures(old(self.bookmarked.clone()) == self.bookmarked),
851 invariant(self.validate())
852 )]
853 fn sort_bookmarks_by(
854 &mut self,
855 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
856 ) {
857 self.bookmarked
858 .sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
859 }
860 #[contract(
861 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
862 ensures(old(self.roots.clone()) == self.roots),
863 ensures(old(self.active) == self.active),
864 ensures(old(self.bookmarked.clone()) == self.bookmarked),
865 invariant(self.validate())
866 )]
867 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
868 self.bookmarked.sort_by(cmp);
869 }
870}
871
872impl<K, T, M, S> ActiveSingularWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
873where
874 K: Hash + Copy + Eq + Ord,
875 S: BuildHasher + Default + Clone,
876{
877 #[inline]
878 fn active(&self) -> Option<K> {
879 self.active
880 }
881}
882
883impl<K, T, M, S> DiscreteWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
884where
885 K: Hash + Copy + Eq + Ord,
886 T: DiscreteContents,
887 S: BuildHasher + Default + Clone,
888{
889 #[contract(
890 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
891 ensures(!ret || self.nodes.contains_key(id)),
892 ensures(!ret || self.nodes.contains_key(&new_id)),
893 ensures(!ret || old(!self.nodes.contains_key(&new_id))),
894 ensures(!ret || self.nodes[id].to.contains(&new_id) && self.nodes[id].to.len() == 1),
895 ensures(!ret || self.nodes[&new_id].from == Some(*id)),
896 ensures(!ret || old(self.nodes.get(id).map(|n| n.to.clone())).unwrap() == self.nodes[&new_id].to),
897 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
898 ensures(old(self.roots.clone()) == self.roots),
899 ensures(old(self.active) == self.active),
900 ensures(old(self.bookmarked.clone()) == self.bookmarked),
901 invariant(self.validate())
902 )]
903 fn split_node(&mut self, id: &K, at: usize, new_id: K) -> bool {
904 if self.nodes.contains_key(&new_id) || *id == new_id {
905 return false;
906 }
907
908 if let Some(mut node) = self.nodes.remove(id) {
909 match node.contents.split(at) {
910 DiscreteContentResult::Two(left, right) => {
911 let left_node = DependentNode {
912 id: node.id,
913 from: node.from,
914 to: IndexSet::from_iter([new_id]),
915 active: node.active,
916 bookmarked: node.bookmarked,
917 contents: left,
918 };
919
920 node.from = Some(node.id);
921 node.id = new_id;
922 node.contents = right;
923 node.active = false;
924 node.bookmarked = false;
925
926 for child in &node.to {
927 let child = self.nodes.get_mut(child).unwrap();
928 child.from = Some(node.id);
929 }
930
931 self.nodes.insert(left_node.id, left_node);
932 self.nodes.insert(node.id, node);
933
934 true
935 }
936 DiscreteContentResult::One(content) => {
937 node.contents = content;
938 self.nodes.insert(node.id, node);
939 false
940 }
941 }
942 } else {
943 false
944 }
945 }
946 #[contract(
947 ensures(ret.is_none() || old(self.nodes.len()) - 1 == self.nodes.len()),
948 ensures(ret.is_none() || !self.nodes.contains_key(id)),
949 ensures(ret.is_none() || old(self.nodes.contains_key(id))),
950 ensures(ret.is_none() || !old(self.contains_active(id)) || old(self.contains_active(id)) && self.contains_active(&ret.unwrap())),
951 ensures(ret.is_none() || old(self.contains_active(id)) || old(self.nodes.get(id).and_then(|n| n.from).and_then(|p| self.nodes.get(&p)).map(|p| p.active)).unwrap() == self.nodes[&ret.unwrap()].active),
952 ensures(ret.is_none() || old(self.nodes.get(id).and_then(|n| n.from).and_then(|p| self.nodes.get(&p)).map(|p| p.from)).unwrap() == self.nodes[&ret.unwrap()].from),
953 ensures(ret.is_none() || old(self.nodes.get(id).map(|node| node.to.clone())).unwrap() == self.nodes[&ret.unwrap()].to),
954 ensures(ret.is_none() || ret.unwrap() == old(self.nodes.get(id).and_then(|node| node.from)).unwrap()),
955 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
956 ensures(ret.is_some() || old(self.active) == self.active),
957 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
958 ensures(old(self.roots.clone()) == self.roots),
959 invariant(self.validate())
960 )]
961 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
962 if let Some(mut node) = self.nodes.remove(id) {
963 if let Some(mut parent) = node.from.and_then(|id| self.nodes.remove(&id)) {
964 if parent.to.len() > 1 {
965 self.nodes.insert(parent.id, parent);
966 self.nodes.insert(node.id, node);
967 return None;
968 }
969
970 match parent.contents.merge(node.contents) {
971 DiscreteContentResult::Two(left, right) => {
972 parent.contents = left;
973 node.contents = right;
974 self.nodes.insert(parent.id, parent);
975 self.nodes.insert(node.id, node);
976 None
977 }
978 DiscreteContentResult::One(content) => {
979 parent.contents = content;
980 parent.to = node.to;
981
982 for child in &parent.to {
983 let child = self.nodes.get_mut(child).unwrap();
984 child.from = Some(parent.id);
985 }
986
987 if node.active {
988 parent.active = true;
989 self.active = Some(parent.id);
990 }
991
992 let parent_id = parent.id;
993
994 self.nodes.insert(parent.id, parent);
995
996 self.bookmarked.shift_remove(&node.id);
997
998 Some(parent_id)
999 }
1000 }
1001 } else {
1002 self.nodes.insert(node.id, node);
1003 None
1004 }
1005 } else {
1006 None
1007 }
1008 }
1009}
1010
1011impl<K, T, M, S> SemiIndependentWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
1012where
1013 K: Hash + Copy + Eq + Ord,
1014 T: IndependentContents,
1015 S: BuildHasher + Default + Clone,
1016{
1017 #[contract(
1018 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
1019 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1020 ensures(old(self.roots.clone()) == self.roots),
1021 ensures(old(self.active) == self.active),
1022 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1023 invariant(self.validate())
1024 )]
1025 #[inline]
1026 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1027 self.nodes
1028 .get_mut(id)
1029 .map(|node| callback(&mut node.contents))
1030 }
1031}
1032
1033impl<K, T, M, S> DeduplicatableWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
1034where
1035 K: Hash + Copy + Eq + Ord,
1036 T: DeduplicatableContents,
1037 S: BuildHasher + Default + Clone,
1038{
1039 fn find_duplicates(&self, id: &K) -> impl Iterator<Item = K> {
1040 self.nodes.get(id).into_iter().flat_map(|node| {
1041 self.siblings(node).filter_map(|sibling| {
1042 if node.contents.is_duplicate_of(&sibling.contents) {
1043 Some(sibling.id)
1044 } else {
1045 None
1046 }
1047 })
1048 })
1049 }
1050}
1051
1052#[cfg(feature = "rkyv")]
1053impl<K, T, S> ArchivedDependentNode<K, T, S>
1054where
1055 K: Archive + Hash + Copy + Eq + Ord,
1056 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1057 T: Archive,
1058 S: BuildHasher + Default + Clone,
1059{
1060 #[inline]
1061 fn validate(&self) -> bool {
1062 (if let ArchivedOption::Some(from) = &self.from {
1063 !self.to.contains(from)
1064 } else {
1065 true
1066 }) && self.from != Some(self.id)
1067 && !self.to.contains(&self.id)
1068 }
1069}
1070
1071#[cfg(feature = "rkyv")]
1072impl<K, T, S> Node<K::Archived, T::Archived> for ArchivedDependentNode<K, T, S>
1073where
1074 K: Archive + Hash + Copy + Eq + Ord,
1075 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1076 T: Archive,
1077 S: BuildHasher + Default + Clone,
1078{
1079 type From = ArchivedOption<K::Archived>;
1080 type To = ArchivedIndexSet<K::Archived>;
1081
1082 #[inline]
1083 fn id(&self) -> K::Archived {
1084 self.id
1085 }
1086 #[inline]
1087 fn from(&self) -> &Self::From {
1088 &self.from
1089 }
1090 #[inline]
1091 fn to(&self) -> &Self::To {
1092 &self.to
1093 }
1094 #[inline]
1095 fn is_active(&self) -> bool {
1096 self.active
1097 }
1098 #[inline]
1099 fn contents(&self) -> &<T as Archive>::Archived {
1100 &self.contents
1101 }
1102}
1103
1104#[cfg(feature = "rkyv")]
1105impl<K, T, M, S> ArchivedDependentWeave<K, T, M, S>
1106where
1107 K: Archive + Hash + Copy + Eq + Ord,
1108 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1109 T: Archive,
1110 M: Archive,
1111 S: BuildHasher + Default + Clone,
1112{
1113 fn validate(&self) -> bool {
1114 let mut scratchpad = Vec::with_capacity(self.nodes.len());
1115 let mut scratchpad_set = HashSet::with_capacity(self.nodes.len());
1116
1117 self.roots
1118 .iter()
1119 .all(move |value| self.nodes.contains_key(value))
1120 && self
1121 .active
1122 .as_ref()
1123 .is_none_or(|active| self.nodes.contains_key(active))
1124 && self
1125 .bookmarked
1126 .iter()
1127 .all(move |value| self.nodes.contains_key(value))
1128 && self.nodes.iter().all(|(key, value)| {
1129 value.validate()
1130 && value.id == *key
1131 && value
1132 .from
1133 .as_ref()
1134 .is_none_or(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
1135 && value.to.iter().all(|v| {
1136 self.nodes
1137 .get(v)
1138 .is_some_and(|p| p.from.as_ref() == Some(key))
1139 })
1140 && value.from.is_none() == self.roots.contains(key)
1141 && value.active == (self.active == Some(*key))
1142 && value.bookmarked == self.bookmarked.contains(key)
1143 })
1144 && !archived_detect_cycles(
1145 &self.nodes,
1146 self.roots.iter().copied(),
1147 &mut scratchpad,
1148 &mut scratchpad_set,
1149 )
1150 }
1151}
1152
1153#[cfg(feature = "rkyv")]
1154unsafe impl<K, T, M, S, C> Verify<C> for ArchivedDependentWeave<K, T, M, S>
1157where
1158 K: Archive + Hash + Copy + Eq + Ord,
1159 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1160 T: Archive,
1161 M: Archive,
1162 S: BuildHasher + Default + Clone,
1163 C: Fallible + ?Sized,
1164 C::Error: Source,
1165{
1166 fn verify(&self, _context: &mut C) -> Result<(), C::Error> {
1167 if !self.validate() {
1168 fail!(ValidationError)
1169 }
1170
1171 Ok(())
1172 }
1173}
1174
1175#[cfg(feature = "rkyv")]
1176impl<K, T, M, S> ImmutableWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1177 for ArchivedDependentWeave<K, T, M, S>
1178where
1179 K: Archive + Hash + Copy + Eq + Ord,
1180 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1181 T: Archive,
1182 M: Archive,
1183 S: BuildHasher + Default + Clone,
1184{
1185 type Nodes = ArchivedHashMap<K::Archived, ArchivedDependentNode<K, T, S>>;
1186 type Roots = ArchivedIndexSet<K::Archived>;
1187
1188 #[inline]
1189 fn len(&self) -> usize {
1190 self.nodes.len()
1191 }
1192 #[inline]
1193 fn is_empty(&self) -> bool {
1194 self.nodes.is_empty()
1195 }
1196 #[inline]
1197 fn nodes(&self) -> &Self::Nodes {
1198 &self.nodes
1199 }
1200 #[inline]
1201 fn roots(&self) -> &Self::Roots {
1202 &self.roots
1203 }
1204 #[inline]
1205 fn contains(&self, id: &K::Archived) -> bool {
1206 self.nodes.contains_key(id)
1207 }
1208 #[inline]
1209 fn contains_active(&self, id: &K::Archived) -> bool {
1210 self.active == Some(*id)
1211 }
1212 #[inline]
1213 fn get_node(&self, id: &K::Archived) -> Option<&ArchivedDependentNode<K, T, S>> {
1214 self.nodes.get(id)
1215 }
1216 fn get_ordered_node_identifiers(&self, output: &mut Vec<K::Archived>) {
1217 output.clear();
1218
1219 let mut scratchpad = Vec::with_capacity(self.len());
1220 let mut scratchpad_2 = Vec::with_capacity(self.len());
1221
1222 for root in self.roots().iter() {
1223 archived_topological_sort(
1224 &self.nodes,
1225 *root,
1226 &mut scratchpad,
1227 &mut scratchpad_2,
1228 output,
1229 );
1230 }
1231 }
1232 fn get_ordered_node_identifiers_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
1233 output.clear();
1234
1235 if self.nodes.contains_key(id) {
1236 let mut scratchpad = Vec::with_capacity(self.len());
1237 let mut scratchpad_2 = Vec::with_capacity(self.len());
1238
1239 archived_topological_sort(&self.nodes, *id, &mut scratchpad, &mut scratchpad_2, output);
1240 }
1241 }
1242 fn get_active_path(&self, output: &mut Vec<K::Archived>) {
1243 output.clear();
1244
1245 if let ArchivedOption::Some(active) = self.active {
1246 archived_path_to_root(&self.nodes, active, output);
1247 }
1248 }
1249 fn get_path_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
1250 output.clear();
1251
1252 if self.nodes.contains_key(id) {
1253 archived_path_to_root(&self.nodes, *id, output);
1254 }
1255 }
1256}
1257
1258#[cfg(feature = "rkyv")]
1259impl<K, T, M, S>
1260 ImmutableMetadataWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived, M::Archived>
1261 for ArchivedDependentWeave<K, T, M, S>
1262where
1263 K: Archive + Hash + Copy + Eq + Ord,
1264 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1265 T: Archive,
1266 M: Archive,
1267 S: BuildHasher + Default + Clone,
1268{
1269 #[inline]
1270 fn metadata(&self) -> &M::Archived {
1271 &self.metadata
1272 }
1273}
1274
1275#[cfg(feature = "rkyv")]
1276impl<K, T, M, S>
1277 ImmutableBookmarkableWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1278 for ArchivedDependentWeave<K, T, M, S>
1279where
1280 K: Archive + Hash + Copy + Eq + Ord,
1281 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1282 T: Archive,
1283 M: Archive,
1284 S: BuildHasher + Default + Clone,
1285{
1286 type Bookmarks = ArchivedIndexSet<K::Archived>;
1287
1288 #[inline]
1289 fn bookmarks(&self) -> &Self::Bookmarks {
1290 &self.bookmarked
1291 }
1292 #[inline]
1293 fn contains_bookmark(&self, id: &K::Archived) -> bool {
1294 self.bookmarked.contains(id)
1295 }
1296}
1297
1298#[cfg(feature = "rkyv")]
1299impl<K, T, M, S> ImmutableSortableWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1300 for ArchivedDependentWeave<K, T, M, S>
1301where
1302 K: Archive + Hash + Copy + Eq + Ord,
1303 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1304 T: Archive,
1305 M: Archive,
1306 S: BuildHasher + Default + Clone,
1307{
1308 fn get_ordered_node_identifiers_mirrored(&self, output: &mut Vec<K::Archived>) {
1309 output.clear();
1310 let mut scratchpad = Vec::with_capacity(self.len());
1311
1312 for root in self.roots().iter() {
1313 archived_topological_sort_mirrored(&self.nodes, *root, &mut scratchpad, output);
1314 }
1315 }
1316 fn get_ordered_node_identifiers_mirrored_from(
1317 &self,
1318 id: &K::Archived,
1319 output: &mut Vec<K::Archived>,
1320 ) {
1321 output.clear();
1322
1323 if self.nodes.contains_key(id) {
1324 let mut scratchpad = Vec::with_capacity(self.len());
1325
1326 archived_topological_sort_mirrored(&self.nodes, *id, &mut scratchpad, output);
1327 }
1328 }
1329}
1330
1331#[cfg(feature = "rkyv")]
1332impl<K, T, M, S>
1333 ImmutableActiveSingularWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1334 for ArchivedDependentWeave<K, T, M, S>
1335where
1336 K: Archive + Hash + Copy + Eq + Ord,
1337 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1338 T: Archive,
1339 M: Archive,
1340 S: BuildHasher + Default + Clone,
1341{
1342 #[inline]
1343 fn active(&self) -> Option<K::Archived> {
1344 match self.active {
1345 ArchivedOption::Some(active) => Some(active),
1346 ArchivedOption::None => None,
1347 }
1348 }
1349}
1350
1351fn path_to_root<K, T, S>(
1352 nodes: &HashMap<K, DependentNode<K, T, S>, S>,
1353 mut id: K,
1354 thread: &mut Vec<K>,
1355) where
1356 K: Hash + Copy + Eq + Ord,
1357 S: BuildHasher + Default + Clone,
1358{
1359 thread.push(id);
1360
1361 while let Some(parent) = nodes[&id].from {
1362 thread.push(parent);
1363 id = parent;
1364 }
1365}
1366
1367fn topological_sort<K, N, T, S>(
1368 nodes: &HashMap<K, N, S>,
1369 id: K,
1370 scratchpad: &mut Vec<K>,
1371 identifiers: &mut Vec<K>,
1372) where
1373 K: Hash + Copy + Eq + Ord,
1374 N: Node<K, T, From = Option<K>, To = IndexSet<K, S>>,
1375 S: BuildHasher + Default + Clone,
1376{
1377 scratchpad.push(id);
1378
1379 while let Some(id) = scratchpad.pop() {
1380 identifiers.push(id);
1381 scratchpad.extend(nodes[&id].to().into_iter().rev().copied());
1382 }
1383}
1384
1385fn topological_sort_mirrored<K, N, T, S>(
1386 nodes: &HashMap<K, N, S>,
1387 id: K,
1388 scratchpad: &mut Vec<K>,
1389 identifiers: &mut Vec<K>,
1390) where
1391 K: Hash + Copy + Eq + Ord,
1392 N: Node<K, T, From = Option<K>, To = IndexSet<K, S>>,
1393 S: BuildHasher + Default + Clone,
1394{
1395 scratchpad.push(id);
1396
1397 while let Some(id) = scratchpad.pop() {
1398 identifiers.push(id);
1399 scratchpad.extend(nodes[&id].to().into_iter().copied());
1400 }
1401}
1402
1403fn detect_cycles<K, N, T, S>(
1404 nodes: &HashMap<K, N, S>,
1405 roots: impl Iterator<Item = K>,
1406 scratchpad: &mut Vec<K>,
1407 scratchpad_set: &mut HashSet<K, S>,
1408) -> bool
1409where
1410 K: Hash + Copy + Eq + Ord,
1411 N: Node<K, T, From = Option<K>, To = IndexSet<K, S>>,
1412 S: BuildHasher + Default + Clone,
1413{
1414 scratchpad.extend(roots);
1415
1416 while let Some(id) = scratchpad.pop() {
1417 if !scratchpad_set.insert(id) {
1418 return true;
1419 }
1420 scratchpad.extend(nodes[&id].to().into_iter().rev().copied());
1421 }
1422
1423 scratchpad_set.len() != nodes.len()
1424}
1425
1426#[cfg(feature = "rkyv")]
1427fn archived_path_to_root<K, T, S>(
1428 nodes: &ArchivedHashMap<K::Archived, ArchivedDependentNode<K, T, S>>,
1429 mut id: K::Archived,
1430 thread: &mut Vec<K::Archived>,
1431) where
1432 K: Archive + Hash + Copy + Eq + Ord,
1433 <K as Archive>::Archived: Hash + Copy + Eq + Ord,
1434 T: Archive,
1435 S: BuildHasher + Default + Clone,
1436{
1437 thread.push(id);
1438
1439 while let ArchivedOption::Some(parent) = nodes[&id].from {
1440 thread.push(parent);
1441 id = parent;
1442 }
1443}
1444
1445#[cfg(feature = "rkyv")]
1446fn archived_topological_sort<K, N, T>(
1447 nodes: &ArchivedHashMap<K, N>,
1448 id: K,
1449 scratchpad: &mut Vec<K>,
1450 scratchpad_2: &mut Vec<K>,
1451 identifiers: &mut Vec<K>,
1452) where
1453 K: Hash + Copy + Eq + Ord,
1454 N: Node<K, T, From = ArchivedOption<K>, To = ArchivedIndexSet<K>>,
1455{
1456 scratchpad.push(id);
1457
1458 while let Some(id) = scratchpad.pop() {
1459 identifiers.push(id);
1460 scratchpad_2.extend(nodes[&id].to().iter().copied());
1461 scratchpad_2.reverse();
1462 scratchpad.append(scratchpad_2);
1463 }
1464}
1465
1466#[cfg(feature = "rkyv")]
1467fn archived_topological_sort_mirrored<K, N, T>(
1468 nodes: &ArchivedHashMap<K, N>,
1469 id: K,
1470 scratchpad: &mut Vec<K>,
1471 identifiers: &mut Vec<K>,
1472) where
1473 K: Hash + Copy + Eq + Ord,
1474 N: Node<K, T, From = ArchivedOption<K>, To = ArchivedIndexSet<K>>,
1475{
1476 scratchpad.push(id);
1477
1478 while let Some(id) = scratchpad.pop() {
1479 identifiers.push(id);
1480 scratchpad.extend(nodes[&id].to().iter().copied());
1481 }
1482}
1483
1484#[cfg(feature = "rkyv")]
1485fn archived_detect_cycles<K, N, T, S>(
1486 nodes: &ArchivedHashMap<K, N>,
1487 roots: impl Iterator<Item = K>,
1488 scratchpad: &mut Vec<K>,
1489 scratchpad_set: &mut HashSet<K, S>,
1490) -> bool
1491where
1492 K: Hash + Copy + Eq + Ord,
1493 N: Node<K, T, From = ArchivedOption<K>, To = ArchivedIndexSet<K>>,
1494 S: BuildHasher + Default + Clone,
1495{
1496 scratchpad.extend(roots);
1497
1498 while let Some(id) = scratchpad.pop() {
1499 if !scratchpad_set.insert(id) {
1500 return true;
1501 }
1502 scratchpad.extend(nodes[&id].to().iter().copied());
1503 }
1504
1505 scratchpad_set.len() != nodes.len()
1506}