comparison mercurial/filelog.py @ 14074:e8271159c8c2

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.
author Sune Foldager <cryo@cyanite.org>
date Sat, 30 Apr 2011 16:32:50 +0200
parents e5060aa22043
children 7c231754a621
comparison
equal deleted inserted replaced
14073:72c84f24b420 14074:e8271159c8c2
4 # 4 #
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 import revlog 8 import revlog
9 import re
9 10
11 _mdre = re.compile('\1\n')
10 def _parsemeta(text): 12 def _parsemeta(text):
11 if not text.startswith('\1\n'): 13 """return (metadatadict, keylist, metadatasize)"""
12 return {} 14 # text can be buffer, so we can't use .startswith or .index
13 s = text.index('\1\n', 2) 15 if text[:2] != '\1\n':
14 mt = text[2:s] 16 return None, None, None
15 m = {} 17 s = _mdre.search(text, 2).start()
16 for l in mt.splitlines(): 18 mtext = text[2:s]
19 meta = {}
20 keys = []
21 for l in mtext.splitlines():
17 k, v = l.split(": ", 1) 22 k, v = l.split(": ", 1)
18 m[k] = v 23 meta[k] = v
19 return m 24 keys.append(k)
25 return meta, keys, (s + 2)
26
27 def _packmeta(meta, keys=None):
28 if not keys:
29 keys = sorted(meta.iterkeys())
30 return "".join("%s: %s\n" % (k, meta[k]) for k in keys)
20 31
21 class filelog(revlog.revlog): 32 class filelog(revlog.revlog):
22 def __init__(self, opener, path): 33 def __init__(self, opener, path):
23 revlog.revlog.__init__(self, opener, 34 revlog.revlog.__init__(self, opener,
24 "/".join(("data", path + ".i"))) 35 "/".join(("data", path + ".i")))
30 s = t.index('\1\n', 2) 41 s = t.index('\1\n', 2)
31 return t[s + 2:] 42 return t[s + 2:]
32 43
33 def add(self, text, meta, transaction, link, p1=None, p2=None): 44 def add(self, text, meta, transaction, link, p1=None, p2=None):
34 if meta or text.startswith('\1\n'): 45 if meta or text.startswith('\1\n'):
35 mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())] 46 text = "\1\n%s\1\n%s" % (_packmeta(meta), text)
36 text = "\1\n%s\1\n%s" % ("".join(mt), text)
37 return self.addrevision(text, transaction, link, p1, p2) 47 return self.addrevision(text, transaction, link, p1, p2)
38 48
39 def renamed(self, node): 49 def renamed(self, node):
40 if self.parents(node)[0] != revlog.nullid: 50 if self.parents(node)[0] != revlog.nullid:
41 return False 51 return False
42 t = self.revision(node) 52 t = self.revision(node)
43 m = _parsemeta(t) 53 m = _parsemeta(t)[0]
44 if m and "copy" in m: 54 if m and "copy" in m:
45 return (m["copy"], revlog.bin(m["copyrev"])) 55 return (m["copy"], revlog.bin(m["copyrev"]))
46 return False 56 return False
47 57
48 def size(self, rev): 58 def size(self, rev):