mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 17:27:53 +03:00
c8c72f8201
Summary: This adds a simple progress bar while the client receives a pack. We don't know ahead of time how large it will be, so we can only provide the bouncy bar kind. But we can show an increasing number of things downloaded, so they know something is actually happening. Test Plan: Ran hg pull with the extension enabled, verified there was a progress bar during the tree prefetch. Reviewers: #mercurial, quark Reviewed By: quark Subscribers: mjpieters Differential Revision: https://phabricator.intern.facebook.com/D5098564 Signature: t1:5098564:1495235358:0020b28da890813f11dba70b157e526e7be418f8
112 lines
3.8 KiB
Python
112 lines
3.8 KiB
Python
# wirepack.py - wireprotocol for exchanging packs
|
|
#
|
|
# Copyright 2017 Facebook, Inc.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
from mercurial.i18n import _
|
|
from mercurial.node import nullid
|
|
import constants
|
|
import struct
|
|
from collections import defaultdict
|
|
|
|
from shallowutil import readexactly, readunpack, mkstickygroupdir, readpath
|
|
import datapack, historypack, shallowutil
|
|
|
|
def sendpackpart(filename, history, data):
|
|
rawfilenamelen = struct.pack(constants.FILENAMESTRUCT,
|
|
len(filename))
|
|
yield '%s%s' % (rawfilenamelen, filename)
|
|
|
|
# Serialize and send history
|
|
historylen = struct.pack('!I', len(history))
|
|
rawhistory = ''
|
|
for entry in history:
|
|
copyfrom = entry[4] or ''
|
|
copyfromlen = len(copyfrom)
|
|
tup = entry[:-1] + (copyfromlen,)
|
|
rawhistory += struct.pack('!20s20s20s20sH', *tup)
|
|
if copyfrom:
|
|
rawhistory += copyfrom
|
|
|
|
yield '%s%s' % (historylen, rawhistory)
|
|
|
|
# Serialize and send data
|
|
yield struct.pack('!I', len(data))
|
|
|
|
for node, deltabase, delta in data:
|
|
deltalen = struct.pack('!Q', len(delta))
|
|
yield '%s%s%s%s' % (node, deltabase, deltalen, delta)
|
|
|
|
def closepart():
|
|
return '\0' * 10
|
|
|
|
def receivepack(ui, fh, packpath):
|
|
receiveddata = []
|
|
receivedhistory = []
|
|
mkstickygroupdir(ui, packpath)
|
|
totalcount = 0
|
|
ui.progress(_("receiving pack"), totalcount)
|
|
with datapack.mutabledatapack(ui, packpath) as dpack:
|
|
with historypack.mutablehistorypack(ui, packpath) as hpack:
|
|
pendinghistory = defaultdict(dict)
|
|
while True:
|
|
filename = readpath(fh)
|
|
count = 0
|
|
|
|
# Store the history for later sorting
|
|
for value in readhistory(fh):
|
|
node = value[0]
|
|
pendinghistory[filename][node] = value
|
|
receivedhistory.append((filename, node))
|
|
count += 1
|
|
|
|
for node, deltabase, delta in readdeltas(fh):
|
|
dpack.add(filename, node, deltabase, delta)
|
|
receiveddata.append((filename, node))
|
|
count += 1
|
|
|
|
if count == 0 and filename == '':
|
|
break
|
|
totalcount += 1
|
|
ui.progress(_("receiving pack"), totalcount)
|
|
|
|
# Add history to pack in toposorted order
|
|
for filename, nodevalues in sorted(pendinghistory.iteritems()):
|
|
def _parentfunc(node):
|
|
p1, p2 = nodevalues[node][1:3]
|
|
parents = []
|
|
if p1 != nullid:
|
|
parents.append(p1)
|
|
if p2 != nullid:
|
|
parents.append(p2)
|
|
return parents
|
|
sortednodes = reversed(shallowutil.sortnodes(
|
|
nodevalues.iterkeys(),
|
|
_parentfunc))
|
|
for node in sortednodes:
|
|
node, p1, p2, linknode, copyfrom = nodevalues[node]
|
|
hpack.add(filename, node, p1, p2, linknode, copyfrom)
|
|
ui.progress(_("receiving pack"), None)
|
|
|
|
return receiveddata, receivedhistory
|
|
|
|
def readhistory(fh):
|
|
count = readunpack(fh, '!I')[0]
|
|
for i in xrange(count):
|
|
entry = readunpack(fh,'!20s20s20s20sH')
|
|
if entry[4] != 0:
|
|
copyfrom = readexactly(fh, entry[4])
|
|
else:
|
|
copyfrom = ''
|
|
entry = entry[:4] + (copyfrom,)
|
|
yield entry
|
|
|
|
def readdeltas(fh):
|
|
count = readunpack(fh, '!I')[0]
|
|
for i in xrange(count):
|
|
node, deltabase, deltalen = readunpack(fh, '!20s20sQ')
|
|
delta = readexactly(fh, deltalen)
|
|
yield (node, deltabase, delta)
|