comparison mercurial/store.py @ 17574:81a033bb29bc

store: let _auxencode() return the list of path segments so we can spare us splitting the path again in _hybridencode()
author Adrian Buehlmann <adrian@cadifra.com>
date Sat, 15 Sep 2012 21:43:05 +0200
parents fb8658ad9e8d
children 61cd71dc3797
comparison
equal deleted inserted replaced
17573:fb8658ad9e8d 17574:81a033bb29bc
131 A segment only needs encoding if a reserved name appears as a 131 A segment only needs encoding if a reserved name appears as a
132 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux" 132 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
133 doesn't need encoding. 133 doesn't need encoding.
134 134
135 >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True) 135 >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True)
136 '~2efoo/au~78.txt/txt.aux/co~6e/pr~6e/nu~6c/foo~2e' 136 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
137 >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.', False) 137 >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.', False)
138 '.com1com2/lp~749.lpt4.lpt1/conprn/com0/lpt0/foo~2e' 138 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
139 >>> _auxencode('foo. ', True) 139 >>> _auxencode('foo. ', True)
140 'foo.~20' 140 ['foo.~20']
141 >>> _auxencode(' .foo', True) 141 >>> _auxencode(' .foo', True)
142 '~20.foo' 142 ['~20.foo']
143 ''' 143 '''
144 res = path.split('/') 144 res = path.split('/')
145 for i, n in enumerate(res): 145 for i, n in enumerate(res):
146 if not n: 146 if not n:
147 continue 147 continue
160 n = n[0:2] + ec + n[3:] 160 n = n[0:2] + ec + n[3:]
161 res[i] = n 161 res[i] = n
162 if n[-1] in '. ': 162 if n[-1] in '. ':
163 # encode last period or space ('foo...' -> 'foo..~2e') 163 # encode last period or space ('foo...' -> 'foo..~2e')
164 res[i] = n[:-1] + "~%02x" % ord(n[-1]) 164 res[i] = n[:-1] + "~%02x" % ord(n[-1])
165 return '/'.join(res) 165 return res
166 166
167 _maxstorepathlen = 120 167 _maxstorepathlen = 120
168 _dirprefixlen = 8 168 _dirprefixlen = 8
169 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4 169 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
170 def _hybridencode(path, auxencode): 170 def _hybridencode(path, auxencode):
201 if not path.startswith('data/'): 201 if not path.startswith('data/'):
202 return path 202 return path
203 # escape directories ending with .i and .d 203 # escape directories ending with .i and .d
204 path = encodedir(path) 204 path = encodedir(path)
205 ndpath = path[len('data/'):] 205 ndpath = path[len('data/'):]
206 res = 'data/' + auxencode(encodefilename(ndpath)) 206 res = 'data/' + '/'.join(auxencode(encodefilename(ndpath)))
207 if len(res) > _maxstorepathlen: 207 if len(res) > _maxstorepathlen:
208 digest = _sha(path).hexdigest() 208 digest = _sha(path).hexdigest()
209 aep = auxencode(lowerencode(ndpath)) 209 parts = auxencode(lowerencode(ndpath))
210 _root, ext = os.path.splitext(aep) 210 _root, ext = os.path.splitext(parts[-1])
211 parts = aep.split('/')
212 basename = parts[-1] 211 basename = parts[-1]
213 sdirs = [] 212 sdirs = []
214 for p in parts[:-1]: 213 for p in parts[:-1]:
215 d = p[:_dirprefixlen] 214 d = p[:_dirprefixlen]
216 if d[-1] in '. ': 215 if d[-1] in '. ':