4141//! Ok(finalize(dependency_graph_so_far))
4242//! }
4343//! }
44+ //!
45+ //! fn activate(&mut dependency_graph: _, &mut unresolved_dependencies: _, candidate:_) -> Result<(), Problem> {
46+ //! // check that we can use candidate given the other selected packages
47+ //! if semver conflict { return Err(Problem::Semver); };
48+ //! if links conflict { return Err(Problem::Links); };
49+ //! ...
50+ //! // update other state
51+ //! if used a [replace] section { update that lookup table };
52+ //! if used a [patch] section { update that lookup table };
53+ //! update activated features
54+ //! ...
55+ //! // add candidate to dependency_graph
56+ //! dependency_graph.add_edge(candidate.parent, candidate.id, candidate.dependency);
57+ //! // add candidate's dependencies to the list to be resolved
58+ //! unresolved_dependencies.extend(candidate.dependencies);
59+ //! Ok(())
60+ //! }
4461//! ```
4562//!
46- //! The real resolver is not recursive to avoid blowing the stack, and has lots of other state to
47- //! maintain. The most expensive (non recursive) call in this algorithm is the
48- //! `dependency_graph_so_far.clone();`. To make this more annoying the first thing we try will
49- //! probably work, and any work we do to prepare for the next iteration is wasted. If we had a
50- //! `undo_activate` we could be much more efficient, completely remove the `.clone()` and just
51- //! `undo_activate` if things tern out to not work. Unfortunately, making sure `undo_activate`
52- //! handles all the corner cases correctly is not practical for the resolver. However, this is
53- //! possible for a graph like thing, a `clone` means record the size of the graph. a `&mut self`
54- //! method means undo everything newer and do the mutation, a `&self` method means only look at the
55- //! older part. This module provides a `StackGraph` type to encapsulate this pattern.
63+ //! The real resolver is not recursive to avoid blowing the stack. The most expensive
64+ //! (non recursive) call in this algorithm is the `dependency_graph_so_far.clone();`.
65+ //! To make this more annoying the first thing we try will probably work, and any work we do to
66+ //! prepare for the next iteration is wasted. If we had a `undo_activate` we could be much more efficient,
67+ //! completely remove the `.clone()` and just `undo_activate` if things tern out to not work.
68+ //! Unfortunately, making sure `undo_activate` handles all the corner cases correctly is not
69+ //! practical for the resolver. However, this is possible for a graph like thing, a `clone` means
70+ //! record the size of the graph. a `&mut self` method means undo everything newer and do the
71+ //! mutation, a `&self` method means only look at the older part. This module provides a
72+ //! `StackGraph` type to encapsulate this pattern.
5673
5774use indexmap:: IndexMap ;
5875use std:: borrow:: Borrow ;
@@ -64,6 +81,10 @@ use std::rc::Rc;
6481
6582type EdgeIndex = usize ;
6683
84+ /// This stores one Edge or Link element. If the two Nodes have data to connect them then we say it
85+ /// is an Edge and the `value` is `Some(E)`, if the two Nodes did not have data then we say it is a
86+ /// Link and the `value` is `None`. If there are other `EdgeLink`s associated with the same two Nodes,
87+ /// then we make a index based doubly linked list using the `next` and `previous` fields.
6788#[ derive( Clone , Debug ) ]
6889struct EdgeLink < E : Clone > {
6990 value : Option < E > ,
@@ -79,11 +100,13 @@ struct EdgeLink<E: Clone> {
79100/// that efficiently undoes the most reason modifications.
80101#[ derive( Clone ) ]
81102pub struct Graph < N : Clone , E : Clone > {
82- /// an index based linked list of the edge data for links. This maintains insertion order.
103+ /// An index based linked list of the edge data. This maintains insertion order.
104+ /// If the connection has data associated with it then that Edge is stored here.
105+ /// If the connection has no data associated with it then that Link is represented with a dummy here.
83106 edges : Vec < EdgeLink < E > > ,
84- /// a hashmap that stores the set of nodes. This is an `IndexMap` so it maintains insertion order .
85- /// For each node it stores all the other nodes that it links to .
86- /// For each link it stores the first index into `edges` .
107+ /// A map from a "from" node to (a map of "to" node to the starting index in the `edges`) .
108+ /// The inner map may be empty to represent a Node that was `add` but not connected to anything .
109+ /// The maps are `IndexMap`s so they maintains insertion order .
87110 nodes : indexmap:: IndexMap < N , indexmap:: IndexMap < N , EdgeIndex > > ,
88111}
89112
@@ -402,7 +425,7 @@ impl<N: Eq + Hash + Clone, E: Eq + Clone> Eq for Graph<N, E> {}
402425/// - the clone has no overhead to read the `Graph` as it was
403426/// - no overhead over using the `Graph` directly when modifying the biggest clone
404427/// Is this too good to be true?
405- /// - If a modification (`&mut` method) is done to a smaller older clone then a full `O(N)`
428+ /// - If a modification (`&mut` method) is done to a clone that is not the largest then a full `O(N)`
406429/// deep clone will happen internally.
407430pub struct StackGraph < N : Clone , E : Clone > {
408431 /// The `Graph` shared by all clones, this `StackGraph` refers to only the prefix of size `age`
0 commit comments