D5305: py3: fix couple of division operator to do integer divison

2018-11-26 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGe0b485a76009: py3: fix couple of division operator to do 
integer divison (authored by pulkit, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5305?vs=12599=12604

REVISION DETAIL
  https://phab.mercurial-scm.org/D5305

AFFECTED FILES
  hgext/remotefilelog/basepack.py
  hgext/remotefilelog/historypack.py

CHANGE DETAILS

diff --git a/hgext/remotefilelog/historypack.py 
b/hgext/remotefilelog/historypack.py
--- a/hgext/remotefilelog/historypack.py
+++ b/hgext/remotefilelog/historypack.py
@@ -252,7 +252,7 @@
 return self._index[end:end + entrylen]
 else:
 while start < end - entrylen:
-mid = start + (end - start) / 2
+mid = start + (end - start) // 2
 mid = mid - ((mid - origstart) % entrylen)
 midnode = self._index[mid:mid + NODELENGTH]
 if midnode == node:
diff --git a/hgext/remotefilelog/basepack.py b/hgext/remotefilelog/basepack.py
--- a/hgext/remotefilelog/basepack.py
+++ b/hgext/remotefilelog/basepack.py
@@ -45,7 +45,7 @@
 # bisect) with (8 step fanout scan + 1 step bisect)
 # 5 step bisect = log(2^16 / 8 / 255)  # fanout
 # 10 step fanout scan = 2^16 / (2^16 / 8)  # fanout space divided by entries
-SMALLFANOUTCUTOFF = 2**16 / 8
+SMALLFANOUTCUTOFF = 2**16 // 8
 
 # The amount of time to wait between checking for new packs. This prevents an
 # exception when data is moved to a new pack after the process has already



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5301: store: append to fncache if there are only new files to write

2018-11-26 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG0728d87a8631: store: append to fncache if there are only 
new files to write (authored by pulkit, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5301?vs=12595=12605

REVISION DETAIL
  https://phab.mercurial-scm.org/D5301

AFFECTED FILES
  mercurial/store.py

CHANGE DETAILS

diff --git a/mercurial/store.py b/mercurial/store.py
--- a/mercurial/store.py
+++ b/mercurial/store.py
@@ -451,6 +451,8 @@
 self.vfs = vfs
 self.entries = None
 self._dirty = False
+# set of new additions to fncache
+self.addls = set()
 
 def _load(self):
 '''fill the entries from the fncache file'''
@@ -479,32 +481,45 @@
 fp.write(encodedir('\n'.join(self.entries) + '\n'))
 fp.close()
 self._dirty = False
+if self.addls:
+# if we have just new entries, let's append them to the fncache
+tr.addbackup('fncache')
+fp = self.vfs('fncache', mode='ab', atomictemp=True)
+if self.addls:
+fp.write(encodedir('\n'.join(self.addls) + '\n'))
+fp.close()
+self.entries = None
+self.addls = set()
 
 def add(self, fn):
 if self.entries is None:
 self._load()
 if fn not in self.entries:
-self._dirty = True
-self.entries.add(fn)
+self.addls.add(fn)
 
 def remove(self, fn):
 if self.entries is None:
 self._load()
+if fn in self.addls:
+self.addls.remove(fn)
+return
 try:
 self.entries.remove(fn)
 self._dirty = True
 except KeyError:
 pass
 
 def __contains__(self, fn):
+if fn in self.addls:
+return True
 if self.entries is None:
 self._load()
 return fn in self.entries
 
 def __iter__(self):
 if self.entries is None:
 self._load()
-return iter(self.entries)
+return iter(self.entries | self.addls)
 
 class _fncachevfs(vfsmod.abstractvfs, vfsmod.proxyvfs):
 def __init__(self, vfs, fnc, encode):
@@ -580,6 +595,7 @@
 
 def invalidatecaches(self):
 self.fncache.entries = None
+self.fncache.addls = set()
 
 def markremoved(self, fn):
 self.fncache.remove(fn)



To: pulkit, #hg-reviewers
Cc: mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5304: py3: use dict.items() instead of dict.iteritems()

2018-11-26 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG5d1550b9a533: py3: use dict.items() instead of 
dict.iteritems() (authored by pulkit, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5304?vs=12598=12603

REVISION DETAIL
  https://phab.mercurial-scm.org/D5304

AFFECTED FILES
  tests/test-remotefilelog-histpack.py

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-histpack.py 
b/tests/test-remotefilelog-histpack.py
--- a/tests/test-remotefilelog-histpack.py
+++ b/tests/test-remotefilelog-histpack.py
@@ -161,11 +161,11 @@
 pack = self.createPack(revisions)
 
 # Verify the pack contents
-for (filename, node), (p1, p2, lastnode) in allentries.iteritems():
+for (filename, node), (p1, p2, lastnode) in allentries.items():
 ancestors = pack.getancestors(filename, node)
 self.assertEquals(ancestorcounts[(filename, node)],
   len(ancestors))
-for anode, (ap1, ap2, alinknode, copyfrom) in 
ancestors.iteritems():
+for anode, (ap1, ap2, alinknode, copyfrom) in ancestors.items():
 ep1, ep2, elinknode = allentries[(filename, anode)]
 self.assertEquals(ap1, ep1)
 self.assertEquals(ap2, ep2)



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5303: py3: convert strings to bytes in tests/test-remotefilelog-histpack.py

2018-11-26 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG9446d5aa0f32: py3: convert strings to bytes in 
tests/test-remotefilelog-histpack.py (authored by pulkit, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D5303?vs=12597=12602#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5303?vs=12597=12602

REVISION DETAIL
  https://phab.mercurial-scm.org/D5303

AFFECTED FILES
  tests/test-remotefilelog-histpack.py

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-histpack.py 
b/tests/test-remotefilelog-histpack.py
--- a/tests/test-remotefilelog-histpack.py
+++ b/tests/test-remotefilelog-histpack.py
@@ -15,6 +15,7 @@
 
 from mercurial.node import nullid
 from mercurial import (
+pycompat,
 ui as uimod,
 )
 # Load the local remotefilelog, not the system one
@@ -35,13 +36,14 @@
 def makeTempDir(self):
 tempdir = tempfile.mkdtemp()
 self.tempdirs.append(tempdir)
-return tempdir
+return pycompat.fsencode(tempdir)
 
 def getHash(self, content):
 return hashlib.sha1(content).digest()
 
 def getFakeHash(self):
-return ''.join(chr(random.randint(0, 255)) for _ in range(20))
+return b''.join(pycompat.bytechr(random.randint(0, 255))
+for _ in range(20))
 
 def createPack(self, revisions=None):
 """Creates and returns a historypack containing the specified 
revisions.
@@ -53,7 +55,7 @@
 revisions = [("filename", self.getFakeHash(), nullid, nullid,
   self.getFakeHash(), None)]
 
-packdir = self.makeTempDir()
+packdir = pycompat.fsencode(self.makeTempDir())
 packer = historypack.mutablehistorypack(uimod.ui(), packdir,
 version=2)
 
@@ -107,7 +109,7 @@
 chain.
 """
 revisions = []
-filename = "foo"
+filename = b"foo"
 lastnode = nullid
 for i in range(10):
 node = self.getFakeHash()
@@ -136,7 +138,7 @@
 revisions = []
 random.seed(0)
 for i in range(100):
-filename = "filename-%s" % i
+filename = b"filename-%d" % i
 entries = []
 p2 = nullid
 linknode = nullid
@@ -172,7 +174,7 @@
 
 def testGetNodeInfo(self):
 revisions = []
-filename = "foo"
+filename = b"foo"
 lastnode = nullid
 for i in range(10):
 node = self.getFakeHash()
@@ -193,7 +195,7 @@
 """Test the getmissing() api.
 """
 revisions = []
-filename = "foo"
+filename = b"foo"
 for i in range(10):
 node = self.getFakeHash()
 p1 = self.getFakeHash()
@@ -223,7 +225,7 @@
 pack = self.createPack()
 
 try:
-pack.add('filename', nullid, nullid, nullid, nullid, None)
+pack.add(b'filename', nullid, nullid, nullid, nullid, None)
 self.assertTrue(False, "historypack.add should throw")
 except RuntimeError:
 pass
@@ -250,7 +252,7 @@
 total = basepack.SMALLFANOUTCUTOFF + 1
 revisions = []
 for i in xrange(total):
-filename = "foo-%s" % i
+filename = b"foo-%d" % i
 node = self.getFakeHash()
 p1 = self.getFakeHash()
 p2 = self.getFakeHash()



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5300: py3: replace str() with pycompat.bytestr() or ('%d' % int)

2018-11-26 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG001f27970b60: py3: replace str() with pycompat.bytestr() or 
(%d % int) (authored by pulkit, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5300?vs=12594=12601

REVISION DETAIL
  https://phab.mercurial-scm.org/D5300

AFFECTED FILES
  hgext/fastannotate/formatter.py

CHANGE DETAILS

diff --git a/hgext/fastannotate/formatter.py b/hgext/fastannotate/formatter.py
--- a/hgext/fastannotate/formatter.py
+++ b/hgext/fastannotate/formatter.py
@@ -39,23 +39,26 @@
 orig = hexfunc
 hexfunc = lambda x: None if x is None else orig(x)
 wnode = hexfunc(repo[None].p1().node()) + '+'
-wrev = str(repo[None].p1().rev())
+wrev = '%d' % repo[None].p1().rev()
 wrevpad = ''
 if not opts.get('changeset'): # only show + if changeset is hidden
 wrev += '+'
 wrevpad = ' '
-revenc = lambda x: wrev if x is None else str(x) + wrevpad
-csetenc = lambda x: wnode if x is None else str(x) + ' '
+revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad
+def csetenc(x):
+if x is None:
+return wnode
+return pycompat.bytestr(x) + ' '
 else:
-revenc = csetenc = str
+revenc = csetenc = pycompat.bytestr
 
 # opt name, separator, raw value (for json/plain), encoder (for plain)
 opmap = [('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
  ('number', ' ', lambda x: getctx(x).rev(), revenc),
  ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
  ('date', ' ', lambda x: getctx(x).date(), datefunc),
- ('file', ' ', lambda x: x[2], str),
- ('line_number', ':', lambda x: x[1] + 1, str)]
+ ('file', ' ', lambda x: x[2], pycompat.bytestr),
+ ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr)]
 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
 funcmap = [(get, sep, fieldnamemap.get(op, op), enc)
for op, sep, get, enc in opmap



To: pulkit, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5302: py3: alias xrange to range

2018-11-26 Thread durin42 (Augie Fackler)
durin42 added inline comments.

INLINE COMMENTS

> test-remotefilelog-histpack.py:29
> +if pycompat.ispy3:
> +xrange = range
> +

why not just use pycompat.xrange directly instead of doing extra indirection?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5302

To: pulkit, #hg-reviewers
Cc: durin42, mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5306: remotefilelog: fix typo in docstring

2018-11-26 Thread durin42 (Augie Fackler)
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5306

AFFECTED FILES
  hgext/remotefilelog/__init__.py

CHANGE DETAILS

diff --git a/hgext/remotefilelog/__init__.py b/hgext/remotefilelog/__init__.py
--- a/hgext/remotefilelog/__init__.py
+++ b/hgext/remotefilelog/__init__.py
@@ -67,7 +67,7 @@
   particular, minimum number of packs files > gencountlimit.
 
 ``remotefilelog.history.generations`` list for specifying the lower bound 
of
-  each generation of the historhy pack files. For example, list [
+  each generation of the history pack files. For example, list [
   '100MB', '1MB'] or ['1MB', '100MB'] will lead to three generations: [
   0, 1MB), [1MB, 100MB) and [100MB, infinity).
 



To: durin42, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8 V2] perf: add a `--clear-caches` to `perfbranchmapupdate`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542931777 -3600
#  Fri Nov 23 01:09:37 2018 +0100
# Node ID d5e0cfcc409ed9f71a7bd85a711f810151ed8c5e
# Parent  41772e57bfc92d38899b24f729d992c39dc32473
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
d5e0cfcc409e
perf: add a `--clear-caches` to `perfbranchmapupdate`

This flag will help to measure the time we spend loading various cache that
support the branchmap update.

Example for an 500 000 revisions repository:

hg perfbranchmapupdate --base 'not tip' --target 'tip'
! wall 0.000860 comb 0.00 user 0.00 sys 0.00 (best of 336)
hg perfbranchmapupdate --base 'not tip' --target 'tip' --clear-caches
! wall 0.029494 comb 0.03 user 0.03 sys 0.00 (best of 100)

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2234,10 +2234,16 @@ def perfbranchmap(ui, repo, *filternames
 @command(b'perfbranchmapupdate', [
  (b'', b'base', [], b'subset of revision to start from'),
  (b'', b'target', [], b'subset of revision to end with'),
+ (b'', b'clear-caches', False, b'clear cache between each runs')
 ] + formatteropts)
 def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
 """benchmark branchmap update from for  revs to  revs
 
+if `--clear-caches` is passed, the following items will be reset before
+each update:
+* the changelog instance and associated indexes
+* the rev-branch-cache instance
+
 Examples:
 
# update for the one last revision
@@ -2250,6 +2256,7 @@ def perfbranchmapupdate(ui, repo, base=(
 from mercurial import repoview
 opts = _byteskwargs(opts)
 timer, fm = gettimer(ui, opts)
+clearcaches = opts['clear_caches']
 unfi = repo.unfiltered()
 x = [None] # used to pass data between closure
 
@@ -2315,6 +2322,9 @@ def perfbranchmapupdate(ui, repo, base=(
 
 def setup():
 x[0] = base.copy()
+if clearcaches:
+unfi._revbranchcache = None
+clearchangelog(repo)
 
 def bench():
 x[0].update(targetrepo, newrevs)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8 V2] perf: start from an existing branchmap if possible

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542834707 0
#  Wed Nov 21 21:11:47 2018 +
# Node ID 41772e57bfc92d38899b24f729d992c39dc32473
# Parent  03c3522ed8a678695eba5a0dc7612236fbdfb47b
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
41772e57bfc9
perf: start from an existing branchmap if possible

If the --base set if a superset of one of the cached branchmap, we should use as
a starting point. This greatly help the overall runtime of
`hg perfbranchmapupdate`

For example, for a repository with about 500 000 revisions, using this trick
make the command runtime move from about 200 second to about 10 seconds. A 20x
gain.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2296,8 +2296,22 @@ def perfbranchmapupdate(ui, repo, base=(
 baserepo = repo.filtered('__perf_branchmap_update_base')
 targetrepo = repo.filtered('__perf_branchmap_update_target')
 
-base = branchmap.branchcache()
-base.update(baserepo, allbaserevs)
+# try to find an existing branchmap to reuse
+subsettable = getbranchmapsubsettable()
+candidatefilter = subsettable.get(None)
+while candidatefilter is not None:
+candidatebm = repo.filtered(candidatefilter).branchmap()
+if candidatebm.validfor(baserepo):
+filtered = repoview.filterrevs(repo, candidatefilter)
+missing = [r for r in allbaserevs if r in filtered]
+base = candidatebm.copy()
+base.update(baserepo, missing)
+break
+candidatefilter = subsettable.get(candidatefilter)
+else:
+# no suitable subset where found
+base = branchmap.branchcache()
+base.update(baserepo, allbaserevs)
 
 def setup():
 x[0] = base.copy()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8 V2] perf: rely on repoview for perfbranchmapupdate

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542832522 0
#  Wed Nov 21 20:35:22 2018 +
# Node ID 03c3522ed8a678695eba5a0dc7612236fbdfb47b
# Parent  3a9ca368b2362f2304895a9a238abccdd4aee633
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
03c3522ed8a6
perf: rely on repoview for perfbranchmapupdate

Using 'repoview' matching the base and target subset make the benchmark more
realistic. It also unlocks optimization to make the command initialization
faster.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2247,8 +2247,10 @@ def perfbranchmapupdate(ui, repo, base=(
$ hg perfbranchmapupdate --base 'stable' --target 'default'
 """
 from mercurial import branchmap
+from mercurial import repoview
 opts = _byteskwargs(opts)
 timer, fm = gettimer(ui, opts)
+unfi = repo.unfiltered()
 x = [None] # used to pass data between closure
 
 # we use a `list` here to avoid possible side effect from smartset
@@ -2271,21 +2273,43 @@ def perfbranchmapupdate(ui, repo, base=(
 newrevs = list(alltargetrevs.difference(allbaserevs))
 newrevs.sort()
 
+allrevs = frozenset(unfi.changelog.revs())
+basefilterrevs = frozenset(allrevs.difference(allbaserevs))
+targetfilterrevs = frozenset(allrevs.difference(alltargetrevs))
+
+def basefilter(repo, visibilityexceptions=None):
+return basefilterrevs
+
+def targetfilter(repo, visibilityexceptions=None):
+return targetfilterrevs
+
 msg = 'benchmark of branchmap with %d revisions with %d new ones\n'
 ui.status(msg % (len(allbaserevs), len(newrevs)))
+if targetfilterrevs:
+msg = '(%d revisions still filtered)\n'
+ui.status(msg % len(targetfilterrevs))
 
-if True:
+try:
+repoview.filtertable['__perf_branchmap_update_base'] = basefilter
+repoview.filtertable['__perf_branchmap_update_target'] = targetfilter
+
+baserepo = repo.filtered('__perf_branchmap_update_base')
+targetrepo = repo.filtered('__perf_branchmap_update_target')
+
 base = branchmap.branchcache()
-base.update(repo, allbaserevs)
+base.update(baserepo, allbaserevs)
 
 def setup():
 x[0] = base.copy()
 
 def bench():
-x[0].update(repo, newrevs)
+x[0].update(targetrepo, newrevs)
 
 timer(bench, setup=setup)
 fm.end()
+finally:
+repoview.filtertable.pop('__perf_branchmap_update_base', None)
+repoview.filtertable.pop('__perf_branchmap_update_target', None)
 
 @command(b'perfbranchmapload', [
  (b'f', b'filter', b'', b'Specify repoview filter'),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8 V2] perf: pre-indent some code in `perfbranchmapupdate`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542837366 -3600
#  Wed Nov 21 22:56:06 2018 +0100
# Node ID 3a9ca368b2362f2304895a9a238abccdd4aee633
# Parent  dc3191e230daa615929d41cc410bfb16cfe658d9
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
3a9ca368b236
perf: pre-indent some code in `perfbranchmapupdate`

This make the next patch easier to read.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2274,17 +2274,18 @@ def perfbranchmapupdate(ui, repo, base=(
 msg = 'benchmark of branchmap with %d revisions with %d new ones\n'
 ui.status(msg % (len(allbaserevs), len(newrevs)))
 
-base = branchmap.branchcache()
-base.update(repo, allbaserevs)
-
-def setup():
-x[0] = base.copy()
+if True:
+base = branchmap.branchcache()
+base.update(repo, allbaserevs)
 
-def bench():
-x[0].update(repo, newrevs)
+def setup():
+x[0] = base.copy()
 
-timer(bench, setup=setup)
-fm.end()
+def bench():
+x[0].update(repo, newrevs)
+
+timer(bench, setup=setup)
+fm.end()
 
 @command(b'perfbranchmapload', [
  (b'f', b'filter', b'', b'Specify repoview filter'),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8 V2] perf: add a `perfbranchmapupdate` command

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542801745 0
#  Wed Nov 21 12:02:25 2018 +
# Node ID dc3191e230daa615929d41cc410bfb16cfe658d9
# Parent  0adc2c0a0792d4a0015ec0634487ed9e08fd0e7e
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
dc3191e230da
perf: add a `perfbranchmapupdate` command

This command benchmark the time necessary to update the branchmap between two
sets of revisions. This changeset introduce a first version, doing nothing fancy
regarding cache or other internal details.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2231,6 +2231,61 @@ def perfbranchmap(ui, repo, *filternames
 branchcachewrite.restore()
 fm.end()
 
+@command(b'perfbranchmapupdate', [
+ (b'', b'base', [], b'subset of revision to start from'),
+ (b'', b'target', [], b'subset of revision to end with'),
+] + formatteropts)
+def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
+"""benchmark branchmap update from for  revs to  revs
+
+Examples:
+
+   # update for the one last revision
+   $ hg perfbranchmapupdate --base 'not tip' --target 'tip'
+
+   $ update for change coming with a new branch
+   $ hg perfbranchmapupdate --base 'stable' --target 'default'
+"""
+from mercurial import branchmap
+opts = _byteskwargs(opts)
+timer, fm = gettimer(ui, opts)
+x = [None] # used to pass data between closure
+
+# we use a `list` here to avoid possible side effect from smartset
+baserevs = list(scmutil.revrange(repo, base))
+targetrevs = list(scmutil.revrange(repo, target))
+if not baserevs:
+raise error.Abort('no revisions selected for --base')
+if not targetrevs:
+raise error.Abort('no revisions selected for --target')
+
+# make sure the target branchmap also contains the one in the base
+targetrevs = list(set(baserevs) | set(targetrevs))
+targetrevs.sort()
+
+cl = repo.changelog
+allbaserevs = list(cl.ancestors(baserevs, inclusive=True))
+allbaserevs.sort()
+alltargetrevs = frozenset(cl.ancestors(targetrevs, inclusive=True))
+
+newrevs = list(alltargetrevs.difference(allbaserevs))
+newrevs.sort()
+
+msg = 'benchmark of branchmap with %d revisions with %d new ones\n'
+ui.status(msg % (len(allbaserevs), len(newrevs)))
+
+base = branchmap.branchcache()
+base.update(repo, allbaserevs)
+
+def setup():
+x[0] = base.copy()
+
+def bench():
+x[0].update(repo, newrevs)
+
+timer(bench, setup=setup)
+fm.end()
+
 @command(b'perfbranchmapload', [
  (b'f', b'filter', b'', b'Specify repoview filter'),
  (b'', b'list', False, b'List brachmap filter caches'),
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -57,6 +57,9 @@ perfstatus
  benchmark the update of a branchmap
perfbranchmapload
  benchmark reading the branchmap
+   perfbranchmapupdate
+ benchmark branchmap update from for  revs to 
+ revs
perfbundleread
  Benchmark reading of bundle files.
perfcca   (no help text available)
@@ -144,6 +147,8 @@ perfstatus
   $ hg perfbookmarks
   $ hg perfbranchmap
   $ hg perfbranchmapload
+  $ hg perfbranchmapupdate --base "not tip" --target "tip"
+  benchmark of branchmap with 3 revisions with 1 new ones
   $ hg perfcca
   $ hg perfchangegroupchangelog
   $ hg perfchangegroupchangelog --cgversion 01
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8 V2] perf: run 'setup' function during stub run

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542926924 -3600
#  Thu Nov 22 23:48:44 2018 +0100
# Node ID 0adc2c0a0792d4a0015ec0634487ed9e08fd0e7e
# Parent  0a3cc351d7189969b98c7f926b408837683f003b
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
0adc2c0a0792
perf: run 'setup' function during stub run

The benchmarked function might need the content of the setup to be run in order
to function properly.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -276,6 +276,8 @@ def gettimer(ui, opts=None):
 return functools.partial(_timer, fm, displayall=displayall), fm
 
 def stub_timer(fm, func, setup=None, title=None):
+if setup is not None:
+setup()
 func()
 
 @contextlib.contextmanager
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8 V2] perf: fallback to subset if ondisk cache is missing in perfbranchmapload

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542935281 -3600
#  Fri Nov 23 02:08:01 2018 +0100
# Node ID 0a3cc351d7189969b98c7f926b408837683f003b
# Parent  578646b1e2b685f8d499e38ee210d3ec5847a550
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
0a3cc351d718
perf: fallback to subset if ondisk cache is missing in perfbranchmapload

If there is no branchmap on disk for that filter, it means that the cache from
some subset's filter is relevant for this one. We look for it instead of
aborting.

That way it is much simpler to run the command in an automated way. We can now
add it to `test-contrib-perf.t`.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2247,17 +2247,24 @@ def perfbranchmapload(ui, repo, filter=b
 ui.status(b'%s - %s\n'
   % (filtername, util.bytecount(st.st_size)))
 return
-if filter:
+if not filter:
+filter = None
+subsettable = getbranchmapsubsettable()
+if filter is None:
+repo = repo.unfiltered()
+else:
 repo = repoview.repoview(repo, filter)
-else:
-repo = repo.unfiltered()
 
 repo.branchmap() # make sure we have a relevant, up to date branchmap
 
+currentfilter = filter
 # try once without timer, the filter may not be cached
-if branchmap.read(repo) is None:
-raise error.Abort(b'No branchmap cached for %s repo'
-  % (filter or b'unfiltered'))
+while branchmap.read(repo) is None:
+currentfilter = subsettable.get(currentfilter)
+if currentfilter is None:
+raise error.Abort(b'No branchmap cached for %s repo'
+  % (filter or b'unfiltered'))
+repo = repo.filtered(currentfilter)
 timer, fm = gettimer(ui, opts)
 def setup():
 if clearrevlogs:
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -143,6 +143,7 @@ perfstatus
   $ hg perfunidiff --alldata 1
   $ hg perfbookmarks
   $ hg perfbranchmap
+  $ hg perfbranchmapload
   $ hg perfcca
   $ hg perfchangegroupchangelog
   $ hg perfchangegroupchangelog --cgversion 01
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 8 V2] perf: prewarm the branchmap in perfbranchmapload

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542935471 -3600
#  Fri Nov 23 02:11:11 2018 +0100
# Node ID 578646b1e2b685f8d499e38ee210d3ec5847a550
# Parent  5bcf264bb1a0b1f57f01b4d20f28d9db9a74f47b
# EXP-Topic perf-branchmap
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
578646b1e2b6
perf: prewarm the branchmap in perfbranchmapload

It is not very interesting to have the command randomly failing because the
branchmap for the tested filter happens to be cold. So we make sure to have a
valid up to date branchmap before going further.

The data might still be missing from disk if a subset was equivalent. See next
changeset for details and fix.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -2251,6 +2251,9 @@ def perfbranchmapload(ui, repo, filter=b
 repo = repoview.repoview(repo, filter)
 else:
 repo = repo.unfiltered()
+
+repo.branchmap() # make sure we have a relevant, up to date branchmap
+
 # try once without timer, the filter may not be cached
 if branchmap.read(repo) is None:
 raise error.Abort(b'No branchmap cached for %s repo'
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] perf: add a `--timing` argument to `perfhelper-tracecopies`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542997971 -3600
#  Fri Nov 23 19:32:51 2018 +0100
# Node ID eb3bef1d74e864bf0436a355b0f4859def00ffc2
# Parent  cfaf3843491bde30916b89180d5f67561a22da28
# EXP-Topic perf-copies
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
eb3bef1d74e8
perf: add a `--timing` argument to `perfhelper-tracecopies`

The new argument will help picking better pair for benchmarking. See
documentation for details.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -1162,19 +1162,39 @@ def perftemplating(ui, repo, testedtempl
 @command(b'perfhelper-tracecopies', formatteropts +
  [
   (b'r', b'revs', [], b'restrict search to these revisions'),
+  (b'', b'timing', False, b'provides extra data (costly)'),
  ])
 def perfhelpertracecopies(ui, repo, revs=[], **opts):
 """find statistic about potential parameters for the `perftracecopies`
 
 This command find source-destination pair relevant for copytracing testing.
 It report value for some of the parameters that impact copy tracing time.
+
+If `--timing` is set, rename detection is run and the associated timing
+will be reported. The extra details comes at the cost of a slower command
+execution.
+
+Since the rename detection is only run once, other factors might easily
+affect the precision of the timing. However it should give a good
+approximation of which revision pairs are very costly.
 """
 opts = _byteskwargs(opts)
 fm = ui.formatter(b'perf', opts)
-header = '%12s %12s %12s %12s\n'
-output = ("%(source)12s %(destination)12s "
-  "%(nbrevs)12d %(nbmissingfiles)12d\n")
-fm.plain(header % ("source", "destination", "nb-revs", "nb-files"))
+dotiming = opts[b'timing']
+
+if dotiming:
+header = '%12s %12s %12s %12s %12s %12s\n'
+output = ("%(source)12s %(destination)12s "
+  "%(nbrevs)12d %(nbmissingfiles)12d "
+  "%(nbrenamedfiles)12d %(time)18.5f\n")
+header_names = ("source", "destination", "nb-revs", "nb-files",
+"nb-renames", "time")
+fm.plain(header % header_names)
+else:
+header = '%12s %12s %12s %12s\n'
+output = ("%(source)12s %(destination)12s "
+  "%(nbrevs)12d %(nbmissingfiles)12d\n")
+fm.plain(header % ("source", "destination", "nb-revs", "nb-files"))
 
 if not revs:
 revs = ['all()']
@@ -1193,18 +1213,26 @@ def perfhelpertracecopies(ui, repo, revs
 missing = copies._computeforwardmissing(base, parent)
 if not missing:
 continue
-fm.startitem()
 data = {
 b'source': base.hex(),
 b'destination': parent.hex(),
 b'nbrevs': len(repo.revs('%d::%d', b, p)),
 b'nbmissingfiles': len(missing),
 }
+if dotiming:
+begin = util.timer()
+renames = copies.pathcopies(base, parent)
+end = util.timer()
+# not very stable timing since we did only one run
+data['time'] = end - begin
+data['nbrenamedfiles'] = len(renames)
+fm.startitem()
 fm.data(**data)
 out = data.copy()
 out['source'] = fm.hexfunc(base.node())
 out['destination'] = fm.hexfunc(parent.node())
 fm.plain(output % out)
+
 fm.end()
 
 @command(b'perfcca', formatteropts)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 5 FOLLOW-UP] revlog: update the documentation for `trim_endidx`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543188192 -3600
#  Mon Nov 26 00:23:12 2018 +0100
# Node ID 498fc4b8da0cf147315b63b4580ef9b6a36e3911
# Parent  7dc2fade8ee58c0554b6f25484a4481ac625ce84
# EXP-Topic follow-up-yuya
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
498fc4b8da0c
revlog: update the documentation for `trim_endidx`

The function role drifted since the function was commented.

diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -1086,7 +1086,7 @@ index_segment_span(indexObject *self, Py
return (end_offset - start_offset) + (int64_t)end_size;
 }
 
-/* returns revs[startidx:endidx] without empty trailing revs */
+/* returns endidx so that revs[startidx:endidx] has no empty trailing revs */
 static Py_ssize_t trim_endidx(indexObject *self, const Py_ssize_t *revs,
   Py_ssize_t startidx, Py_ssize_t endidx)
 {
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 5 FOLLOW-UP] revlog: properly detect corrupted revlog in `index_get_length`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543188069 -3600
#  Mon Nov 26 00:21:09 2018 +0100
# Node ID 7dc2fade8ee58c0554b6f25484a4481ac625ce84
# Parent  9e936fdbd084acef9ca4edf998024896a30a0937
# EXP-Topic follow-up-yuya
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
7dc2fade8ee5
revlog: properly detect corrupted revlog in `index_get_length`

Pointed out by Yuya Nishihara.

diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -242,7 +242,14 @@ static inline int index_get_length(index
return (int)ret;
} else {
const char *data = index_deref(self, rev);
-   return (int)getbe32(data + 8);
+   int tmp = (int)getbe32(data + 8);
+   if (tmp < 0) {
+   PyErr_Format(PyExc_OverflowError,
+"revlog entry size out of bound (%d)",
+tmp);
+   return -1;
+   }
+   return tmp;
}
 }
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 5 FOLLOW-UP] perf: rename `perfhelper-tracecopies` to `perfhelper-pathcopies`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543187712 -3600
#  Mon Nov 26 00:15:12 2018 +0100
# Node ID 9e936fdbd084acef9ca4edf998024896a30a0937
# Parent  47117f84f39cb5bc12212ba9c31212c9236feb85
# EXP-Topic follow-up-yuya
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
9e936fdbd084
perf: rename `perfhelper-tracecopies` to `perfhelper-pathcopies`

The command it supports is called `perfpathcopies`. It seems better to align the
names.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -1160,11 +1160,11 @@ def perftemplating(ui, repo, testedtempl
 timer(format)
 fm.end()
 
-@command(b'perfhelper-tracecopies', formatteropts +
+@command(b'perfhelper-pathcopies', formatteropts +
  [
   (b'r', b'revs', [], b'restrict search to these revisions'),
  ])
-def perfhelpertracecopies(ui, repo, revs=[], **opts):
+def perfhelperpathcopies(ui, repo, revs=[], **opts):
 """find statistic about potential parameters for the `perftracecopies`
 
 This command find source-destination pair relevant for copytracing testing.
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -83,7 +83,7 @@ perfstatus
perffncachewrite
  (no help text available)
perfheads (no help text available)
-   perfhelper-tracecopies
+   perfhelper-pathcopies
  find statistic about potential parameters for the
  'perftracecopies'
perfindex (no help text available)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 5 FOLLOW-UP] perf: add a docstring to `perfpathcopies`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543187630 -3600
#  Mon Nov 26 00:13:50 2018 +0100
# Node ID 47117f84f39cb5bc12212ba9c31212c9236feb85
# Parent  87443a7ac7f6a37ed59d6429c87118c64b7287f6
# EXP-Topic follow-up-yuya
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
47117f84f39c
perf: add a docstring to `perfpathcopies`

This will help people to find this command.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -834,6 +834,7 @@ def perfmergecalculate(ui, repo, rev, **
 
 @command(b'perfpathcopies', [], b"REV REV")
 def perfpathcopies(ui, repo, rev1, rev2, **opts):
+"""benchmark the copy tracing logic"""
 opts = _byteskwargs(opts)
 timer, fm = gettimer(ui, opts)
 ctx1 = scmutil.revsingle(repo, rev1, rev1)
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -104,7 +104,7 @@ perfstatus
  (no help text available)
perfparents   (no help text available)
perfpathcopies
- (no help text available)
+ benchmark the copy tracing logic
perfphasesbenchmark phasesets computation
perfphasesremote
  benchmark time needed to analyse phases of the remote server
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 5 FOLLOW-UP] revlog: update the docstring of `ancestors` to match reality

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543187291 -3600
#  Mon Nov 26 00:08:11 2018 +0100
# Node ID 87443a7ac7f6a37ed59d6429c87118c64b7287f6
# Parent  cfaf3843491bde30916b89180d5f67561a22da28
# EXP-Topic follow-up-yuya
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
87443a7ac7f6
revlog: update the docstring of `ancestors` to match reality

Code using this method expect the revision to be (reverse) sorted. As pointed by
Yuya Nishihara, the docstring should reflect that.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -768,7 +768,7 @@ class revlog(object):
 return chain, stopped
 
 def ancestors(self, revs, stoprev=0, inclusive=False):
-"""Generate the ancestors of 'revs' in reverse topological order.
+"""Generate the ancestors of 'revs' in reverse revision order.
 Does not generate revs lower than stoprev.
 
 See the documentation for ancestor.lazyancestors for more details."""
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 5 V3] perf: disable revlogs clearing in `perftags` by default

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542735864 0
#  Tue Nov 20 17:44:24 2018 +
# Node ID 400476885997b972298b537b5d694ba9500f3f90
# Parent  4394597460a13bcd6fc2b4d88826f9399ac27de0
# EXP-Topic perf-tags
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
400476885997
perf: disable revlogs clearing in `perftags` by default

This aligns things with what `perfbookmarks` does. I decided to disable the
revlogs clearing by default to focus on the core logic by default, ignoring
side effects.

If we prefer to emphasize the side effect, we can instead keep this on in
`perftags` and enable it by default in `perfbookmarks`.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -538,7 +538,7 @@ def perfheads(ui, repo, **opts):
 
 @command(b'perftags', formatteropts+
 [
-(b'', b'clear-revlogs', True, 'refresh changelog and manifest'),
+(b'', b'clear-revlogs', False, 'refresh changelog and manifest'),
 ])
 def perftags(ui, repo, **opts):
 import mercurial.changelog
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 5 V3] perf: add a `clear-revlogs` flag to `perfbookmarks`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542711320 0
#  Tue Nov 20 10:55:20 2018 +
# Node ID 4394597460a13bcd6fc2b4d88826f9399ac27de0
# Parent  568c6a0abb650b9c0949e2231f0d8ff51cf40ece
# EXP-Topic perf-tags
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
4394597460a1
perf: add a `clear-revlogs` flag to `perfbookmarks`

This flag (off by default) makes it possible to enable the refresh of the
changelog and revlog. This is useful to check for costly side effects of
bookmark loading.

Usually, these side effects are shared with other logics (eg: tags).

example output in my mercurial repo (with 1 bookmark, so not a great example):
$ hg perfbookmarks
! wall 0.44
$ hg perfbookmarks --clear-revlogs
! wall 0.001380

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -583,13 +583,19 @@ def perfancestorset(ui, repo, revset, **
 timer(d)
 fm.end()
 
-@command(b'perfbookmarks', formatteropts)
+@command(b'perfbookmarks', formatteropts +
+[
+(b'', b'clear-revlogs', False, 'refresh changelog and manifest'),
+])
 def perfbookmarks(ui, repo, **opts):
 """benchmark parsing bookmarks from disk to memory"""
 opts = _byteskwargs(opts)
 timer, fm = gettimer(ui, opts)
 
+clearrevlogs = opts['clear_revlogs']
 def s():
+if clearrevlogs:
+clearchangelog(repo)
 clearfilecache(repo, b'_bookmarks')
 def d():
 repo._bookmarks
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 5 V3] tags: cache `repo.changelog` access when checking tags nodes

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542710295 0
#  Tue Nov 20 10:38:15 2018 +
# Node ID 568c6a0abb650b9c0949e2231f0d8ff51cf40ece
# Parent  e5c18b7087cdeac2a1213c3499e9a8215b252af6
# EXP-Topic perf-tags
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
568c6a0abb65
tags: cache `repo.changelog` access when checking tags nodes

The tags reading process checks if the nodes referenced in tags exist. Caching
the access to `repo.changelog` provides a large speedup for repositories with
many tags.

running `hg perftags` in a large private repository
before: ! wall 0.393464 comb 0.39 user 0.33 sys 0.06 (median of 25)
after:  ! wall 0.267711 comb 0.27 user 0.21 sys 0.06 (median of 38)

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1416,10 +1416,11 @@ class localrepository(object):
 tags, tt = self._findtags()
 else:
 tags = self._tagscache.tags
+rev = self.changelog.rev
 for k, v in tags.iteritems():
 try:
 # ignore tags to unknown nodes
-self.changelog.rev(v)
+rev(v)
 t[k] = v
 except (error.LookupError, ValueError):
 pass
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 5 V3] perf: add a `clear-revlogs` flag to `perftags`

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542710780 0
#  Tue Nov 20 10:46:20 2018 +
# Node ID e5c18b7087cdeac2a1213c3499e9a8215b252af6
# Parent  a2a4aabea58bef816eeb53e80ddaf0d438717c66
# EXP-Topic perf-tags
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
e5c18b7087cd
perf: add a `clear-revlogs` flag to `perftags`

This flag (on by default) makes it possible to disable the refresh of the
changelog and revlog. This is useful to check for the time spent in the core
tags logic without the associated side effects. Usually, these side effects
are shared with other logics (eg: bookmarks).

Example output in my Mercurial repository

$ hg perftags
! wall 0.017919 comb 0.02 user 0.02 sys 0.00 (best of 141)
$ hg perftags --no-clear-revlogs
! wall 0.012982 comb 0.01 user 0.01 sys 0.00 (best of 207)

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -536,7 +536,10 @@ def perfheads(ui, repo, **opts):
 timer(d)
 fm.end()
 
-@command(b'perftags', formatteropts)
+@command(b'perftags', formatteropts+
+[
+(b'', b'clear-revlogs', True, 'refresh changelog and manifest'),
+])
 def perftags(ui, repo, **opts):
 import mercurial.changelog
 import mercurial.manifest
@@ -545,9 +548,11 @@ def perftags(ui, repo, **opts):
 timer, fm = gettimer(ui, opts)
 svfs = getsvfs(repo)
 repocleartagscache = repocleartagscachefunc(repo)
+clearrevlogs = opts['clear_revlogs']
 def s():
-clearchangelog(repo)
-clearfilecache(repo.unfiltered(), 'manifest')
+if clearrevlogs:
+clearchangelog(repo)
+clearfilecache(repo.unfiltered(), 'manifest')
 repocleartagscache()
 def t():
 return len(repo.tags())
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 5 V3] perf: stop creating new revlog by hand in perftags

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1543149473 -3600
#  Sun Nov 25 13:37:53 2018 +0100
# Node ID a2a4aabea58bef816eeb53e80ddaf0d438717c66
# Parent  cfaf3843491bde30916b89180d5f67561a22da28
# EXP-Topic perf-tags
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
a2a4aabea58b
perf: stop creating new revlog by hand in perftags

It i better to let the repository logic create its own object. We now just clear
the cache. New object will be automatically created from there.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -546,10 +546,8 @@ def perftags(ui, repo, **opts):
 svfs = getsvfs(repo)
 repocleartagscache = repocleartagscachefunc(repo)
 def s():
-repo.changelog = mercurial.changelog.changelog(svfs)
-rootmanifest = mercurial.manifest.manifestrevlog(svfs)
-repo.manifestlog = mercurial.manifest.manifestlog(svfs, repo,
-  rootmanifest)
+clearchangelog(repo)
+clearfilecache(repo.unfiltered(), 'manifest')
 repocleartagscache()
 def t():
 return len(repo.tags())
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 6] vfs: also audit rename

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498961267 -7200
#  Sun Jul 02 04:07:47 2017 +0200
# Node ID afdc73b20bd1faeec1b278ef0a2ab8d1dda71eb8
# Parent  cc7d970d99eb242dbe2d8e792a9212aabd06911f
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
afdc73b20bd1
vfs: also audit rename

Renaming through the vfs is not used in many places, and none of them seems to
be at security risk.

However it is still worthwhile to run the auditing on rename file to perform
developer-warning level checks.

diff --git a/mercurial/vfs.py b/mercurial/vfs.py
--- a/mercurial/vfs.py
+++ b/mercurial/vfs.py
@@ -436,6 +436,10 @@ class vfs(abstractvfs):
 
 return fp
 
+def rename(self, src, dst, *args, **kwargs):
+self._auditpath(dst, 'w')
+return super(vfs, self).rename(src, dst, *args, **kwargs)
+
 def symlink(self, src, dst):
 self.audit(dst)
 linkname = self.join(dst)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 6] vfs: makes all audited path relative

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498963863 -7200
#  Sun Jul 02 04:51:03 2017 +0200
# Node ID cc7d970d99eb242dbe2d8e792a9212aabd06911f
# Parent  7f04e7e8eea72eb588d9460df7c0f2b72941b760
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
cc7d970d99eb
vfs: makes all audited path relative

Only auditing relative path helps the vfs warning logic.

diff --git a/mercurial/vfs.py b/mercurial/vfs.py
--- a/mercurial/vfs.py
+++ b/mercurial/vfs.py
@@ -339,6 +339,8 @@ class vfs(abstractvfs):
 
 def _auditpath(self, path, mode):
 if self._audit:
+if os.path.isabs(path) and path.startswith(self.base):
+path = os.path.relpath(path, self.base)
 r = util.checkosfilename(path)
 if r:
 raise error.Abort("%s: %r" % (r, path))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 6] vfs: extract the audit path logic into a submethod

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1498961184 -7200
#  Sun Jul 02 04:06:24 2017 +0200
# Node ID 7f04e7e8eea72eb588d9460df7c0f2b72941b760
# Parent  3d8d2de85c9afc06b7aad740aa1ad2c817d18dfa
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
7f04e7e8eea7
vfs: extract the audit path logic into a submethod

This will make it possible to apply it in more cases.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1029,12 +1029,12 @@ class localrepository(object):
 path = path[len(repo.path) + 1:]
 if path.startswith('cache/'):
 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
-repo.ui.develwarn(msg % path, stacklevel=2, config="cache-vfs")
+repo.ui.develwarn(msg % path, stacklevel=3, config="cache-vfs")
 if path.startswith('journal.') or path.startswith('undo.'):
 # journal is covered by 'lock'
 if repo._currentlock(repo._lockref) is None:
 repo.ui.develwarn('write with no lock: "%s"' % path,
-  stacklevel=2, config='check-locks')
+  stacklevel=3, config='check-locks')
 elif repo._currentlock(repo._wlockref) is None:
 # rest of vfs files are covered by 'wlock'
 #
@@ -1043,7 +1043,7 @@ class localrepository(object):
 if path.startswith(prefix):
 return
 repo.ui.develwarn('write with no wlock: "%s"' % path,
-  stacklevel=2, config='check-locks')
+  stacklevel=3, config='check-locks')
 return ret
 return checkvfs
 
@@ -1062,7 +1062,7 @@ class localrepository(object):
 path = path[len(repo.sharedpath) + 1:]
 if repo._currentlock(repo._lockref) is None:
 repo.ui.develwarn('write with no lock: "%s"' % path,
-  stacklevel=3)
+  stacklevel=4)
 return ret
 return checksvfs
 
diff --git a/mercurial/vfs.py b/mercurial/vfs.py
--- a/mercurial/vfs.py
+++ b/mercurial/vfs.py
@@ -337,6 +337,13 @@ class vfs(abstractvfs):
 return
 os.chmod(name, self.createmode & 0o666)
 
+def _auditpath(self, path, mode):
+if self._audit:
+r = util.checkosfilename(path)
+if r:
+raise error.Abort("%s: %r" % (r, path))
+self.audit(path, mode=mode)
+
 def __call__(self, path, mode="r", atomictemp=False, notindexed=False,
  backgroundclose=False, checkambig=False, auditpath=True):
 '''Open ``path`` file, which is relative to vfs root.
@@ -369,11 +376,7 @@ class vfs(abstractvfs):
 cases (see also issue5418 and issue5584 for detail).
 '''
 if auditpath:
-if self._audit:
-r = util.checkosfilename(path)
-if r:
-raise error.Abort("%s: %r" % (r, path))
-self.audit(path, mode=mode)
+self._auditpath(path, mode)
 f = self.join(path)
 
 if "b" not in mode:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 6] subrepo-git: use an official origvfs when appropriate

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542913288 -3600
#  Thu Nov 22 20:01:28 2018 +0100
# Node ID 3d8d2de85c9afc06b7aad740aa1ad2c817d18dfa
# Parent  a83de6825f6aac64efc059e6224225b073d441f4
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
3d8d2de85c9a
subrepo-git: use an official origvfs when appropriate

The origvfs has the auditor properly set and can move file without issue.

The current code is currently working without errors because rename are not
audited, yet.

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -1806,11 +1806,15 @@ class gitsubrepo(abstractsubrepo):
 if not opts.get(r'no_backup'):
 status = self.status(None)
 names = status.modified
+origvfs = scmutil.getorigvfs(self.ui, self._subparent)
+if origvfs is None:
+origvfs = self.wvfs
 for name in names:
 bakname = scmutil.origpath(self.ui, self._subparent, name)
 self.ui.note(_('saving current version of %s as %s\n') %
 (name, bakname))
-self.wvfs.rename(name, bakname)
+name = self.wvfs.join(name)
+origvfs.rename(name, bakname)
 
 if not opts.get(r'dry_run'):
 self.get(substate, overwrite=True)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 6] vfs: treat 'undo.' file the same as 'journal.' file

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542908647 -3600
#  Thu Nov 22 18:44:07 2018 +0100
# Node ID 5bcdd426a817c333ca30dac9a02ec100f962155e
# Parent  dba590f27c7abacbd7e9b27f3e06822bb0b339cb
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
5bcdd426a817
vfs: treat 'undo.' file the same as 'journal.' file

They are the same kind of file, they are protected by the store lock, but
directly lives inside the '.hg' directory.

No warnings were ever raised about them because `vfs.rename` is not audited.
Something we are trying to change.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1030,7 +1030,7 @@ class localrepository(object):
 if path.startswith('cache/'):
 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
 repo.ui.develwarn(msg % path, stacklevel=2, config="cache-vfs")
-if path.startswith('journal.'):
+if path.startswith('journal.') or path.startswith('undo.'):
 # journal is covered by 'lock'
 if repo._currentlock(repo._lockref) is None:
 repo.ui.develwarn('write with no lock: "%s"' % path,
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 6] revert: extract origvfs logic in a sub-function

2018-11-26 Thread Boris Feld
# HG changeset patch
# User Boris Feld 
# Date 1542911165 -3600
#  Thu Nov 22 19:26:05 2018 +0100
# Node ID a83de6825f6aac64efc059e6224225b073d441f4
# Parent  5bcdd426a817c333ca30dac9a02ec100f962155e
# EXP-Topic vfs.audit-rename
# Available At https://bitbucket.org/octobus/mercurial-devel/
#  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 
a83de6825f6a
revert: extract origvfs logic in a sub-function

The subrepo's "revert" logic could benefit from it.

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -814,21 +814,29 @@ def parsefollowlinespattern(repo, rev, p
 raise error.ParseError(msg)
 return files[0]
 
+def getorigvfs(ui, repo):
+"""return a vfs suitable to save 'orig' file
+
+return None if no special directory is configured"""
+origbackuppath = ui.config('ui', 'origbackuppath')
+if not origbackuppath:
+return None
+return vfs.vfs(repo.wvfs.join(origbackuppath))
+
 def origpath(ui, repo, filepath):
 '''customize where .orig files are created
 
 Fetch user defined path from config file: [ui] origbackuppath = 
 Fall back to default (filepath with .orig suffix) if not specified
 '''
-origbackuppath = ui.config('ui', 'origbackuppath')
-if not origbackuppath:
+origvfs = getorigvfs(ui, repo)
+if origvfs is None:
 return filepath + ".orig"
 
 # Convert filepath from an absolute path into a path inside the repo.
 filepathfromroot = util.normpath(os.path.relpath(filepath,
  start=repo.root))
 
-origvfs = vfs.vfs(repo.wjoin(origbackuppath))
 origbackupdir = origvfs.dirname(filepathfromroot)
 if not origvfs.isdir(origbackupdir) or origvfs.islink(origbackupdir):
 ui.note(_('creating directory: %s\n') % origvfs.join(origbackupdir))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5305: py3: fix couple of division operator to do integer divison

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5305

AFFECTED FILES
  hgext/remotefilelog/basepack.py
  hgext/remotefilelog/historypack.py

CHANGE DETAILS

diff --git a/hgext/remotefilelog/historypack.py 
b/hgext/remotefilelog/historypack.py
--- a/hgext/remotefilelog/historypack.py
+++ b/hgext/remotefilelog/historypack.py
@@ -252,7 +252,7 @@
 return self._index[end:end + entrylen]
 else:
 while start < end - entrylen:
-mid = start + (end - start) / 2
+mid = start + (end - start) // 2
 mid = mid - ((mid - origstart) % entrylen)
 midnode = self._index[mid:mid + NODELENGTH]
 if midnode == node:
diff --git a/hgext/remotefilelog/basepack.py b/hgext/remotefilelog/basepack.py
--- a/hgext/remotefilelog/basepack.py
+++ b/hgext/remotefilelog/basepack.py
@@ -45,7 +45,7 @@
 # bisect) with (8 step fanout scan + 1 step bisect)
 # 5 step bisect = log(2^16 / 8 / 255)  # fanout
 # 10 step fanout scan = 2^16 / (2^16 / 8)  # fanout space divided by entries
-SMALLFANOUTCUTOFF = 2**16 / 8
+SMALLFANOUTCUTOFF = 2**16 // 8
 
 # The amount of time to wait between checking for new packs. This prevents an
 # exception when data is moved to a new pack after the process has already



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5304: py3: use dict.items() instead of dict.iteritems()

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  dict.iteritems() does not exist on Python 3.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5304

AFFECTED FILES
  tests/test-remotefilelog-histpack.py

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-histpack.py 
b/tests/test-remotefilelog-histpack.py
--- a/tests/test-remotefilelog-histpack.py
+++ b/tests/test-remotefilelog-histpack.py
@@ -164,11 +164,11 @@
 pack = self.createPack(revisions)
 
 # Verify the pack contents
-for (filename, node), (p1, p2, lastnode) in allentries.iteritems():
+for (filename, node), (p1, p2, lastnode) in allentries.items():
 ancestors = pack.getancestors(filename, node)
 self.assertEquals(ancestorcounts[(filename, node)],
   len(ancestors))
-for anode, (ap1, ap2, alinknode, copyfrom) in 
ancestors.iteritems():
+for anode, (ap1, ap2, alinknode, copyfrom) in ancestors.items():
 ep1, ep2, elinknode = allentries[(filename, anode)]
 self.assertEquals(ap1, ep1)
 self.assertEquals(ap2, ep2)



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5303: py3: convert strings to bytes in tests/test-remotefilelog-histpack.py

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5303

AFFECTED FILES
  tests/test-remotefilelog-histpack.py

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-histpack.py 
b/tests/test-remotefilelog-histpack.py
--- a/tests/test-remotefilelog-histpack.py
+++ b/tests/test-remotefilelog-histpack.py
@@ -39,13 +39,14 @@
 def makeTempDir(self):
 tempdir = tempfile.mkdtemp()
 self.tempdirs.append(tempdir)
-return tempdir
+return pycompat.fsencode(tempdir)
 
 def getHash(self, content):
 return hashlib.sha1(content).digest()
 
 def getFakeHash(self):
-return ''.join(chr(random.randint(0, 255)) for _ in range(20))
+return b''.join(pycompat.bytechr(random.randint(0, 255))
+for _ in range(20))
 
 def createPack(self, revisions=None):
 """Creates and returns a historypack containing the specified 
revisions.
@@ -57,7 +58,7 @@
 revisions = [("filename", self.getFakeHash(), nullid, nullid,
   self.getFakeHash(), None)]
 
-packdir = self.makeTempDir()
+packdir = pycompat.fsencode(self.makeTempDir())
 packer = historypack.mutablehistorypack(uimod.ui(), packdir,
 version=2)
 
@@ -111,7 +112,7 @@
 chain.
 """
 revisions = []
-filename = "foo"
+filename = b"foo"
 lastnode = nullid
 for i in range(10):
 node = self.getFakeHash()
@@ -140,7 +141,7 @@
 revisions = []
 random.seed(0)
 for i in range(100):
-filename = "filename-%s" % i
+filename = b"filename-%d" % i
 entries = []
 p2 = nullid
 linknode = nullid
@@ -176,7 +177,7 @@
 
 def testGetNodeInfo(self):
 revisions = []
-filename = "foo"
+filename = b"foo"
 lastnode = nullid
 for i in range(10):
 node = self.getFakeHash()
@@ -197,7 +198,7 @@
 """Test the getmissing() api.
 """
 revisions = []
-filename = "foo"
+filename = b"foo"
 for i in range(10):
 node = self.getFakeHash()
 p1 = self.getFakeHash()
@@ -227,7 +228,7 @@
 pack = self.createPack()
 
 try:
-pack.add('filename', nullid, nullid, nullid, nullid, None)
+pack.add(b'filename', nullid, nullid, nullid, nullid, None)
 self.assertTrue(False, "historypack.add should throw")
 except RuntimeError:
 pass
@@ -254,7 +255,7 @@
 total = basepack.SMALLFANOUTCUTOFF + 1
 revisions = []
 for i in xrange(total):
-filename = "foo-%s" % i
+filename = b"foo-%d" % i
 node = self.getFakeHash()
 p1 = self.getFakeHash()
 p2 = self.getFakeHash()



To: pulkit, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5302: py3: alias xrange to range

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  xrange does not exists on Python 3.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5302

AFFECTED FILES
  tests/test-remotefilelog-histpack.py

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-histpack.py 
b/tests/test-remotefilelog-histpack.py
--- a/tests/test-remotefilelog-histpack.py
+++ b/tests/test-remotefilelog-histpack.py
@@ -15,6 +15,7 @@
 
 from mercurial.node import nullid
 from mercurial import (
+pycompat,
 ui as uimod,
 )
 # Load the local remotefilelog, not the system one
@@ -24,6 +25,9 @@
 historypack,
 )
 
+if pycompat.ispy3:
+xrange = range
+
 class histpacktests(unittest.TestCase):
 def setUp(self):
 self.tempdirs = []



To: pulkit, #hg-reviewers
Cc: mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5301: store: append to fncache if there are only new files to write

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Before this patch, if we have to add a new entry to fncache, we write the 
whole
  fncache again which slows things down on large fncache which have millions of
  entries. Addition of a new entry is common operation while pulling new files 
or
  commiting a new file.
  
  This patch adds a new fncache.addls set which keeps track of the additions
  happening and store them. When we write the fncache, we will just read the 
addls
  set and append those entries at the end of fncache.
  We make sure that the entries are new entries by loading the fncache and 
making
  sure entry does not exists there. In future if we can check if an entry is new
  without loading the fncache, that will speed up things more.
  
  Performance numbers for commiting a new file:
  
  mercurial repo
  before: 0.08784651756286621
  after: 0.08474504947662354
  
  mozilla-central
  before: 1.83314049243927
  after: 1.7054164409637451
  
  netbeans
  before: 0.7953150272369385
  after: 0.7202838659286499
  
  pypy
  before: 0.17805707454681396
  after: 0.13431048393249512
  
  In our internal repo, the performance improvement is in seconds.
  
  I have used octobus's ASV perf benchmark thing to get the above numbers. I 
also
  see some minute perf improvements related to creating a new commit without a 
new
  file, but I believe that's just some noise.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5301

AFFECTED FILES
  mercurial/store.py

CHANGE DETAILS

diff --git a/mercurial/store.py b/mercurial/store.py
--- a/mercurial/store.py
+++ b/mercurial/store.py
@@ -451,6 +451,8 @@
 self.vfs = vfs
 self.entries = None
 self._dirty = False
+# set of new additions to fncache
+self.addls = set()
 
 def _load(self):
 '''fill the entries from the fncache file'''
@@ -479,32 +481,45 @@
 fp.write(encodedir('\n'.join(self.entries) + '\n'))
 fp.close()
 self._dirty = False
+if self.addls:
+# if we have just new entries, let's append them to the fncache
+tr.addbackup('fncache')
+fp = self.vfs('fncache', mode='ab', atomictemp=True)
+if self.addls:
+fp.write(encodedir('\n'.join(self.addls) + '\n'))
+fp.close()
+self.entries = None
+self.addls = set()
 
 def add(self, fn):
 if self.entries is None:
 self._load()
 if fn not in self.entries:
-self._dirty = True
-self.entries.add(fn)
+self.addls.add(fn)
 
 def remove(self, fn):
 if self.entries is None:
 self._load()
+if fn in self.addls:
+self.addls.remove(fn)
+return
 try:
 self.entries.remove(fn)
 self._dirty = True
 except KeyError:
 pass
 
 def __contains__(self, fn):
+if fn in self.addls:
+return True
 if self.entries is None:
 self._load()
 return fn in self.entries
 
 def __iter__(self):
 if self.entries is None:
 self._load()
-return iter(self.entries)
+return iter(self.entries | self.addls)
 
 class _fncachevfs(vfsmod.abstractvfs, vfsmod.proxyvfs):
 def __init__(self, vfs, fnc, encode):
@@ -580,6 +595,7 @@
 
 def invalidatecaches(self):
 self.fncache.entries = None
+self.fncache.addls = set()
 
 def markremoved(self, fn):
 self.fncache.remove(fn)



To: pulkit, #hg-reviewers
Cc: mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5300: py3: replace str() with pycompat.bytestr() or ('%d' % int)

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit updated this revision to Diff 12594.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D5300?vs=12591=12594

REVISION DETAIL
  https://phab.mercurial-scm.org/D5300

AFFECTED FILES
  hgext/fastannotate/formatter.py

CHANGE DETAILS

diff --git a/hgext/fastannotate/formatter.py b/hgext/fastannotate/formatter.py
--- a/hgext/fastannotate/formatter.py
+++ b/hgext/fastannotate/formatter.py
@@ -39,23 +39,26 @@
 orig = hexfunc
 hexfunc = lambda x: None if x is None else orig(x)
 wnode = hexfunc(repo[None].p1().node()) + '+'
-wrev = str(repo[None].p1().rev())
+wrev = '%d' % repo[None].p1().rev()
 wrevpad = ''
 if not opts.get('changeset'): # only show + if changeset is hidden
 wrev += '+'
 wrevpad = ' '
-revenc = lambda x: wrev if x is None else str(x) + wrevpad
-csetenc = lambda x: wnode if x is None else str(x) + ' '
+revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad
+def csetenc(x):
+if x is None:
+return wnode
+return pycompat.bytestr(x) + ' '
 else:
-revenc = csetenc = str
+revenc = csetenc = pycompat.bytestr
 
 # opt name, separator, raw value (for json/plain), encoder (for plain)
 opmap = [('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
  ('number', ' ', lambda x: getctx(x).rev(), revenc),
  ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
  ('date', ' ', lambda x: getctx(x).date(), datefunc),
- ('file', ' ', lambda x: x[2], str),
- ('line_number', ':', lambda x: x[1] + 1, str)]
+ ('file', ' ', lambda x: x[2], pycompat.bytestr),
+ ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr)]
 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
 funcmap = [(get, sep, fieldnamemap.get(op, op), enc)
for op, sep, get, enc in opmap



To: pulkit, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5300: py3: replace str() with pycompat.bytestr() or ('%d' % int)

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  In https://phab.mercurial-scm.org/D5300#78881, @yuja wrote:
  
  > > - revenc = lambda x: wrev if x is None else str(x) + wrevpad
  > > - csetenc = lambda x: wnode if x is None else str(x) + ' ' +
revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad +
csetenc = lambda x: wnode if x is None else pycompat.bytestr(x) + ' '
  >
  > check-code complains that the line is too long. Maybe rewrite as a function?
  
  
  Ah, looks like I forgot to run tests. Sorry about that.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5300

To: pulkit, #hg-reviewers
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] tests: disable remotefilelog on Windows

2018-11-26 Thread Yuya Nishihara
On Sat, 24 Nov 2018 23:17:26 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1543086662 18000
> #  Sat Nov 24 14:11:02 2018 -0500
> # Node ID 99e50fb3ffc6fa3d5e81427c69e5280c84254ab0
> # Parent  1f9de5636e5f7f4bfe2d3fb8c5dde543a1870161
> tests: disable remotefilelog on Windows
> 
> I've spent a non trivial amount of time trying to eliminate the test errors, 
> but
> it's looking like this is pretty dependent on Unix support.  For example, 
> there
> are attempts to delete open files, and uses of threads that report I/O 
> attempts
> on closed files.  (Maybe this is a race condition?  Don't we usually use
> processes as workers on Windows?)
> 
> In any event, I don't want real new errors elsewhere to be masked by these 
> known
> problems.
> 
> For some reason $CACHEDIR is reported as missing in 
> test-remotefilelog-repack.t,
> but it actually exists in the hgcloneshallow call inside
> shallowutil.mkstickygroupdir().  By the time the process exits, it's gone.  I
> don't see it being removed by code that calls 'rmdir' or 'remove' in the
> extension itself.

Queued, thanks.

Should we make remotefilelog.uisetup() abort if enabled on Windows?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 06 of 13] perf: prewarm the branchmap in perfbranchmapload

2018-11-26 Thread Pulkit Goyal
On Fri, Nov 23, 2018 at 8:21 PM Boris FELD  wrote:

> On 23/11/2018 15:49, Pulkit Goyal wrote:
>
>
>
> On Fri, Nov 23, 2018 at 5:19 PM Boris Feld  wrote:
>
>> # HG changeset patch
>> # User Boris Feld 
>> # Date 1542935471 -3600
>> #  Fri Nov 23 02:11:11 2018 +0100
>> # Node ID 9f543638d909768a0db0aa779d37817c4b8878ab
>> # Parent  e72da9d014ba91ee4f2fe620a9646404a64d7484
>> # EXP-Topic perf-branchmap
>> # Available At https://bitbucket.org/octobus/mercurial-devel/
>> #  hg pull https://bitbucket.org/octobus/mercurial-devel/ -r
>> 9f543638d909
>> perf: prewarm the branchmap in perfbranchmapload
>>
>> It is not very interesting to have the command randomly failing because
>> the
>> branchmap for the tested filter happens to be cold. So we make sure to
>> have a
>> valid up to date branchmap before going further.
>>
>> The data might still be missing from disk if a subset was equivalent. See
>> next
>> changeset for details and fix.
>>
>> diff --git a/contrib/perf.py b/contrib/perf.py
>> --- a/contrib/perf.py
>> +++ b/contrib/perf.py
>> @@ -2203,6 +2203,9 @@ def perfbranchmapload(ui, repo, filter=b
>>  repo = repoview.repoview(repo, filter)
>>  else:
>>  repo = repo.unfiltered()
>> +
>> +repo.branchmap # make sure we have a relevant, up to date branchmap
>>
>
> Do you want to call this function? According to my understanding it won't
> load the branchmap or do something useful.
>
> Ho yeah, good catch.
>

Okay, appended '()' in flight and queued 6-8, many thanks!

>
> ___
> Mercurial-devel mailing 
> listMercurial-devel@mercurial-scm.orghttps://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] localrepo: correct docstring of filectx()

2018-11-26 Thread Pulkit Goyal
On Sun, Nov 25, 2018 at 4:51 PM Yuya Nishihara  wrote:

> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1543153194 -32400
> #  Sun Nov 25 22:39:54 2018 +0900
> # Node ID 3cba13b2e62284f3bd4ed3219864b7418a99f596
> # Parent  cfaf3843491bde30916b89180d5f67561a22da28
> localrepo: correct docstring of filectx()
>
> The same reason as b6c2543e1dd8. It can't be any changeset specifiers but
> revision number.
>

Queued this, many thanks!
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D5296: store: don't read the whole fncache in memory

2018-11-26 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  In https://phab.mercurial-scm.org/D5296#78834, @yuja wrote:
  
  > > diff --git a/mercurial/store.py b/mercurial/store.py
  > > 
  > >   - a/mercurial/store.py +++ b/mercurial/store.py @@ -461,13 +461,13 @@
  > > 1. skip nonexistent file self.entries = set() return
  > > - self.entries = set(decodedir(fp.read()).splitlines())
  > > - if '' in self.entries:
  > > - fp.seek(0)
  > > - for n, line in enumerate(util.iterfile(fp)):
  > > - if not line.rstrip('\n'):
  > > - t = _('invalid entry in fncache, line %d') % (n + 1)
  > > - raise error.Abort(t) +self.entries = set() +for n, line 
in enumerate(util.iterfile(fp)): +entry = line.rstrip('\n') +   
 if not entry: +t = _('invalid entry in fncache, line %d') 
% (n + 1) +raise error.Abort(t) +
self.entries.add(decodedir(entry))
  >
  > This goes the opposite direction to 
https://phab.mercurial-scm.org/rHG9fca5b056c0a2f673aefa64f7ec7488bd9188d9d. I 
guess the current code
  >  would be faster if the fncache is around ~10MB. Can you benchmark it?
  
  
  Yeah the current code is much faster if fncache is not large.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D5296

To: pulkit, #hg-reviewers
Cc: yuja, mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 4 of 4] annotate: remove dead code to not convert path to relative path

2018-11-26 Thread Martin von Zweigbergk via Mercurial-devel
On Sat, Nov 24, 2018 at 4:40 AM Yuya Nishihara  wrote:

> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1543057555 -32400
> #  Sat Nov 24 20:05:55 2018 +0900
> # Node ID 1aac31914fee54803cd5c206f0dddcc18f6120e2
> # Parent  3ba66c3809b43da8216aea05b0cef15bf3a53109
> annotate: remove dead code to not convert path to relative path
>

Queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel