cob: Simplify graph builder
Since we use `Oid` as the primary graph index, there's no need to keep a separate index. Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
parent
57fcb117fc
commit
70260236b2
|
|
@ -3,10 +3,7 @@
|
||||||
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
|
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
|
||||||
// Linking Exception. For full terms see the included LICENSE file.
|
// Linking Exception. For full terms see the included LICENSE file.
|
||||||
|
|
||||||
use std::{
|
use std::{collections::BTreeSet, convert::TryInto};
|
||||||
collections::{hash_map::Entry, BTreeSet, HashMap},
|
|
||||||
convert::TryInto,
|
|
||||||
};
|
|
||||||
|
|
||||||
use git_ext::Oid;
|
use git_ext::Oid;
|
||||||
use radicle_dag::{Dag, Node};
|
use radicle_dag::{Dag, Node};
|
||||||
|
|
@ -87,9 +84,7 @@ impl ChangeGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a graph evaluate it to produce a collaborative object. This will
|
/// Given a graph evaluate it to produce a collaborative object. This will
|
||||||
/// filter out branches of the graph which do not have valid signatures,
|
/// filter out branches of the graph which do not have valid signatures.
|
||||||
/// or which do not have permission to make a change, or which make a
|
|
||||||
/// change which invalidates the schema of the object
|
|
||||||
pub(crate) fn evaluate(&self) -> CollaborativeObject {
|
pub(crate) fn evaluate(&self) -> CollaborativeObject {
|
||||||
let mut roots: Vec<(&Oid, &Node<_, _>)> = self.graph.roots().collect();
|
let mut roots: Vec<(&Oid, &Node<_, _>)> = self.graph.roots().collect();
|
||||||
roots.sort_by_key(|(k, _)| *k);
|
roots.sort_by_key(|(k, _)| *k);
|
||||||
|
|
@ -98,21 +93,21 @@ impl ChangeGraph {
|
||||||
let (root, root_node) = roots.first().unwrap();
|
let (root, root_node) = roots.first().unwrap();
|
||||||
let manifest = root_node.manifest.clone();
|
let manifest = root_node.manifest.clone();
|
||||||
let rng = fastrand::Rng::new();
|
let rng = fastrand::Rng::new();
|
||||||
let sorted = self.graph.sorted(rng);
|
let items = self.graph.sorted(rng).into_iter().map(|oid| {
|
||||||
let items = sorted.iter().map(|oid| {
|
let node = &self.graph[&oid];
|
||||||
let node = &self.graph[oid];
|
|
||||||
let child_commits = node
|
let child_commits = node
|
||||||
.dependents
|
.dependents
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| *self.graph[e].id())
|
.map(|e| *self.graph[e].id())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
(&node.value, *oid, child_commits)
|
(&node.value, oid, child_commits)
|
||||||
});
|
});
|
||||||
let history = {
|
let history = {
|
||||||
let root_change = &self.graph[*root];
|
let root_change = &self.graph[*root];
|
||||||
evaluate(*root_change.id(), &self.graph, items)
|
evaluate(*root_change.id(), &self.graph, items)
|
||||||
};
|
};
|
||||||
|
|
||||||
CollaborativeObject {
|
CollaborativeObject {
|
||||||
manifest,
|
manifest,
|
||||||
history,
|
history,
|
||||||
|
|
@ -131,16 +126,12 @@ impl ChangeGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GraphBuilder {
|
struct GraphBuilder {
|
||||||
node_indices: HashMap<Oid, Oid>,
|
|
||||||
graph: Dag<Oid, Change>,
|
graph: Dag<Oid, Change>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GraphBuilder {
|
impl Default for GraphBuilder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GraphBuilder {
|
GraphBuilder { graph: Dag::new() }
|
||||||
node_indices: HashMap::new(),
|
|
||||||
graph: Dag::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,12 +145,11 @@ impl GraphBuilder {
|
||||||
) -> impl Iterator<Item = (object::Commit, Oid)> + '_ {
|
) -> impl Iterator<Item = (object::Commit, Oid)> + '_ {
|
||||||
let resource_commit = *change.resource();
|
let resource_commit = *change.resource();
|
||||||
let commit_id = commit.id;
|
let commit_id = commit.id;
|
||||||
if let Entry::Vacant(e) = self.node_indices.entry(commit_id) {
|
|
||||||
self.graph.node(commit_id, change);
|
self.graph.node(commit_id, change);
|
||||||
e.insert(commit_id);
|
|
||||||
}
|
|
||||||
commit.parents.into_iter().filter_map(move |parent| {
|
commit.parents.into_iter().filter_map(move |parent| {
|
||||||
if parent.id != resource_commit && !self.has_dependency(commit_id, parent.id) {
|
if parent.id != resource_commit && !self.graph.has_dependency(&commit_id, &parent.id) {
|
||||||
Some((parent, commit_id))
|
Some((parent, commit_id))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -167,26 +157,8 @@ impl GraphBuilder {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_dependency(&mut self, child_id: Oid, parent_id: Oid) -> bool {
|
|
||||||
let parent_ix = self.node_indices.get(&parent_id);
|
|
||||||
let child_ix = self.node_indices.get(&child_id);
|
|
||||||
match (parent_ix, child_ix) {
|
|
||||||
(Some(parent_ix), Some(child_ix)) => self.graph.has_dependency(child_ix, parent_ix),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_edge(&mut self, child: Oid, parent: Oid) {
|
fn add_edge(&mut self, child: Oid, parent: Oid) {
|
||||||
// This panics if the child or parent ids are not in the graph already
|
self.graph.dependency(child, parent);
|
||||||
let child_id = self
|
|
||||||
.node_indices
|
|
||||||
.get(&child)
|
|
||||||
.expect("BUG: child id expected to be in graph");
|
|
||||||
let parent_id = self
|
|
||||||
.node_indices
|
|
||||||
.get(&parent)
|
|
||||||
.expect("BUG: parent id expected to in graph");
|
|
||||||
self.graph.dependency(*child_id, *parent_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build(self, object_id: ObjectId) -> Option<ChangeGraph> {
|
fn build(self, object_id: ObjectId) -> Option<ChangeGraph> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue