aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorKaiden Fey <kookie@spacekookie.de>2020-11-10 12:27:00 +0100
committerMx Kookie <kookie@spacekookie.de>2020-12-21 05:19:47 +0100
commitb2681a59d5dfae8afed0a6a8d46210133667532c (patch)
treeb6a62979d4a0abbd1183801aa70f9ae3bec18a7c /apps
parenta2513a72e699f0db1c345e952b336c6cbc912a3e (diff)
supergit: starting work on implementing branching iterators
Diffstat (limited to 'apps')
-rw-r--r--apps/servers/octopus/supergit/src/bin/test.rs16
-rw-r--r--apps/servers/octopus/supergit/src/branch.rs56
2 files changed, 64 insertions, 8 deletions
diff --git a/apps/servers/octopus/supergit/src/bin/test.rs b/apps/servers/octopus/supergit/src/bin/test.rs
index b7dba0379df3..cb21d5c25645 100644
--- a/apps/servers/octopus/supergit/src/bin/test.rs
+++ b/apps/servers/octopus/supergit/src/bin/test.rs
@@ -22,12 +22,12 @@ fn main() {
let head = main.get_head();
let tree = head.get_tree();
-
- println!(
- "{:?}",
- tree.history(main.get_all(), "Cargo.toml")
- .into_iter()
- .map(|c| c.summary())
- .collect::<Vec<_>>()
- );
+
+ // println!(
+ // "{:?}",
+ // tree.history(main.get_all(), "infra/libkookie/nixpkgs/nixos/modules/module-list.nix")
+ // .into_iter()
+ // .map(|c| c.summary())
+ // .collect::<Vec<_>>()
+ // );
}
diff --git a/apps/servers/octopus/supergit/src/branch.rs b/apps/servers/octopus/supergit/src/branch.rs
index 3261d23b9177..6b838f4ff420 100644
--- a/apps/servers/octopus/supergit/src/branch.rs
+++ b/apps/servers/octopus/supergit/src/branch.rs
@@ -1,4 +1,5 @@
use crate::{Commit, HashId};
+use atomptr::AtomPtr;
use git2::Repository;
use std::{mem, sync::Arc};
@@ -124,6 +125,8 @@ impl Branch {
/// handles. This means that without explicitly branching, this
/// iterator is first-parent.
pub struct BranchIter {
+ rec: AtomPtr<IterMode>,
+ splits: AtomPtr<Vec<HashId>>,
repo: Arc<Repository>,
curr: Option<HashId>,
limit: SegLimit,
@@ -133,6 +136,8 @@ impl BranchIter {
/// Create a new branch segment iterator
fn new(repo: Arc<Repository>, last: HashId, limit: SegLimit) -> Self {
Self {
+ rec: AtomPtr::new(IterMode::FirstParent),
+ splits: AtomPtr::new(vec![]),
repo,
curr: Some(last),
limit,
@@ -214,6 +219,25 @@ impl Iterator for BranchIter {
}
}
+/// Specify the mode of a branch iterator
+///
+/// The default value is `FirstParent`, meaning that merged branches
+/// will create a new `Branch` handle that the user must iterate
+/// manually.
+///
+/// This is a reasonable default, but means that history searches for
+/// files become more tedious. To improve this use-case, iterators
+/// can internally be set to change their iteration behaviour, meaning
+/// that returned commits are always `BranchCommit::Commit`, and can
+pub enum IterMode {
+ /// Default value, iterating only first-parent commits
+ FirstParent,
+ /// Iterate a branch to completion, before picking the next
+ DepthFirst,
+ /// Iterate branches as they come up
+ BreadthFirst,
+}
+
/// the limit applied to a branch segment
pub enum SegLimit {
/// No limit, enumerating all children
@@ -259,3 +283,35 @@ impl BranchCommit {
}
}
}
+
+/// Additional iterator data
+struct IterData {
+ splits: AtomPtr<Vec<HashId>>,
+}
+
+impl IterData {
+ fn new() -> Self {
+ Self {
+ splits: AtomPtr::new(vec![]),
+ }
+ }
+
+ fn append(&self, id: HashId) {
+ let mut vec = (**self.splits.get_ref()).clone();
+ let mut new = vec![id];
+ new.append(&mut vec);
+ self.splits.swap(new);
+ }
+
+ fn next(&self) -> Option<HashId> {
+ let mut vec = (**self.splits.get_ref()).clone();
+ let next = if vec.len() < 0 {
+ Some(vec.remove(0))
+ } else {
+ None
+ };
+
+ self.splits.swap(vec);
+ next
+ }
+}