annotate mercurial/pushkey.py @ 30308:d500ddae7494

bdiff: don't check border condition in loop `plast = a + len - 1`. So, this "for" loop iterates from "a" to "plast", inclusive. So, `p == plast` can only be true on the final iteration of the loop. So checking for it on every loop iteration is wasteful. This patch simply decreases the upper bound of the loop by 1 and adds an explicit check after iteration for the `p == plast` case. We can't simply add 1 to the initial value for "i" because that doesn't do the correct thing on empty input strings. `perfbdiff -m 3041e4d59df2` on the Firefox repo becomes significantly faster: ! wall 0.072763 comb 0.070000 user 0.070000 sys 0.000000 (best of 100) ! wall 0.053221 comb 0.060000 user 0.060000 sys 0.000000 (best of 100) For the curious, this code has its origins in 8b067bde6679, which is the changeset that introduced bdiff.c in 2005. Also, GNU diffutils is able to perform a similar line-based diff in under 20ms. So there's likely more perf wins to be found in this code. One of them is the hashing algorithm. But it looks like mpm spent some time testing hash collisions in d0c48891dd4a. I'd like to do the same before switching away from lyhash, just to be on the safe side.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sun, 06 Nov 2016 00:37:50 -0700
parents 7b200566e474
children 57875cf423c9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # pushkey.py - dispatching for pushing and pulling keys
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25969
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
8 from __future__ import absolute_import
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
9
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
10 from . import (
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
11 bookmarks,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
12 encoding,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
13 obsolete,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
14 phases,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
15 )
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
16
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
17 def _nslist(repo):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
18 n = {}
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
19 for k in _namespaces:
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20 n[k] = ""
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 21661
diff changeset
21 if not obsolete.isenabled(repo, obsolete.exchangeopt):
17298
59c14bf5a48c pushkey: do not exchange obsole markers if feature is disabled
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17075
diff changeset
22 n.pop('obsolete')
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
23 return n
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
25 _namespaces = {"namespaces": (lambda *x: False, _nslist),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
26 "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
27 "phases": (phases.pushphase, phases.listphases),
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 15648
diff changeset
28 "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
29 }
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 def register(namespace, pushkey, listkeys):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32 _namespaces[namespace] = (pushkey, listkeys)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34 def _get(namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
35 return _namespaces.get(namespace, (lambda *x: False, lambda *x: {}))
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
37 def push(repo, namespace, key, old, new):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
38 '''should succeed iff value was old'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
39 pk = _get(namespace)[0]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 return pk(repo, key, old, new)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 def list(repo, namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 '''return a dict'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 lk = _get(namespace)[1]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 return lk(repo)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
47 encode = encoding.fromlocal
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
48
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
49 decode = encoding.tolocal
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
50
21650
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
51 def encodekeys(keys):
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
52 """encode the content of a pushkey namespace for exchange over the wire"""
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
53 return '\n'.join(['%s\t%s' % (encode(k), encode(v)) for k, v in keys])
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
54
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
55 def decodekeys(data):
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
56 """decode the content of a pushkey namespace from exchange over the wire"""
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
57 result = {}
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
58 for l in data.splitlines():
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
59 k, v = l.split('\t')
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
60 result[decode(k)] = decode(v)
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
61 return result