##// END OF EJS Templates
dirstate-v2: Add heuristic for when to create a new data file...
dirstate-v2: Add heuristic for when to create a new data file … instead of appending to the existing one. This is based on keeping track of how much of the existing data is not used anymore. Differential Revision: https://phab.mercurial-scm.org/D11097

File last commit:

r48474:ff97e793 default
r48481:d9411836 default
Show More
docket.py
62 lines | 2.0 KiB | text/x-python | PythonLexer
# 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