sapling/remotefilelog/wirepack.py
Durham Goode 2b12f514c7 treemanifest: include tree pack during pushes
Summary:
To enable pushing between peers (and eventually pushing to the server), let's
teach bundle creation to include the trees being pushed.

Test Plan: Adds a test

Reviewers: #mercurial, quark

Reviewed By: quark

Subscribers: quark, mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D4957456

Signature: t1:4957456:1493266296:67f98a2b3d691644bde9098a713d05266f349cde
2017-04-27 10:44:34 -07:00

105 lines
3.6 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.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)
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
# 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)
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)