docket.py
62 lines
| 2.0 KiB
| text/x-python
|
PythonLexer
Simon Sapin
|
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 | ||||
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 | ||||
# * 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) | ||||
HEADER = struct.Struct(">{}s32s32sLB".format(len(V2_FORMAT_MARKER))) | ||||
class DirstateDocket(object): | ||||
data_filename_pattern = b'dirstate.%s.d' | ||||
def __init__(self, parents, data_size, uuid): | ||||
self.parents = parents | ||||
self.data_size = data_size | ||||
self.uuid = uuid | ||||
@classmethod | ||||
def with_new_uuid(cls, parents, data): | ||||
return cls(parents, data, docket_mod.make_uid()) | ||||
@classmethod | ||||
def parse(cls, data, nodeconstants): | ||||
if not data: | ||||
parents = (nodeconstants.nullid, nodeconstants.nullid) | ||||
return cls(parents, 0, None) | ||||
marker, p1, p2, data_size, uuid_size = HEADER.unpack_from(data) | ||||
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] | ||||
return cls((p1, p2), data_size, uuid) | ||||
def serialize(self): | ||||
p1, p2 = self.parents | ||||
header = HEADER.pack( | ||||
V2_FORMAT_MARKER, p1, p2, self.data_size, len(self.uuid) | ||||
) | ||||
return header + self.uuid | ||||
def data_filename(self): | ||||
return self.data_filename_pattern % self.uuid | ||||