Mercurial > hg
changeset 26469:fb743268510e
streamclone: move payload header generation into own function
The stream clone data over the wire protocol contains a header line
indicating total file count and data size. In bundle2, this metadata can
be captured by a part parameter and doesn't need to be in the body.
In preparation for bundle2, have generatev1() return the raw metadata
and move the header generation to its own function.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sun, 04 Oct 2015 19:06:06 -0700 |
parents | 19bbd53af46d |
children | 4b5647d9ee13 |
files | mercurial/streamclone.py mercurial/wireproto.py |
diffstat | 2 files changed, 37 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/streamclone.py Sun Oct 04 18:44:46 2015 -0700 +++ b/mercurial/streamclone.py Sun Oct 04 19:06:06 2015 -0700 @@ -164,13 +164,12 @@ def generatev1(repo): """Emit content for version 1 of a streaming clone. - This is a generator of raw chunks that constitute a streaming clone. + This returns a 3-tuple of (file count, byte size, data iterator). - The stream begins with a line of 2 space-delimited integers containing the - number of entries and total bytes size. + The data iterator consists of N entries for each file being transferred. + Each file entry starts as a line with the file name and integer size + delimited by a null byte. - Next, are N entries for each file being transferred. Each file entry starts - as a line with the file name and integer size delimited by a null byte. The raw file data follows. Following the raw file data is the next file entry, or EOF. @@ -196,31 +195,44 @@ repo.ui.debug('%d files, %d bytes to transfer\n' % (len(entries), total_bytes)) - yield '%d %d\n' % (len(entries), total_bytes) svfs = repo.svfs oldaudit = svfs.mustaudit debugflag = repo.ui.debugflag svfs.mustaudit = False - try: - for name, size in entries: - if debugflag: - repo.ui.debug('sending %s (%d bytes)\n' % (name, size)) - # partially encode name over the wire for backwards compat - yield '%s\0%d\n' % (store.encodedir(name), size) - if size <= 65536: - fp = svfs(name) - try: - data = fp.read(size) - finally: - fp.close() - yield data - else: - for chunk in util.filechunkiter(svfs(name), limit=size): - yield chunk - finally: - svfs.mustaudit = oldaudit + def emitrevlogdata(): + try: + for name, size in entries: + if debugflag: + repo.ui.debug('sending %s (%d bytes)\n' % (name, size)) + # partially encode name over the wire for backwards compat + yield '%s\0%d\n' % (store.encodedir(name), size) + if size <= 65536: + fp = svfs(name) + try: + data = fp.read(size) + finally: + fp.close() + yield data + else: + for chunk in util.filechunkiter(svfs(name), limit=size): + yield chunk + finally: + svfs.mustaudit = oldaudit + + return len(entries), total_bytes, emitrevlogdata() + +def generatev1wireproto(repo): + """Emit content for version 1 of streaming clone suitable for the wire. + + This is the data output from ``generatev1()`` with a header line + indicating file count and byte size. + """ + filecount, bytecount, it = generatev1(repo) + yield '%d %d\n' % (filecount, bytecount) + for chunk in it: + yield chunk def consumev1(repo, fp, filecount, bytecount): """Apply the contents from version 1 of a streaming clone file handle.
--- a/mercurial/wireproto.py Sun Oct 04 18:44:46 2015 -0700 +++ b/mercurial/wireproto.py Sun Oct 04 19:06:06 2015 -0700 @@ -718,7 +718,7 @@ try: # LockError may be raised before the first result is yielded. Don't # emit output until we're sure we got the lock successfully. - it = streamclone.generatev1(repo) + it = streamclone.generatev1wireproto(repo) return streamres(getstream(it)) except error.LockError: return '2\n'