1use alloc::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, DiscreteContentResult, DiscreteContents, DiscreteWeave,
33 IndependentContents, MetadataWeave, Node, SemiIndependentWeave, SortableBookmarkableWeave,
34 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 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::default(),
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}
358
359impl<K, T, M, S> Weave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
360where
361 K: Hash + Copy + Eq + Ord,
362 S: BuildHasher + Default + Clone,
363{
364 type Nodes = HashMap<K, DependentNode<K, T, S>, S>;
365 type Roots = IndexSet<K, S>;
366
367 #[inline]
368 fn len(&self) -> usize {
369 self.nodes.len()
370 }
371 #[inline]
372 fn is_empty(&self) -> bool {
373 self.nodes.is_empty()
374 }
375 #[inline]
376 fn nodes(&self) -> &Self::Nodes {
377 &self.nodes
378 }
379 #[inline]
380 fn roots(&self) -> &Self::Roots {
381 &self.roots
382 }
383 #[inline]
384 fn contains(&self, id: &K) -> bool {
385 self.nodes.contains_key(id)
386 }
387 #[inline]
388 fn contains_active(&self, id: &K) -> bool {
389 self.active == Some(*id)
390 }
391 #[inline]
392 fn get(&self, id: &K) -> Option<&DependentNode<K, T, S>> {
393 self.nodes.get(id)
394 }
395 #[inline]
396 fn get_parents(&self, id: &K) -> Option<&Option<K>> {
397 self.nodes.get(id).map(|node| &node.from)
398 }
399 #[inline]
400 fn get_children(&self, id: &K) -> Option<&IndexSet<K, S>> {
401 self.nodes.get(id).map(|node| &node.to)
402 }
403 #[inline]
404 fn get_contents(&self, id: &K) -> Option<&T> {
405 self.nodes.get(id).map(|node| &node.contents)
406 }
407 #[cfg_attr(debug_assertions, contract(
408 ensures(output.len() == self.nodes.len()),
409 ensures(valid_topological_sort(&self.nodes, output)),
410 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
411 ensures(old(self.roots.clone()) == self.roots),
412 ensures(old(self.active) == self.active),
413 ensures(old(self.bookmarked.clone()) == self.bookmarked),
414 invariant(self.validate())
415 ))]
416 fn get_ordered_identifiers(&mut self, output: &mut Vec<K>) {
417 output.clear();
418
419 for root in &self.roots {
420 topological_sort(&self.nodes, *root, &mut self.scratchpad, output);
421 }
422 }
423 #[cfg_attr(debug_assertions, contract(
424 ensures(lacks_duplicates(output)),
425 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
426 ensures(self.nodes.contains_key(id) || output.is_empty()),
427 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
428 ensures(old(self.roots.clone()) == self.roots),
429 ensures(old(self.active) == self.active),
430 ensures(old(self.bookmarked.clone()) == self.bookmarked),
431 invariant(self.validate())
432 ))]
433 fn get_ordered_identifiers_from(&mut self, id: &K, output: &mut Vec<K>) {
434 output.clear();
435
436 if self.nodes.contains_key(id) {
437 topological_sort(&self.nodes, *id, &mut self.scratchpad, output);
438 }
439 }
440 #[cfg_attr(debug_assertions, contract(
441 ensures(self.active == output.first().copied()),
442 ensures(lacks_duplicates(output)),
443 ensures(valid_path(&self.nodes, output)),
444 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
445 ensures(old(self.roots.clone()) == self.roots),
446 ensures(old(self.active) == self.active),
447 ensures(old(self.bookmarked.clone()) == self.bookmarked),
448 invariant(self.validate())
449 ))]
450 fn get_active_path(&mut self, output: &mut Vec<K>) {
451 output.clear();
452
453 if let Some(active) = self.active {
454 path_to_root(&self.nodes, active, output);
455 }
456 }
457 #[cfg_attr(debug_assertions, contract(
458 ensures(!self.nodes.contains_key(id) || output.first() == Some(id)),
459 ensures(self.nodes.contains_key(id) || output.is_empty()),
460 ensures(lacks_duplicates(output)),
461 ensures(valid_path(&self.nodes, output)),
462 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
463 ensures(old(self.roots.clone()) == self.roots),
464 ensures(old(self.active) == self.active),
465 ensures(old(self.bookmarked.clone()) == self.bookmarked),
466 invariant(self.validate())
467 ))]
468 fn get_path_from(&mut self, id: &K, output: &mut Vec<K>) {
469 output.clear();
470
471 if self.nodes.contains_key(id) {
472 path_to_root(&self.nodes, *id, output);
473 }
474 }
475 #[cfg_attr(debug_assertions, contract(
476 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
477 ensures(!ret || old(!self.nodes.contains_key(&node.id))),
478 ensures(!ret || self.nodes.contains_key(&old(node.id))),
479 ensures(!ret || old(node.active) == (self.active == Some(old(node.id)))),
480 ensures(!ret || old(node.bookmarked) == self.bookmarked.contains(&old(node.id))),
481 ensures(!ret || old(node.from.is_some()) || self.roots.contains(&old(node.id))),
482 ensures(!ret || old(node.from.is_none()) || old(self.roots.clone()) == self.roots),
483 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
484 ensures(ret || old(self.roots.clone()) == self.roots),
485 ensures(ret || old(self.active) == self.active),
486 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
487 invariant(self.validate())
488 ))]
489 fn insert(&mut self, node: DependentNode<K, T, S>) -> bool {
490 if self.nodes.contains_key(&node.id) || !node.validate() || !node.to.is_empty() {
491 return false;
492 }
493
494 if let Some(from) = &node.from {
495 match self.nodes.get_mut(from) {
496 Some(parent) => {
497 parent.to.insert(node.id);
498 }
499 None => return false,
500 }
501 } else {
502 self.roots.insert(node.id);
503 }
504
505 if node.active {
506 if let Some(active) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
507 active.active = false;
508 }
509
510 self.active = Some(node.id);
511 }
512
513 if node.bookmarked {
514 self.bookmarked.insert(node.id);
515 }
516
517 self.nodes.insert(node.id, node);
518
519 true
520 }
521 #[cfg_attr(debug_assertions, contract(
522 ensures(!ret || value == self.contains_active(id)),
523 ensures(ret || old(self.active) == self.active),
524 ensures(ret == self.nodes.contains_key(id)),
525 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
526 ensures(old(self.roots.clone()) == self.roots),
527 ensures(old(self.bookmarked.clone()) == self.bookmarked),
528 invariant(self.validate())
529 ))]
530 fn set_active(&mut self, id: &K, value: bool) -> bool {
531 match self.nodes.get_mut(id) {
532 Some(node) => {
533 node.active = value;
534
535 if value {
536 if self.active != Some(node.id)
537 && let Some(active) = self.active.and_then(|id| self.nodes.get_mut(&id))
538 {
539 active.active = false;
540 }
541
542 self.active = Some(*id);
543 } else if self.active == Some(node.id) {
544 self.active = node.from;
545
546 if let Some(active) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
547 active.active = true;
548 }
549 }
550
551 true
552 }
553 None => false,
554 }
555 }
556 #[cfg_attr(debug_assertions, contract(
557 ensures(!self.nodes.contains_key(id)),
558 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
559 ensures(ret.as_ref().is_none_or(|node| &node.id == id)),
560 ensures(ret.is_none() || old(self.nodes.len()) > self.nodes.len()),
561 ensures(ret.is_none() || old(self.bookmarked.len()) >= self.bookmarked.len()),
562 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
563 ensures(ret.is_some() || old(self.roots.clone()) == self.roots),
564 ensures(ret.is_some() || old(self.active) == self.active),
565 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
566 invariant(self.validate())
567 ))]
568 fn remove(&mut self, id: &K) -> Option<DependentNode<K, T, S>> {
569 let mut removed_node = None;
570 let mut removed_active = false;
571
572 self.scratchpad.push(*id);
573
574 while let Some(id) = self.scratchpad.pop() {
575 if let Some(node) = self.nodes.remove(&id) {
576 if node.from.is_none() {
577 self.roots.shift_remove(&id);
578 }
579 if node.bookmarked {
580 self.bookmarked.shift_remove(&id);
581 }
582 if node.active {
583 self.active = None;
584 removed_active = true;
585 }
586
587 if let Some(parent) = node.from.and_then(|id| self.nodes.get_mut(&id)) {
588 parent.to.shift_remove(&id);
589 }
590 self.scratchpad.extend(node.to.iter().rev().copied());
591
592 if removed_node.is_none() {
593 removed_node = Some(node);
594 }
595 }
596 }
597
598 if let Some(removed) = removed_node {
599 if removed_active {
600 self.active = removed.from;
601
602 if let Some(node) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
603 node.active = true;
604 }
605 }
606 Some(removed)
607 } else {
608 None
609 }
610 }
611 #[cfg_attr(debug_assertions, contract(
612 ensures(!self.nodes.contains_key(id)),
613 ensures(ret == old(self.nodes.contains_key(id))),
614 ensures(!ret || old(self.nodes.len()) > self.nodes.len()),
615 ensures(!ret || old(self.bookmarked.len()) >= self.bookmarked.len()),
616 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
617 ensures(ret || old(self.roots.clone()) == self.roots),
618 ensures(ret || old(self.active) == self.active),
619 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
620 invariant(self.validate())
621 ))]
622 fn remove_tracked(
623 &mut self,
624 id: &K,
625 mut on_removal: impl FnMut(DependentNode<K, T, S>),
626 ) -> bool {
627 let removed_node_parent = self.nodes.get(id).map(|node| node.from);
628 let mut removed_active = false;
629
630 self.scratchpad.push(*id);
631
632 while let Some(id) = self.scratchpad.pop() {
633 if let Some(node) = self.nodes.remove(&id) {
634 if node.from.is_none() {
635 self.roots.shift_remove(&id);
636 }
637 if node.bookmarked {
638 self.bookmarked.shift_remove(&id);
639 }
640 if node.active {
641 self.active = None;
642 removed_active = true;
643 }
644
645 if let Some(parent) = node.from.and_then(|id| self.nodes.get_mut(&id)) {
646 parent.to.shift_remove(&id);
647 }
648 self.scratchpad.extend(node.to.iter().rev().copied());
649
650 on_removal(node);
651 }
652 }
653
654 if let Some(parent) = removed_node_parent {
655 if removed_active {
656 self.active = parent;
657
658 if let Some(node) = self.active.and_then(|id| self.nodes.get_mut(&id)) {
659 node.active = true;
660 }
661 }
662 true
663 } else {
664 false
665 }
666 }
667 #[cfg_attr(debug_assertions, contract(
668 ensures(self.nodes.is_empty()),
669 ensures(self.validate())
670 ))]
671 fn clear(&mut self) {
672 self.nodes.clear();
673 self.roots.clear();
674 self.active = None;
675 self.bookmarked.clear();
676 }
677}
678
679impl<K, T, M, S> DependentWeave<K, T, M, S>
680where
681 K: Hash + Copy + Eq + Ord,
682 S: BuildHasher + Default + Clone,
683{
684 pub fn validate(&self) -> bool {
686 let mut scratchpad = Vec::with_capacity(self.nodes.len());
687 let mut scratchpad_set = HashSet::with_capacity_and_hasher(self.nodes.len(), S::default());
688
689 self.scratchpad.is_empty()
690 && self
691 .roots
692 .iter()
693 .all(move |value| self.nodes.contains_key(value))
694 && self
695 .active
696 .as_ref()
697 .is_none_or(|active| self.nodes.contains_key(active))
698 && self
699 .bookmarked
700 .iter()
701 .all(move |value| self.nodes.contains_key(value))
702 && self.nodes.iter().all(|(key, value)| {
703 value.validate()
704 && value.id == *key
705 && value
706 .from
707 .as_ref()
708 .is_none_or(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
709 && value.to.iter().all(|v| {
710 self.nodes
711 .get(v)
712 .is_some_and(|p| p.from.as_ref() == Some(key))
713 })
714 && value.from.is_none() == self.roots.contains(key)
715 && value.active == (self.active == Some(*key))
716 && value.bookmarked == self.bookmarked.contains(key)
717 })
718 && !detect_cycles(
719 &self.nodes,
720 self.roots.iter().copied(),
721 &mut scratchpad,
722 &mut scratchpad_set,
723 )
724 }
725}
726
727impl<K, T, M, S> MetadataWeave<K, DependentNode<K, T, S>, T, M> for DependentWeave<K, T, M, S>
728where
729 K: Hash + Copy + Eq + Ord,
730 S: BuildHasher + Default + Clone,
731{
732 #[inline]
733 fn metadata(&self) -> &M {
734 &self.metadata
735 }
736 #[cfg_attr(debug_assertions, contract(
737 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
738 ensures(old(self.roots.clone()) == self.roots),
739 ensures(old(self.active) == self.active),
740 ensures(old(self.bookmarked.clone()) == self.bookmarked),
741 invariant(self.validate())
742 ))]
743 #[inline]
744 fn metadata_mut<O>(&mut self, callback: impl FnOnce(&mut M) -> O) -> O {
745 callback(&mut self.metadata)
746 }
747}
748
749impl<K, T, M, S> BookmarkableWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
750where
751 K: Hash + Copy + Eq + Ord,
752 S: BuildHasher + Default + Clone,
753{
754 type Bookmarks = IndexSet<K, S>;
755
756 #[inline]
757 fn bookmarks(&self) -> &Self::Bookmarks {
758 &self.bookmarked
759 }
760 #[inline]
761 fn contains_bookmark(&self, id: &K) -> bool {
762 self.bookmarked.contains(id)
763 }
764 #[cfg_attr(debug_assertions, contract(
765 ensures(!ret || value == self.bookmarked.contains(id)),
766 ensures(ret || old(self.bookmarked.clone()) == self.bookmarked),
767 ensures(ret == self.nodes.contains_key(id)),
768 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
769 ensures(old(self.roots.clone()) == self.roots),
770 ensures(old(self.active) == self.active),
771 invariant(self.validate())
772 ))]
773 fn set_bookmarked(&mut self, id: &K, value: bool) -> bool {
774 match self.nodes.get_mut(id) {
775 Some(node) => {
776 node.bookmarked = value;
777 if value {
778 self.bookmarked.insert(node.id);
779 } else {
780 self.bookmarked.shift_remove(id);
781 }
782
783 true
784 }
785 None => false,
786 }
787 }
788}
789
790impl<K, T, M, S> SortableWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
791where
792 K: Hash + Copy + Eq + Ord,
793 S: BuildHasher + Default + Clone,
794{
795 #[cfg_attr(debug_assertions, contract(
796 ensures(ret == self.nodes.contains_key(id)),
797 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
798 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
799 ensures(old(self.roots.clone()) == self.roots),
800 ensures(old(self.active) == self.active),
801 ensures(old(self.bookmarked.clone()) == self.bookmarked),
802 invariant(self.validate())
803 ))]
804 fn sort_children_by(
805 &mut self,
806 id: &K,
807 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
808 ) -> bool {
809 if let Some(mut node) = self.nodes.remove(id) {
810 node.to.sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
811 self.nodes.insert(node.id, node);
812
813 true
814 } else {
815 false
816 }
817 }
818 #[cfg_attr(debug_assertions, contract(
819 ensures(ret == self.nodes.contains_key(id)),
820 ensures(old(self.nodes.get(id).map(|n| n.to.clone())) == self.nodes.get(id).map(|n| n.to.clone())),
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 sort_children_by_id(&mut self, id: &K, cmp: impl FnMut(&K, &K) -> Ordering) -> bool {
828 if let Some(node) = self.nodes.get_mut(id) {
829 node.to.sort_by(cmp);
830
831 true
832 } else {
833 false
834 }
835 }
836 #[cfg_attr(debug_assertions, contract(
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_roots_by(
844 &mut self,
845 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
846 ) {
847 self.roots
848 .sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
849 }
850 #[cfg_attr(debug_assertions, contract(
851 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
852 ensures(old(self.roots.clone()) == self.roots),
853 ensures(old(self.active) == self.active),
854 ensures(old(self.bookmarked.clone()) == self.bookmarked),
855 invariant(self.validate())
856 ))]
857 fn sort_roots_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
858 self.roots.sort_by(cmp);
859 }
860}
861
862impl<K, T, M, S> SortableBookmarkableWeave<K, DependentNode<K, T, S>, T>
863 for DependentWeave<K, T, M, S>
864where
865 K: Hash + Copy + Eq + Ord,
866 S: BuildHasher + Default + Clone,
867{
868 #[cfg_attr(debug_assertions, contract(
869 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
870 ensures(old(self.roots.clone()) == self.roots),
871 ensures(old(self.active) == self.active),
872 ensures(old(self.bookmarked.clone()) == self.bookmarked),
873 invariant(self.validate())
874 ))]
875 fn sort_bookmarks_by(
876 &mut self,
877 mut cmp: impl FnMut(&DependentNode<K, T, S>, &DependentNode<K, T, S>) -> Ordering,
878 ) {
879 self.bookmarked
880 .sort_by(|a, b| cmp(&self.nodes[a], &self.nodes[b]));
881 }
882 #[cfg_attr(debug_assertions, contract(
883 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
884 ensures(old(self.roots.clone()) == self.roots),
885 ensures(old(self.active) == self.active),
886 ensures(old(self.bookmarked.clone()) == self.bookmarked),
887 invariant(self.validate())
888 ))]
889 fn sort_bookmarks_by_id(&mut self, cmp: impl FnMut(&K, &K) -> Ordering) {
890 self.bookmarked.sort_by(cmp);
891 }
892}
893
894impl<K, T, M, S> ActiveSingularWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
895where
896 K: Hash + Copy + Eq + Ord,
897 S: BuildHasher + Default + Clone,
898{
899 #[inline]
900 fn active(&self) -> Option<K> {
901 self.active
902 }
903}
904
905impl<K, T, M, S> DiscreteWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
906where
907 K: Hash + Copy + Eq + Ord,
908 T: DiscreteContents,
909 S: BuildHasher + Default + Clone,
910{
911 #[cfg_attr(debug_assertions, contract(
912 ensures(!ret || old(self.nodes.len()) + 1 == self.nodes.len()),
913 ensures(!ret || self.nodes.contains_key(id)),
914 ensures(!ret || self.nodes.contains_key(&new_id)),
915 ensures(!ret || old(!self.nodes.contains_key(&new_id))),
916 ensures(!ret || self.nodes[id].to.contains(&new_id) && self.nodes[id].to.len() == 1),
917 ensures(!ret || self.nodes[&new_id].from == Some(*id)),
918 ensures(!ret || old(self.nodes.get(id).map(|n| n.to.clone())).unwrap() == self.nodes[&new_id].to),
919 ensures(ret || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
920 ensures(old(self.roots.clone()) == self.roots),
921 ensures(old(self.active) == self.active),
922 ensures(old(self.bookmarked.clone()) == self.bookmarked),
923 invariant(self.validate())
924 ))]
925 fn split(&mut self, id: &K, at: usize, new_id: K) -> bool {
926 if self.nodes.contains_key(&new_id) || *id == new_id {
927 return false;
928 }
929
930 if let Some(mut node) = self.nodes.remove(id) {
931 match node.contents.split(at) {
932 DiscreteContentResult::Two(left, right) => {
933 let left_node = DependentNode {
934 id: node.id,
935 from: node.from,
936 to: IndexSet::from_iter([new_id]),
937 active: node.active,
938 bookmarked: node.bookmarked,
939 contents: left,
940 };
941
942 node.from = Some(node.id);
943 node.id = new_id;
944 node.contents = right;
945 node.active = false;
946 node.bookmarked = false;
947
948 for child in &node.to {
949 let child = self.nodes.get_mut(child).unwrap();
950 child.from = Some(node.id);
951 }
952
953 self.nodes.insert(left_node.id, left_node);
954 self.nodes.insert(node.id, node);
955
956 true
957 }
958 DiscreteContentResult::One(content) => {
959 node.contents = content;
960 self.nodes.insert(node.id, node);
961 false
962 }
963 }
964 } else {
965 false
966 }
967 }
968 #[cfg_attr(debug_assertions, contract(
969 ensures(ret.is_none() || old(self.nodes.len()) - 1 == self.nodes.len()),
970 ensures(ret.is_none() || !self.nodes.contains_key(id)),
971 ensures(ret.is_none() || old(self.nodes.contains_key(id))),
972 ensures(ret.is_none() || !old(self.contains_active(id)) || old(self.contains_active(id)) && self.contains_active(&ret.unwrap())),
973 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),
974 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),
975 ensures(ret.is_none() || old(self.nodes.get(id).map(|node| node.to.clone())).unwrap() == self.nodes[&ret.unwrap()].to),
976 ensures(ret.is_none() || ret.unwrap() == old(self.nodes.get(id).and_then(|node| node.from)).unwrap()),
977 ensures(ret.is_some() || old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
978 ensures(ret.is_some() || old(self.active) == self.active),
979 ensures(ret.is_some() || old(self.bookmarked.clone()) == self.bookmarked),
980 ensures(old(self.roots.clone()) == self.roots),
981 invariant(self.validate())
982 ))]
983 fn merge_with_parent(&mut self, id: &K) -> Option<K> {
984 if let Some(mut node) = self.nodes.remove(id) {
985 if let Some(mut parent) = node.from.as_ref().and_then(|id| self.nodes.remove(id)) {
986 if parent.to.len() > 1 {
987 self.nodes.insert(parent.id, parent);
988 self.nodes.insert(node.id, node);
989 return None;
990 }
991
992 match parent.contents.merge(node.contents) {
993 DiscreteContentResult::Two(left, right) => {
994 parent.contents = left;
995 node.contents = right;
996 self.nodes.insert(parent.id, parent);
997 self.nodes.insert(node.id, node);
998 None
999 }
1000 DiscreteContentResult::One(content) => {
1001 parent.contents = content;
1002 parent.to = node.to;
1003
1004 for child in &parent.to {
1005 let child = self.nodes.get_mut(child).unwrap();
1006 child.from = Some(parent.id);
1007 }
1008
1009 if node.active {
1010 parent.active = true;
1011 self.active = Some(parent.id);
1012 }
1013
1014 let parent_id = parent.id;
1015
1016 if node.bookmarked && !parent.bookmarked {
1017 parent.bookmarked = true;
1018 assert!(
1019 self.bookmarked
1020 .replace_index(
1021 self.bookmarked.get_index_of(&node.id).unwrap(),
1022 parent.id,
1023 )
1024 .is_ok(),
1025 "Should be unreachable"
1026 );
1027 } else {
1028 self.bookmarked.shift_remove(&node.id);
1029 }
1030
1031 self.nodes.insert(parent.id, parent);
1032
1033 Some(parent_id)
1034 }
1035 }
1036 } else {
1037 self.nodes.insert(node.id, node);
1038 None
1039 }
1040 } else {
1041 None
1042 }
1043 }
1044}
1045
1046impl<K, T, M, S> SemiIndependentWeave<K, DependentNode<K, T, S>, T> for DependentWeave<K, T, M, S>
1047where
1048 K: Hash + Copy + Eq + Ord,
1049 T: IndependentContents,
1050 S: BuildHasher + Default + Clone,
1051{
1052 #[cfg_attr(debug_assertions, contract(
1053 ensures(ret.is_some() == old(self.nodes.contains_key(id))),
1054 ensures(old(self.nodes.keys().copied().collect::<HashSet<_>>()) == self.nodes.keys().copied().collect::<HashSet<_>>()),
1055 ensures(old(self.roots.clone()) == self.roots),
1056 ensures(old(self.active) == self.active),
1057 ensures(old(self.bookmarked.clone()) == self.bookmarked),
1058 invariant(self.validate())
1059 ))]
1060 #[inline]
1061 fn get_contents_mut<O>(&mut self, id: &K, callback: impl FnOnce(&mut T) -> O) -> Option<O> {
1062 self.nodes
1063 .get_mut(id)
1064 .map(|node| callback(&mut node.contents))
1065 }
1066}
1067
1068#[cfg(feature = "rkyv")]
1069impl<K, T, S> ArchivedDependentNode<K, T, S>
1070where
1071 K: Archive + Hash + Copy + Eq + Ord,
1072 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1073 T: Archive,
1074 S: BuildHasher + Default + Clone,
1075{
1076 #[inline]
1077 fn validate(&self) -> bool {
1078 (if let ArchivedOption::Some(from) = &self.from {
1079 !self.to.contains(from)
1080 } else {
1081 true
1082 }) && self.from != Some(self.id)
1083 && !self.to.contains(&self.id)
1084 }
1085}
1086
1087#[cfg(feature = "rkyv")]
1088impl<K, T, S> Node<K::Archived, T::Archived> for ArchivedDependentNode<K, T, S>
1089where
1090 K: Archive + Hash + Copy + Eq + Ord,
1091 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1092 T: Archive,
1093 S: BuildHasher + Default + Clone,
1094{
1095 type From = ArchivedOption<K::Archived>;
1096 type To = ArchivedIndexSet<K::Archived>;
1097
1098 #[inline]
1099 fn id(&self) -> K::Archived {
1100 self.id
1101 }
1102 #[inline]
1103 fn from(&self) -> &Self::From {
1104 &self.from
1105 }
1106 #[inline]
1107 fn to(&self) -> &Self::To {
1108 &self.to
1109 }
1110 #[inline]
1111 fn is_active(&self) -> bool {
1112 self.active
1113 }
1114 #[inline]
1115 fn contents(&self) -> &T::Archived {
1116 &self.contents
1117 }
1118}
1119
1120#[cfg(feature = "rkyv")]
1121impl<K, T, M, S> ArchivedDependentWeave<K, T, M, S>
1122where
1123 K: Archive + Hash + Copy + Eq + Ord,
1124 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1125 T: Archive,
1126 M: Archive,
1127 S: BuildHasher + Default + Clone,
1128{
1129 fn validate(&self) -> bool {
1130 let mut scratchpad = Vec::with_capacity(self.nodes.len());
1131 let mut scratchpad_set = HashSet::with_capacity(self.nodes.len());
1132
1133 self.roots
1134 .iter()
1135 .all(move |value| self.nodes.contains_key(value))
1136 && self
1137 .active
1138 .as_ref()
1139 .is_none_or(|active| self.nodes.contains_key(active))
1140 && self
1141 .bookmarked
1142 .iter()
1143 .all(move |value| self.nodes.contains_key(value))
1144 && self.nodes.iter().all(|(key, value)| {
1145 value.validate()
1146 && value.id == *key
1147 && value
1148 .from
1149 .as_ref()
1150 .is_none_or(|v| self.nodes.get(v).is_some_and(|p| p.to.contains(key)))
1151 && value.to.iter().all(|v| {
1152 self.nodes
1153 .get(v)
1154 .is_some_and(|p| p.from.as_ref() == Some(key))
1155 })
1156 && value.from.is_none() == self.roots.contains(key)
1157 && value.active == (self.active == Some(*key))
1158 && value.bookmarked == self.bookmarked.contains(key)
1159 })
1160 && !archived_detect_cycles(
1161 &self.nodes,
1162 self.roots.iter().copied(),
1163 &mut scratchpad,
1164 &mut scratchpad_set,
1165 )
1166 }
1167}
1168
1169#[cfg(feature = "rkyv")]
1170unsafe impl<K, T, M, S, C> Verify<C> for ArchivedDependentWeave<K, T, M, S>
1173where
1174 K: Archive + Hash + Copy + Eq + Ord,
1175 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1176 T: Archive,
1177 M: Archive,
1178 S: BuildHasher + Default + Clone,
1179 C: Fallible + ?Sized,
1180 C::Error: Source,
1181{
1182 fn verify(&self, _context: &mut C) -> Result<(), C::Error> {
1183 if !self.validate() {
1184 fail!(ValidationError)
1185 }
1186
1187 Ok(())
1188 }
1189}
1190
1191#[cfg(feature = "rkyv")]
1192impl<K, T, M, S> ImmutableWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1193 for ArchivedDependentWeave<K, T, M, S>
1194where
1195 K: Archive + Hash + Copy + Eq + Ord,
1196 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1197 T: Archive,
1198 M: Archive,
1199 S: BuildHasher + Default + Clone,
1200{
1201 type Nodes = ArchivedHashMap<K::Archived, ArchivedDependentNode<K, T, S>>;
1202 type Roots = ArchivedIndexSet<K::Archived>;
1203
1204 #[inline]
1205 fn len(&self) -> usize {
1206 self.nodes.len()
1207 }
1208 #[inline]
1209 fn is_empty(&self) -> bool {
1210 self.nodes.is_empty()
1211 }
1212 #[inline]
1213 fn nodes(&self) -> &Self::Nodes {
1214 &self.nodes
1215 }
1216 #[inline]
1217 fn roots(&self) -> &Self::Roots {
1218 &self.roots
1219 }
1220 #[inline]
1221 fn contains(&self, id: &K::Archived) -> bool {
1222 self.nodes.contains_key(id)
1223 }
1224 #[inline]
1225 fn contains_active(&self, id: &K::Archived) -> bool {
1226 self.active == Some(*id)
1227 }
1228 #[inline]
1229 fn get(&self, id: &K::Archived) -> Option<&ArchivedDependentNode<K, T, S>> {
1230 self.nodes.get(id)
1231 }
1232 #[inline]
1233 fn get_parents(&self, id: &K::Archived) -> Option<&ArchivedOption<K::Archived>> {
1234 self.nodes.get(id).map(|node| &node.from)
1235 }
1236 #[inline]
1237 fn get_children(&self, id: &K::Archived) -> Option<&ArchivedIndexSet<K::Archived>> {
1238 self.nodes.get(id).map(|node| &node.to)
1239 }
1240 #[inline]
1241 fn get_contents(&self, id: &K::Archived) -> Option<&T::Archived> {
1242 self.nodes.get(id).map(|node| &node.contents)
1243 }
1244 fn get_ordered_identifiers(&self, output: &mut Vec<K::Archived>) {
1245 output.clear();
1246
1247 let mut scratchpad = Vec::with_capacity(self.len());
1248 let mut scratchpad_2 = Vec::with_capacity(self.len());
1249
1250 for root in self.roots.iter() {
1251 archived_topological_sort(
1252 &self.nodes,
1253 *root,
1254 &mut scratchpad,
1255 &mut scratchpad_2,
1256 output,
1257 );
1258 }
1259 }
1260 fn get_ordered_identifiers_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
1261 output.clear();
1262
1263 if self.nodes.contains_key(id) {
1264 let mut scratchpad = Vec::with_capacity(self.len());
1265 let mut scratchpad_2 = Vec::with_capacity(self.len());
1266
1267 archived_topological_sort(&self.nodes, *id, &mut scratchpad, &mut scratchpad_2, output);
1268 }
1269 }
1270 fn get_active_path(&self, output: &mut Vec<K::Archived>) {
1271 output.clear();
1272
1273 if let ArchivedOption::Some(active) = self.active {
1274 archived_path_to_root(&self.nodes, active, output);
1275 }
1276 }
1277 fn get_path_from(&self, id: &K::Archived, output: &mut Vec<K::Archived>) {
1278 output.clear();
1279
1280 if self.nodes.contains_key(id) {
1281 archived_path_to_root(&self.nodes, *id, output);
1282 }
1283 }
1284}
1285
1286#[cfg(feature = "rkyv")]
1287impl<K, T, M, S>
1288 ImmutableMetadataWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived, M::Archived>
1289 for ArchivedDependentWeave<K, T, M, S>
1290where
1291 K: Archive + Hash + Copy + Eq + Ord,
1292 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1293 T: Archive,
1294 M: Archive,
1295 S: BuildHasher + Default + Clone,
1296{
1297 #[inline]
1298 fn metadata(&self) -> &M::Archived {
1299 &self.metadata
1300 }
1301}
1302
1303#[cfg(feature = "rkyv")]
1304impl<K, T, M, S>
1305 ImmutableBookmarkableWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1306 for ArchivedDependentWeave<K, T, M, S>
1307where
1308 K: Archive + Hash + Copy + Eq + Ord,
1309 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1310 T: Archive,
1311 M: Archive,
1312 S: BuildHasher + Default + Clone,
1313{
1314 type Bookmarks = ArchivedIndexSet<K::Archived>;
1315
1316 #[inline]
1317 fn bookmarks(&self) -> &Self::Bookmarks {
1318 &self.bookmarked
1319 }
1320 #[inline]
1321 fn contains_bookmark(&self, id: &K::Archived) -> bool {
1322 self.bookmarked.contains(id)
1323 }
1324}
1325
1326#[cfg(feature = "rkyv")]
1327impl<K, T, M, S>
1328 ImmutableActiveSingularWeave<K::Archived, ArchivedDependentNode<K, T, S>, T::Archived>
1329 for ArchivedDependentWeave<K, T, M, S>
1330where
1331 K: Archive + Hash + Copy + Eq + Ord,
1332 <K as Archive>::Archived: Hash + Copy + Eq + Ord + 'static,
1333 T: Archive,
1334 M: Archive,
1335 S: BuildHasher + Default + Clone,
1336{
1337 #[inline]
1338 fn active(&self) -> Option<K::Archived> {
1339 match self.active {
1340 ArchivedOption::Some(active) => Some(active),
1341 ArchivedOption::None => None,
1342 }
1343 }
1344}
1345
1346fn path_to_root<K, T, S>(
1347 nodes: &HashMap<K, DependentNode<K, T, S>, S>,
1348 mut id: K,
1349 thread: &mut Vec<K>,
1350) where
1351 K: Hash + Copy + Eq + Ord,
1352 S: BuildHasher + Default + Clone,
1353{
1354 thread.push(id);
1355
1356 while let Some(parent) = nodes[&id].from {
1357 thread.push(parent);
1358 id = parent;
1359 }
1360}
1361
1362fn topological_sort<K, N, T, S>(
1363 nodes: &HashMap<K, N, S>,
1364 id: K,
1365 scratchpad: &mut Vec<K>,
1366 identifiers: &mut Vec<K>,
1367) where
1368 K: Hash + Copy + Eq + Ord,
1369 N: Node<K, T, From = Option<K>, To = IndexSet<K, S>>,
1370 S: BuildHasher + Default + Clone,
1371{
1372 scratchpad.push(id);
1373
1374 while let Some(id) = scratchpad.pop() {
1375 identifiers.push(id);
1376 scratchpad.extend(nodes[&id].to().into_iter().rev().copied());
1377 }
1378}
1379fn detect_cycles<K, N, T, S>(
1380 nodes: &HashMap<K, N, S>,
1381 roots: impl Iterator<Item = K>,
1382 scratchpad: &mut Vec<K>,
1383 scratchpad_set: &mut HashSet<K, S>,
1384) -> bool
1385where
1386 K: Hash + Copy + Eq + Ord,
1387 N: Node<K, T, From = Option<K>, To = IndexSet<K, S>>,
1388 S: BuildHasher + Default + Clone,
1389{
1390 scratchpad.extend(roots);
1391
1392 while let Some(id) = scratchpad.pop() {
1393 if !scratchpad_set.insert(id) {
1394 return true;
1395 }
1396 scratchpad.extend(nodes[&id].to().into_iter().rev().copied());
1397 }
1398
1399 scratchpad_set.len() != nodes.len()
1400}
1401
1402#[cfg(feature = "rkyv")]
1403fn archived_path_to_root<K, T, S>(
1404 nodes: &ArchivedHashMap<K::Archived, ArchivedDependentNode<K, T, S>>,
1405 mut id: K::Archived,
1406 thread: &mut Vec<K::Archived>,
1407) where
1408 K: Archive + Hash + Copy + Eq + Ord,
1409 <K as Archive>::Archived: Hash + Copy + Eq + Ord,
1410 T: Archive,
1411 S: BuildHasher + Default + Clone,
1412{
1413 thread.push(id);
1414
1415 while let ArchivedOption::Some(parent) = nodes[&id].from {
1416 thread.push(parent);
1417 id = parent;
1418 }
1419}
1420
1421#[cfg(feature = "rkyv")]
1422fn archived_topological_sort<K, N, T>(
1423 nodes: &ArchivedHashMap<K, N>,
1424 id: K,
1425 scratchpad: &mut Vec<K>,
1426 scratchpad_2: &mut Vec<K>,
1427 identifiers: &mut Vec<K>,
1428) where
1429 K: Hash + Copy + Eq + Ord,
1430 N: Node<K, T, From = ArchivedOption<K>, To = ArchivedIndexSet<K>>,
1431{
1432 scratchpad.push(id);
1433
1434 while let Some(id) = scratchpad.pop() {
1435 identifiers.push(id);
1436 scratchpad_2.extend(nodes[&id].to().iter().copied());
1437 scratchpad_2.reverse();
1438 scratchpad.append(scratchpad_2);
1439 }
1440}
1441
1442#[cfg(feature = "rkyv")]
1443fn archived_detect_cycles<K, N, T, S>(
1444 nodes: &ArchivedHashMap<K, N>,
1445 roots: impl Iterator<Item = K>,
1446 scratchpad: &mut Vec<K>,
1447 scratchpad_set: &mut HashSet<K, S>,
1448) -> bool
1449where
1450 K: Hash + Copy + Eq + Ord,
1451 N: Node<K, T, From = ArchivedOption<K>, To = ArchivedIndexSet<K>>,
1452 S: BuildHasher + Default + Clone,
1453{
1454 scratchpad.extend(roots);
1455
1456 while let Some(id) = scratchpad.pop() {
1457 if !scratchpad_set.insert(id) {
1458 return true;
1459 }
1460 scratchpad.extend(nodes[&id].to().iter().copied());
1461 }
1462
1463 scratchpad_set.len() != nodes.len()
1464}