# HG changeset patch # User Pierre-Yves David # Date 2022-05-20 10:02:52 # Node ID 5846bc8a285540e74dfe3cad5aecf0adfd04b086 # Parent d513ae93dff31eb3119f21dc05f1b01cbbd98935 revlog: finer computation of "issnapshot" If the parent had an empty diff, we skip of it to compute a diff against the parent base. This create shorter and simpler chain. However these case could be wrongly detected as snapshot. So we improve the code doing this detection. In practice nobody care as when tried on a copy of mozilla-try and we got the same number of snapshot (1315) in both case. Performance where equivalent. diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -1382,6 +1382,7 @@ static inline int index_baserev(indexObj static int index_issnapshotrev(indexObject *self, Py_ssize_t rev) { int ps[2]; + int b; Py_ssize_t base; while (rev >= 0) { base = (Py_ssize_t)index_baserev(self, rev); @@ -1399,6 +1400,20 @@ static int index_issnapshotrev(indexObje assert(PyErr_Occurred()); return -1; }; + while ((index_get_length(self, ps[0]) == 0) && ps[0] >= 0) { + b = index_baserev(self, ps[0]); + if (b == ps[0]) { + break; + } + ps[0] = b; + } + while ((index_get_length(self, ps[1]) == 0) && ps[1] >= 0) { + b = index_baserev(self, ps[1]); + if (b == ps[1]) { + break; + } + ps[1] = b; + } if (base == ps[0] || base == ps[1]) { return 0; } diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -1775,7 +1775,17 @@ class revlog: if base == nullrev: return True p1 = entry[5] + while self.length(p1) == 0: + b = self.deltaparent(p1) + if b == p1: + break + p1 = b p2 = entry[6] + while self.length(p2) == 0: + b = self.deltaparent(p2) + if b == p2: + break + p2 = b if base == p1 or base == p2: return False return self.issnapshot(base)