Patchwork [2,of,4] rust-ancestors: duplicate loop that visits parents of revs/bases

login
register
mail settings
Submitter Yuya Nishihara
Date Jan. 6, 2019, 3:54 a.m.
Message ID <01b61bcb9abd37024369.1546746845@mimosa>
Download mbox | patch
Permalink /patch/37491/
State Accepted
Headers show

Comments

Yuya Nishihara - Jan. 6, 2019, 3:54 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1545223868 -32400
#      Wed Dec 19 21:51:08 2018 +0900
# Node ID 01b61bcb9abd37024369ce80eb2c585d47add935
# Parent  e87cc0ce61a67f7fbc9c12ab1505a23e23b8217d
rust-ancestors: duplicate loop that visits parents of revs/bases

As the inline comment says, it can't be cleanly implemented in Rust. It's
better to duplicate the code instead of inserting "if"s. The loop will be
cleaned up by future commits.

Patch

diff --git a/rust/hg-core/src/ancestors.rs b/rust/hg-core/src/ancestors.rs
--- a/rust/hg-core/src/ancestors.rs
+++ b/rust/hg-core/src/ancestors.rs
@@ -345,14 +345,6 @@  impl<G: Graph> MissingAncestors<G> {
             if revs_visit.remove(&curr) {
                 missing.push(curr);
                 this_visit_is_revs = true;
-            } else if bases_visit.contains(&curr) {
-                this_visit_is_revs = false;
-            } else {
-                // not an ancestor of revs or bases: ignore
-                continue;
-            }
-
-            {
                 for p in self.graph.parents(curr)?.iter().cloned() {
                     if p == NULL_REVISION {
                         continue;
@@ -378,6 +370,35 @@  impl<G: Graph> MissingAncestors<G> {
                         }
                     }
                 }
+            } else if bases_visit.contains(&curr) {
+                this_visit_is_revs = false;
+                for p in self.graph.parents(curr)?.iter().cloned() {
+                    if p == NULL_REVISION {
+                        continue;
+                    }
+                    let in_other_visit = if this_visit_is_revs {
+                        bases_visit.contains(&p)
+                    } else {
+                        revs_visit.contains(&p)
+                    };
+                    if in_other_visit || both_visit.contains(&p) {
+                        // p is implicitely in this_visit.
+                        // This means p is or should be in bothvisit
+                        // TODO optim: hence if bothvisit, we look up twice
+                        revs_visit.remove(&p);
+                        bases_visit.insert(p);
+                        both_visit.insert(p);
+                    } else {
+                        // visit later
+                        if this_visit_is_revs {
+                            revs_visit.insert(p);
+                        } else {
+                            bases_visit.insert(p);
+                        }
+                    }
+                }
+            } else {
+                // not an ancestor of revs or bases: ignore
             }
         }
         missing.reverse();