manifest: extract method for parsing manifest
authorMartin von Zweigbergk <martinvonz@google.com>
Fri, 27 Mar 2015 15:02:43 -0700
changeset 24524 63b6031384fc
parent 24523 a4b81dbe73c1
child 24525 e118f74d246f
manifest: extract method for parsing manifest By extracting a method that generates (path, node, flags) tuples, we can reuse the code for parsing a manifest without doing it via a _lazymanifest like treemanifest currently does. It also prepares for parsing the new manifest format. Note that this makes parsing into treemanifest slower, since the parsing is now always done in pure Python. Since treemanifests will be expected (or even forced) to be used only with the new manifest format, parsing via _lazymanifest was not an option anyway.
mercurial/manifest.py
--- a/mercurial/manifest.py	Sun Mar 29 18:28:48 2015 -0700
+++ b/mercurial/manifest.py	Fri Mar 27 15:02:43 2015 -0700
@@ -11,6 +11,26 @@
 
 propertycache = util.propertycache
 
+def _parse(data):
+    """Generates (path, node, flags) tuples from a manifest text"""
+    # This method does a little bit of excessive-looking
+    # precondition checking. This is so that the behavior of this
+    # class exactly matches its C counterpart to try and help
+    # prevent surprise breakage for anyone that develops against
+    # the pure version.
+    if data and data[-1] != '\n':
+        raise ValueError('Manifest did not end in a newline.')
+    prev = None
+    for l in data.splitlines():
+        if prev is not None and prev > l:
+            raise ValueError('Manifest lines not in sorted order.')
+        prev = l
+        f, n = l.split('\0')
+        if len(n) > 40:
+            yield f, revlog.bin(n[:40]), n[40:]
+        else:
+            yield f, revlog.bin(n), ''
+
 class _lazymanifest(dict):
     """This is the pure implementation of lazymanifest.
 
@@ -18,24 +38,9 @@
     """
 
     def __init__(self, data):
-        # This init method does a little bit of excessive-looking
-        # precondition checking. This is so that the behavior of this
-        # class exactly matches its C counterpart to try and help
-        # prevent surprise breakage for anyone that develops against
-        # the pure version.
-        if data and data[-1] != '\n':
-            raise ValueError('Manifest did not end in a newline.')
         dict.__init__(self)
-        prev = None
-        for l in data.splitlines():
-            if prev is not None and prev > l:
-                raise ValueError('Manifest lines not in sorted order.')
-            prev = l
-            f, n = l.split('\0')
-            if len(n) > 40:
-                self[f] = revlog.bin(n[:40]), n[40:]
-            else:
-                self[f] = revlog.bin(n), ''
+        for f, n, fl in _parse(data):
+            self[f] = n, fl
 
     def __setitem__(self, k, v):
         node, flag = v
@@ -342,8 +347,7 @@
         # Using _lazymanifest here is a little slower than plain old dicts
         self._files = {}
         self._flags = {}
-        lm = _lazymanifest(text)
-        for f, n, fl in lm.iterentries():
+        for f, n, fl in _parse(text):
             self[f] = n
             if fl:
                 self.setflag(f, fl)