Patchwork [2,of,4,V2] obsolete: add a filteredmarkerdict class

login
register
mail settings
Submitter Jun Wu
Date March 13, 2017, 9:48 a.m.
Message ID <09a30f1a2da8d17d4781.1489398494@localhost.localdomain>
Download mbox | patch
Permalink /patch/19281/
State Changes Requested
Delegated to: Jun Wu
Headers show

Comments

Jun Wu - March 13, 2017, 9:48 a.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1489386664 25200
#      Sun Mar 12 23:31:04 2017 -0700
# Node ID 09a30f1a2da8d17d4781b1a66a282265138f4f29
# Parent  dec2b2328ef19c166f0ed1cb711b6c99dc9c590a
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 09a30f1a2da8
obsolete: add a filteredmarkerdict class

See the previous patch for motivation. This allows us to make markers
invisible on demand.

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -517,4 +517,41 @@  def _checkinvalidmarkers(markers):
                                'invalid successors nullid'))
 
+class filteredmarkerdict(dict):
+    """a dict where its values (markers) are filtered when accessed
+
+    Markers with date <= _nodeversions.get(precursor, -1) will be filtered.
+    """
+
+    def __init__(self, nodeversions):
+        self._nodeversions = nodeversions
+
+    def get(self, key, default=None):
+        self._filter(key)
+        return super(filteredmarkerdict, self).get(key, default)
+
+    def __contains__(self, key):
+        self._filter(key)
+        return super(filteredmarkerdict, self).__contains__(key)
+
+    def _filter(self, key):
+        markers = super(filteredmarkerdict, self).get(key, None)
+        if markers is None:
+            return
+        filtered = []
+        for m in markers:
+            prec = m[0]
+            pver = self._nodeversions.get(prec, -1)
+            date = m[4][0]
+            if date <= pver:
+                filtered.append(m)
+        if not filtered:
+            return
+        # We can mutate the set, because nodeversions can only be updated with
+        # newer dates. The items being removed won't be revived later.
+        if len(filtered) == len(markers):
+            del self[key]
+            return
+        self[key] = set(x for x in markers if x not in filtered)
+
 class obsstore(object):
     """Store obsolete markers