[PATCH 2 of 3] obsolete: append new markers to obsstore file instead of rewriting everything
Adrian Buehlmann
adrian at cadifra.com
Sun Jul 15 06:40:58 CDT 2012
On 2012-07-04 02:26, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1341360168 -7200
> # Node ID 194c37e42b720e5ee9c2bba9f6d8d306cb3e1766
> # Parent f7efc57ef2e61b94028726e5887ce97d159c2524
> obsolete: append new markers to obsstore file instead of rewriting everything
>
> This is the second step toward incremental writing of marker inside a transaction.
> The obsstore file is now handled append only.
>
> Header writing have been extracted from _writemarkers.
>
> Because the _writemarkers method have been dropped, the push code directly reuse
> the serialised content of local repo `listkeys`. This is not very pretty, but this
> part of the protocol still need major improvement anyway.
>
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -1808,9 +1808,8 @@
> self.ui.warn(_('updating %s to public failed!\n')
> % newremotehead)
> if 'obsolete' in self.listkeys('namespaces') and self.obsstore:
> - data = self.obsstore._writemarkers()
> - r = remote.pushkey('obsolete', 'dump', '',
> - base85.b85encode(data))
> + data = self.listkeys('obsolete')['dump']
> + r = remote.pushkey('obsolete', 'dump', '', data)
> if not r:
> self.ui.warn(_('failed to push obsolete markers!\n'))
> finally:
> diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
> --- a/mercurial/obsolete.py
> +++ b/mercurial/obsolete.py
> @@ -209,12 +209,14 @@
> """Write all markers on disk
>
> After this operation, "new" markers are considered "known"."""
> + # XXX: transaction logic should be used
> if self._new:
> - # XXX: transaction logic should be used here. But for
> - # now rewriting the whole file is good enough.
> - f = self.sopener('obsstore', 'wb', atomictemp=True)
> + f = self.sopener('obsstore', 'ab')
> try:
> - self._writemarkers(f)
> + if f.tell() == 0:
> + # plain new obsstore
> + f.write(_pack('>B', _fmversion))
> + _writemarkers(f.write, self._new)
> f.close()
> self._new[:] = []
> except: # re-raises
> @@ -228,32 +230,25 @@
> for suc in sucs:
> self.successors.setdefault(suc, set()).add(marker)
>
> - def _writemarkers(self, stream=None):
> - # Kept separate from flushmarkers(), it will be reused for
> - # markers exchange.
> - if stream is None:
> - final = []
> - w = final.append
> - else:
> - w = stream.write
> - w(_pack('>B', _fmversion))
> - for marker in self._all:
> - pre, sucs, flags, metadata = marker
> - nbsuc = len(sucs)
> - format = _fmfixed + (_fmnode * nbsuc)
> - data = [nbsuc, len(metadata), flags, pre]
> - data.extend(sucs)
> - w(_pack(format, *data))
> - w(metadata)
> - if stream is None:
> - return ''.join(final)
> +def _writemarkers(write, markers):
> + # Kept separate from flushmarkers(), it will be reused for
> + # markers exchange.
> + for marker in markers:
> + pre, sucs, flags, metadata = marker
> + nbsuc = len(sucs)
> + format = _fmfixed + (_fmnode * nbsuc)
> + data = [nbsuc, len(metadata), flags, pre]
> + data.extend(sucs)
> + write(_pack(format, *data))
> + write(metadata)
>
> def listmarkers(repo):
> """List markers over pushkey"""
> if not repo.obsstore:
> return {}
> - data = repo.obsstore._writemarkers()
> - return {'dump': base85.b85encode(data)}
> + data = [_pack('>B', _fmversion)]
> + _writemarkers(data.append, repo.obsstore)
> + return {'dump': base85.b85encode(''.join(data))}
>
> def pushmarker(repo, key, old, new):
> """Push markers over pushkey"""
This was pushed as http://selenic.com/repo/hg/rev/95d785ccb4e5
Bisecting reveals that it is the first changeset that causes test-obsolete.t to
fail on Windows with:
--- C:\Users\adi\hgrepos\hg-main\tests\test-obsolete.t
+++ C:\Users\adi\hgrepos\hg-main\tests\test-obsolete.t.err
@@ -43,8 +43,8 @@
created new head
$ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
$ hg debugobsolete
- 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
- cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ abort: parsing obsolete marker: metadata is too short, 42 bytes expected, got 16777216
+ [255]
See also
http://hgbuildbot.kublai.com/builders/Windows%202008%20R2%20hg%20tests/builds/148/steps/run-tests.py%20%28python2.6%29/logs/stdio
More information about the Mercurial-devel
mailing list