##// END OF EJS Templates
dirstate-v2: fix infinite loop in pure packer...
dirstate-v2: fix infinite loop in pure packer Due to the naive approach to path relative-ness, some tree shapes like the one introduced in the associated test could result in the packer going into an endless loop which allocated new `Node` objects endlessly until the process was killed by Linux's OOM killer. Differential Revision: https://phab.mercurial-scm.org/D12170

File last commit:

r49035:a32a9607 default
r49614:46d12f77 stable
Show More
docket.py
71 lines | 2.3 KiB | text/x-python | PythonLexer
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 # dirstatedocket.py - docket file for dirstate-v2
#
# Copyright Mercurial Contributors
#
# 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 struct
from ..revlogutils import docket as docket_mod
Simon Sapin
dirstate-v2: initial Python parser...
r49035 from . import v2
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474
V2_FORMAT_MARKER = b"dirstate-v2\n"
# * 12 bytes: format marker
# * 32 bytes: node ID of the working directory's first parent
# * 32 bytes: node ID of the working directory's second parent
Simon Sapin
dirstate-v2: Move data file info in the docket closer together...
r48977 # * {TREE_METADATA_SIZE} bytes: tree metadata, parsed separately
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 # * 4 bytes: big-endian used size of the data file
# * 1 byte: length of the data file's UUID
# * variable: data file's UUID
#
# Node IDs are null-padded if shorter than 32 bytes.
# A data file shorter than the specified used size is corrupted (truncated)
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 HEADER = struct.Struct(
Simon Sapin
dirstate-v2: initial Python parser...
r49035 ">{}s32s32s{}sLB".format(len(V2_FORMAT_MARKER), v2.TREE_METADATA_SIZE)
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 )
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474
class DirstateDocket(object):
Simon Sapin
dirstate-v2: Remove the `.d` suffix in data file names...
r48780 data_filename_pattern = b'dirstate.%s'
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 def __init__(self, parents, data_size, tree_metadata, uuid):
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 self.parents = parents
self.data_size = data_size
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 self.tree_metadata = tree_metadata
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 self.uuid = uuid
@classmethod
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 def with_new_uuid(cls, parents, data_size, tree_metadata):
return cls(parents, data_size, tree_metadata, docket_mod.make_uid())
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474
@classmethod
def parse(cls, data, nodeconstants):
if not data:
parents = (nodeconstants.nullid, nodeconstants.nullid)
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 return cls(parents, 0, b'', None)
Simon Sapin
dirstate-v2: Move data file info in the docket closer together...
r48977 marker, p1, p2, meta, data_size, uuid_size = HEADER.unpack_from(data)
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 if marker != V2_FORMAT_MARKER:
raise ValueError("expected dirstate-v2 marker")
uuid = data[HEADER.size : HEADER.size + uuid_size]
p1 = p1[: nodeconstants.nodelen]
p2 = p2[: nodeconstants.nodelen]
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 return cls((p1, p2), data_size, meta, uuid)
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474
def serialize(self):
p1, p2 = self.parents
header = HEADER.pack(
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 V2_FORMAT_MARKER,
p1,
p2,
Simon Sapin
dirstate-v2: Move data file info in the docket closer together...
r48977 self.tree_metadata,
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 self.data_size,
len(self.uuid),
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 )
return header + self.uuid
def data_filename(self):
return self.data_filename_pattern % self.uuid