mercurial/dirstateutils/docket.py
author Manuel Jacob <me@manueljacob.de>
Thu, 15 Sep 2022 01:48:38 +0200
changeset 49494 c96ed4029fda
parent 48946 642e31cb55f0
permissions -rw-r--r--
templates: add filter to reverse list The filter supports only lists because for lists, it’s straightforward to implement. Reversing text doesn’t seem very useful and is hard to implement. Reversing the bytes would break multi-bytes encodings. Reversing the code points would break characters consisting of multiple code points. Reversing graphemes is non-trivial without using a library not included in the standard library.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     1
# dirstatedocket.py - docket file for dirstate-v2
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     2
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
# Copyright Mercurial Contributors
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     4
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     7
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     8
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     9
import struct
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    10
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    11
from ..revlogutils import docket as docket_mod
48221
a32a96079e2d dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48165
diff changeset
    12
from . import v2
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    13
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    14
V2_FORMAT_MARKER = b"dirstate-v2\n"
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    15
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    16
# * 12 bytes: format marker
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    17
# * 32 bytes: node ID of the working directory's first parent
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    18
# * 32 bytes: node ID of the working directory's second parent
48165
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47966
diff changeset
    19
# * {TREE_METADATA_SIZE} bytes: tree metadata, parsed separately
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    20
# * 4 bytes: big-endian used size of the data file
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    21
# * 1 byte: length of the data file's UUID
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    22
# * variable: data file's UUID
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    23
#
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    24
# Node IDs are null-padded if shorter than 32 bytes.
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    25
# A data file shorter than the specified used size is corrupted (truncated)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    26
HEADER = struct.Struct(
48221
a32a96079e2d dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48165
diff changeset
    27
    ">{}s32s32s{}sLB".format(len(V2_FORMAT_MARKER), v2.TREE_METADATA_SIZE)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    28
)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    29
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    30
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    31
class DirstateDocket:
47966
681851d6409b dirstate-v2: Remove the `.d` suffix in data file names
Simon Sapin <simon.sapin@octobus.net>
parents: 47684
diff changeset
    32
    data_filename_pattern = b'dirstate.%s'
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    33
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    34
    def __init__(self, parents, data_size, tree_metadata, uuid):
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    35
        self.parents = parents
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    36
        self.data_size = data_size
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    37
        self.tree_metadata = tree_metadata
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    38
        self.uuid = uuid
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    39
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    40
    @classmethod
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    41
    def with_new_uuid(cls, parents, data_size, tree_metadata):
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    42
        return cls(parents, data_size, tree_metadata, docket_mod.make_uid())
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    43
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    44
    @classmethod
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    45
    def parse(cls, data, nodeconstants):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    46
        if not data:
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    47
            parents = (nodeconstants.nullid, nodeconstants.nullid)
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    48
            return cls(parents, 0, b'', None)
48165
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47966
diff changeset
    49
        marker, p1, p2, meta, data_size, uuid_size = HEADER.unpack_from(data)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    50
        if marker != V2_FORMAT_MARKER:
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    51
            raise ValueError("expected dirstate-v2 marker")
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    52
        uuid = data[HEADER.size : HEADER.size + uuid_size]
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    53
        p1 = p1[: nodeconstants.nodelen]
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    54
        p2 = p2[: nodeconstants.nodelen]
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    55
        return cls((p1, p2), data_size, meta, uuid)
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    56
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    57
    def serialize(self):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    58
        p1, p2 = self.parents
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    59
        header = HEADER.pack(
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    60
            V2_FORMAT_MARKER,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    61
            p1,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    62
            p2,
48165
d467e44f71d7 dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents: 47966
diff changeset
    63
            self.tree_metadata,
47682
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    64
            self.data_size,
78f7f0d490ee dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47674
diff changeset
    65
            len(self.uuid),
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    66
        )
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    67
        return header + self.uuid
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    68
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    69
    def data_filename(self):
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    70
        return self.data_filename_pattern % self.uuid