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