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