Details
Details
- Reviewers
indygreg - Group Reviewers
hg-reviewers - Commits
- rHG64b16de2c66a: remotefilelog: remove now-unused wirepack code
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
( )
indygreg |
hg-reviewers |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
D | M | hgext/remotefilelog/wirepack.py (235 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
Augie Fackler | Oct 16 2018, 2:04 PM |
Status | Author | Revision | |
---|---|---|---|
Closed | pulkit | ||
Closed | pulkit | ||
Closed | pulkit | ||
Closed | pulkit | ||
Closed | pulkit | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 |
# 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 __future__ import absolute_import | |||||
import StringIO | |||||
import collections | |||||
import struct | |||||
from mercurial.i18n import _ | |||||
from mercurial.node import nullid | |||||
from mercurial import ( | |||||
pycompat, | |||||
) | |||||
from . import ( | |||||
constants, | |||||
datapack, | |||||
historypack, | |||||
shallowutil, | |||||
) | |||||
def sendpackpart(filename, history, data): | |||||
"""A wirepack is formatted as follows: | |||||
wirepack = <filename len: 2 byte unsigned int><filename> | |||||
<history len: 4 byte unsigned int>[<history rev>,...] | |||||
<data len: 4 byte unsigned int>[<data rev>,...] | |||||
hist rev = <node: 20 byte> | |||||
<p1node: 20 byte> | |||||
<p2node: 20 byte> | |||||
<linknode: 20 byte> | |||||
<copyfromlen: 2 byte unsigned int> | |||||
<copyfrom> | |||||
data rev = <node: 20 byte> | |||||
<deltabasenode: 20 byte> | |||||
<delta len: 8 byte unsigned int> | |||||
<delta> | |||||
""" | |||||
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)) | |||||
# TODO: support datapack metadata | |||||
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 = [] | |||||
shallowutil.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 = collections.defaultdict(dict) | |||||
while True: | |||||
filename = shallowutil.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 = shallowutil.readunpack(fh, '!I')[0] | |||||
for i in pycompat.xrange(count): | |||||
entry = shallowutil.readunpack(fh,'!20s20s20s20sH') | |||||
if entry[4] != 0: | |||||
copyfrom = shallowutil.readexactly(fh, entry[4]) | |||||
else: | |||||
copyfrom = '' | |||||
entry = entry[:4] + (copyfrom,) | |||||
yield entry | |||||
def readdeltas(fh): | |||||
count = shallowutil.readunpack(fh, '!I')[0] | |||||
for i in pycompat.xrange(count): | |||||
node, deltabase, deltalen = shallowutil.readunpack(fh, '!20s20sQ') | |||||
delta = shallowutil.readexactly(fh, deltalen) | |||||
yield (node, deltabase, delta) | |||||
class wirepackstore(object): | |||||
def __init__(self, wirepack): | |||||
self._data = {} | |||||
self._history = {} | |||||
fh = StringIO.StringIO(wirepack) | |||||
self._load(fh) | |||||
def get(self, name, node): | |||||
raise RuntimeError("must use getdeltachain with wirepackstore") | |||||
def getdeltachain(self, name, node): | |||||
delta, deltabase = self._data[(name, node)] | |||||
return [(name, node, name, deltabase, delta)] | |||||
def getmeta(self, name, node): | |||||
try: | |||||
size = len(self._data[(name, node)]) | |||||
except KeyError: | |||||
raise KeyError((name, hex(node))) | |||||
return {constants.METAKEYFLAG: '', | |||||
constants.METAKEYSIZE: size} | |||||
def getancestors(self, name, node, known=None): | |||||
if known is None: | |||||
known = set() | |||||
if node in known: | |||||
return [] | |||||
ancestors = {} | |||||
seen = set() | |||||
missing = [(name, node)] | |||||
while missing: | |||||
curname, curnode = missing.pop() | |||||
info = self._history.get((name, node)) | |||||
if info is None: | |||||
continue | |||||
p1, p2, linknode, copyfrom = info | |||||
if p1 != nullid and p1 not in known: | |||||
key = (name if not copyfrom else copyfrom, p1) | |||||
if key not in seen: | |||||
seen.add(key) | |||||
missing.append(key) | |||||
if p2 != nullid and p2 not in known: | |||||
key = (name, p2) | |||||
if key not in seen: | |||||
seen.add(key) | |||||
missing.append(key) | |||||
ancestors[curnode] = (p1, p2, linknode, copyfrom) | |||||
if not ancestors: | |||||
raise KeyError((name, hex(node))) | |||||
return ancestors | |||||
def getnodeinfo(self, name, node): | |||||
try: | |||||
return self._history[(name, node)] | |||||
except KeyError: | |||||
raise KeyError((name, hex(node))) | |||||
def add(self, *args): | |||||
raise RuntimeError("cannot add to a wirepack store") | |||||
def getmissing(self, keys): | |||||
missing = [] | |||||
for name, node in keys: | |||||
if (name, node) not in self._data: | |||||
missing.append((name, node)) | |||||
return missing | |||||
def _load(self, fh): | |||||
data = self._data | |||||
history = self._history | |||||
while True: | |||||
filename = shallowutil.readpath(fh) | |||||
count = 0 | |||||
# Store the history for later sorting | |||||
for value in readhistory(fh): | |||||
node = value[0] | |||||
history[(filename, node)] = value[1:] | |||||
count += 1 | |||||
for node, deltabase, delta in readdeltas(fh): | |||||
data[(filename, node)] = (delta, deltabase) | |||||
count += 1 | |||||
if count == 0 and filename == '': | |||||
break | |||||
def markledger(self, ledger, options=None): | |||||
pass | |||||
def cleanup(self, ledger): | |||||
pass |