[PATCH 1 of 6] filelog: extract metadata parsing and packing

Sune Foldager cryo at cyanite.org
Mon Jan 31 04:21:39 CST 2011


# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1296295790 -3600
# Node ID 90afd2364f5d05afe149156379fc3ee6dfd604fe
# Parent  0d1dca7d2a041cb1cb6c6bd90608aa87068bde02
filelog: extract metadata parsing and packing

_parsemeta returns the dictionary and a list of keys in the order they appear
in metadata. This can be used to repack the dictionary in the same order.

_packmeta creates metadata from a dictionary and an optional key-order list.

In _parsemeta, we use slices and re.search indead of str.index so we can accept
both buffers and strings.

diff --git a/mercurial/filelog.py b/mercurial/filelog.py
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -6,17 +6,7 @@
 # GNU General Public License version 2 or any later version.
 
 import revlog
-
-def _parsemeta(text):
-    if not text.startswith('\1\n'):
-        return {}
-    s = text.index('\1\n', 2)
-    mt = text[2:s]
-    m = {}
-    for l in mt.splitlines():
-        k, v = l.split(": ", 1)
-        m[k] = v
-    return m
+import re
 
 class filelog(revlog.revlog):
     def __init__(self, opener, path):
@@ -32,15 +22,14 @@
 
     def add(self, text, meta, transaction, link, p1=None, p2=None):
         if meta or text.startswith('\1\n'):
-            mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
-            text = "\1\n%s\1\n%s" % ("".join(mt), text)
+            text = "\1\n%s\1\n%s" % (_packmeta(meta), text)
         return self.addrevision(text, transaction, link, p1, p2)
 
     def renamed(self, node):
         if self.parents(node)[0] != revlog.nullid:
             return False
         t = self.revision(node)
-        m = _parsemeta(t)
+        m = _parsemeta(t)[0]
         if m and "copy" in m:
             return (m["copy"], revlog.bin(m["copyrev"]))
         return False
@@ -77,3 +66,23 @@
             return t2 != text
 
         return True
+
+_mdre = re.compile('\1\n')
+def _parsemeta(text):
+    # text can be buffer, so we can't use .startswith or .index
+    if text[:2] != '\1\n':
+        return None, None, None
+    s = _mdre.search(text, 2).start()
+    mtext = text[2:s]
+    meta = {}
+    keys = []
+    for l in mtext.splitlines():
+        k, v = l.split(": ", 1)
+        meta[k] = v
+        keys.append(k)
+    return meta, keys, (s + 2)
+
+def _packmeta(meta, keys=None):
+    if not keys:
+        keys = sorted(meta.iterkeys())
+    return "".join("%s: %s\n" % (k, meta[k]) for k in keys)


More information about the Mercurial-devel mailing list