transaction: build changes['revs'] as range instead of a set

Revisions are added consecutively, so a range can easily represent them
in the changes list. This saves around 45 Bytes / revision on 64bit
platforms and reduces the memory footprint of issue5691 by 15MB.

Don't copy changes['revs'] in getobsoleted. Ranges have a very efficient
contains implementation already.

Differential Revision: https://phab.mercurial-scm.org/D1615
This commit is contained in:
Joerg Sonnenberger 2017-12-08 01:23:34 +01:00
parent b3191ab441
commit 9c25f296a4
4 changed files with 10 additions and 5 deletions

View File

@ -541,5 +541,10 @@ class changelog(revlog.revlog):
*args, **kwargs)
revs = transaction.changes.get('revs')
if revs is not None:
revs.add(rev)
if revs:
assert revs[-1] + 1 == rev
revs = xrange(revs[0], rev + 1)
else:
revs = xrange(rev, rev + 1)
transaction.changes['revs'] = revs
return node

View File

@ -1275,7 +1275,7 @@ class localrepository(object):
validator=validate,
releasefn=releasefn,
checkambigfiles=_cachedfiles)
tr.changes['revs'] = set()
tr.changes['revs'] = xrange(0, 0)
tr.changes['obsmarkers'] = set()
tr.changes['phases'] = {}
tr.changes['bookmarks'] = {}

View File

@ -441,12 +441,12 @@ def getobsoleted(repo, tr):
public = phases.public
addedmarkers = tr.changes.get('obsmarkers')
addedrevs = tr.changes.get('revs')
seenrevs = set(addedrevs)
seenrevs = set()
obsoleted = set()
for mark in addedmarkers:
node = mark[0]
rev = torev(node)
if rev is None or rev in seenrevs:
if rev is None or rev in seenrevs or rev in addedrevs:
continue
seenrevs.add(rev)
if phase(repo, rev) == public:

View File

@ -1262,7 +1262,7 @@ def registersummarycallback(repo, otr, txnname=''):
@reportsummary
def reportnewcs(repo, tr):
"""Report the range of new revisions pulled/unbundled."""
newrevs = list(tr.changes.get('revs', set()))
newrevs = tr.changes.get('revs', xrange(0, 0))
if not newrevs:
return