Mercurial > hg
annotate rust/hg-core/src/dirstate_tree/on_disk.rs @ 48195:4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Previously we stored the entire value from `stat_result.st_mode`,
like dirstate-v1 does. However only the executable permission
and type of file (only symbolic links and normal files are supported)
are relevant to Mecurial.
So replace this field with two bits in the existing bitfield byte.
For now the unused space is left as padding, as it will be used
for something else soon.
Differential Revision: https://phab.mercurial-scm.org/D11635
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 12 Oct 2021 17:57:57 +0200 |
parents | 1000db4a71f1 |
children | 47fabca85457 |
rev | line source |
---|---|
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
1 //! The "version 2" disk representation of the dirstate |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
2 //! |
48166
e8a576de703f
dirstate-v2: Add internal documentation
Simon Sapin <simon.sapin@octobus.net>
parents:
48165
diff
changeset
|
3 //! See `mercurial/helptext/internals/dirstate-v2.txt` |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
4 |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
5 use crate::dirstate::TruncatedTimestamp; |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
6 use crate::dirstate_tree::dirstate_map::{self, DirstateMap, NodeRef}; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
7 use crate::dirstate_tree::path_with_basename::WithBasename; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
8 use crate::errors::HgError; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
9 use crate::utils::hg_path::HgPath; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
10 use crate::DirstateEntry; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
11 use crate::DirstateError; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
12 use crate::DirstateParents; |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
13 use bitflags::bitflags; |
48194
1000db4a71f1
dirstate-v2: Store unsigned integers inside DirstateEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48193
diff
changeset
|
14 use bytes_cast::unaligned::{U16Be, U32Be}; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
15 use bytes_cast::BytesCast; |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
16 use format_bytes::format_bytes; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
17 use std::borrow::Cow; |
47675
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
18 use std::convert::{TryFrom, TryInto}; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
19 |
47280
1766130fe9ba
dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 /// Added at the start of `.hg/dirstate` when the "v2" format is used. |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
21 /// This a redundant sanity check more than an actual "magic number" since |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
22 /// `.hg/requires` already governs which format should be used. |
47280
1766130fe9ba
dirstate-v2: Change the on-disk format when the requirement is enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 pub const V2_FORMAT_MARKER: &[u8; 12] = b"dirstate-v2\n"; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
24 |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
25 /// Keep space for 256-bit hashes |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
26 const STORED_NODE_ID_BYTES: usize = 32; |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
27 |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
28 /// … even though only 160 bits are used for now, with SHA-1 |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
29 const USED_NODE_ID_BYTES: usize = 20; |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
30 |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
31 pub(super) const IGNORE_PATTERNS_HASH_LEN: usize = 20; |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
32 pub(super) type IgnorePatternsHash = [u8; IGNORE_PATTERNS_HASH_LEN]; |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
33 |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
34 /// Must match the constant of the same name in |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
35 /// `mercurial/dirstateutils/docket.py` |
47684
852262e2e7d9
dirstate-v2: Reserve a few bytes of space for future extensions
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
36 const TREE_METADATA_SIZE: usize = 44; |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
37 |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
38 /// Make sure that size-affecting changes are made knowingly |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
39 #[allow(unused)] |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
40 fn static_assert_size_of() { |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
41 let _ = std::mem::transmute::<TreeMetadata, [u8; TREE_METADATA_SIZE]>; |
47684
852262e2e7d9
dirstate-v2: Reserve a few bytes of space for future extensions
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
42 let _ = std::mem::transmute::<DocketHeader, [u8; TREE_METADATA_SIZE + 81]>; |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
43 let _ = std::mem::transmute::<Node, [u8; 43]>; |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
44 } |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
45 |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
46 // Must match `HEADER` in `mercurial/dirstateutils/docket.py` |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
47 #[derive(BytesCast)] |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
48 #[repr(C)] |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
49 struct DocketHeader { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
50 marker: [u8; V2_FORMAT_MARKER.len()], |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
51 parent_1: [u8; STORED_NODE_ID_BYTES], |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
52 parent_2: [u8; STORED_NODE_ID_BYTES], |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
53 |
48165
d467e44f71d7
dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents:
48139
diff
changeset
|
54 metadata: TreeMetadata, |
d467e44f71d7
dirstate-v2: Move data file info in the docket closer together
Simon Sapin <simon.sapin@octobus.net>
parents:
48139
diff
changeset
|
55 |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
56 /// Counted in bytes |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
57 data_size: Size, |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
58 |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
59 uuid_size: u8, |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
60 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
61 |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
62 pub struct Docket<'on_disk> { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
63 header: &'on_disk DocketHeader, |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
64 uuid: &'on_disk [u8], |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
65 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
66 |
48188
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
67 /// Fields are documented in the *Tree metadata in the docket file* |
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
68 /// section of `mercurial/helptext/internals/dirstate-v2.txt` |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
69 #[derive(BytesCast)] |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
70 #[repr(C)] |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
71 struct TreeMetadata { |
47676
096ee2e260a3
dirstate-v2: Rename Header to Root, move it to the end of the data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47675
diff
changeset
|
72 root_nodes: ChildNodes, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
73 nodes_with_entry_count: Size, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
74 nodes_with_copy_source_count: Size, |
47681
d94118365ec5
dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47680
diff
changeset
|
75 unreachable_bytes: Size, |
47684
852262e2e7d9
dirstate-v2: Reserve a few bytes of space for future extensions
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
76 unused: [u8; 4], |
852262e2e7d9
dirstate-v2: Reserve a few bytes of space for future extensions
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
77 |
48188
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
78 /// See *Optional hash of ignore patterns* section of |
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
79 /// `mercurial/helptext/internals/dirstate-v2.txt` |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
80 ignore_patterns_hash: IgnorePatternsHash, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
81 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
82 |
48188
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
83 /// Fields are documented in the *The data file format* |
77fc340acad7
dirstate-v2: Document flags/mode/size/mtime fields of tree nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
48166
diff
changeset
|
84 /// section of `mercurial/helptext/internals/dirstate-v2.txt` |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
85 #[derive(BytesCast)] |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
86 #[repr(C)] |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
87 pub(super) struct Node { |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
88 full_path: PathSlice, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
89 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
90 /// In bytes from `self.full_path.start` |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
91 base_name_start: PathSize, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
92 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
93 copy_source: OptPathSlice, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
94 children: ChildNodes, |
47478
ca8121d26732
dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents:
47476
diff
changeset
|
95 pub(super) descendants_with_entry_count: Size, |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
96 pub(super) tracked_descendants_count: Size, |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
97 flags: Flags, |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
98 data: Entry, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
99 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
100 |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
101 bitflags! { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
102 #[derive(BytesCast)] |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
103 #[repr(C)] |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
104 struct Flags: u8 { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
105 const WDIR_TRACKED = 1 << 0; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
106 const P1_TRACKED = 1 << 1; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
107 const P2_INFO = 1 << 2; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
108 const HAS_MODE_AND_SIZE = 1 << 3; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
109 const HAS_MTIME = 1 << 4; |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
110 const MODE_EXEC_PERM = 1 << 5; |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
111 const MODE_IS_SYMLINK = 1 << 7; |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
112 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
113 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
114 |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
115 #[derive(BytesCast, Copy, Clone, Debug)] |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
116 #[repr(C)] |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
117 struct Entry { |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
118 _padding: U32Be, |
48194
1000db4a71f1
dirstate-v2: Store unsigned integers inside DirstateEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48193
diff
changeset
|
119 size: U32Be, |
1000db4a71f1
dirstate-v2: Store unsigned integers inside DirstateEntry
Simon Sapin <simon.sapin@octobus.net>
parents:
48193
diff
changeset
|
120 mtime: U32Be, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
121 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
122 |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
123 /// Duration since the Unix epoch |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
124 #[derive(BytesCast, Copy, Clone)] |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
125 #[repr(C)] |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
126 struct PackedTimestamp { |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
127 _padding: U32Be, |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
128 truncated_seconds: U32Be, |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
129 nanoseconds: U32Be, |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
130 } |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
131 |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
132 /// Counted in bytes from the start of the file |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
133 /// |
47476
f23eafb036af
dirstate-v2: Use 32-bit integers instead of 64-bit for offsets
Simon Sapin <simon.sapin@octobus.net>
parents:
47475
diff
changeset
|
134 /// NOTE: not supporting `.hg/dirstate` files larger than 4 GiB. |
f23eafb036af
dirstate-v2: Use 32-bit integers instead of 64-bit for offsets
Simon Sapin <simon.sapin@octobus.net>
parents:
47475
diff
changeset
|
135 type Offset = U32Be; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
136 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
137 /// Counted in number of items |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
138 /// |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
139 /// NOTE: we choose not to support counting more than 4 billion nodes anywhere. |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
140 type Size = U32Be; |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
141 |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
142 /// Counted in bytes |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
143 /// |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
144 /// NOTE: we choose not to support file names/paths longer than 64 KiB. |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
145 type PathSize = U16Be; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
146 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
147 /// A contiguous sequence of `len` times `Node`, representing the child nodes |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
148 /// of either some other node or of the repository root. |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
149 /// |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
150 /// Always sorted by ascending `full_path`, to allow binary search. |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
151 /// Since nodes with the same parent nodes also have the same parent path, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
152 /// only the `base_name`s need to be compared during binary search. |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
153 #[derive(BytesCast, Copy, Clone)] |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
154 #[repr(C)] |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
155 struct ChildNodes { |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
156 start: Offset, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
157 len: Size, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
158 } |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
159 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
160 /// A `HgPath` of `len` bytes |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
161 #[derive(BytesCast, Copy, Clone)] |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
162 #[repr(C)] |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
163 struct PathSlice { |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
164 start: Offset, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
165 len: PathSize, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
166 } |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
167 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
168 /// Either nothing if `start == 0`, or a `HgPath` of `len` bytes |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
169 type OptPathSlice = PathSlice; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
170 |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
171 /// Unexpected file format found in `.hg/dirstate` with the "v2" format. |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47334
diff
changeset
|
172 /// |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47334
diff
changeset
|
173 /// This should only happen if Mercurial is buggy or a repository is corrupted. |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47334
diff
changeset
|
174 #[derive(Debug)] |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47334
diff
changeset
|
175 pub struct DirstateV2ParseError; |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
176 |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
177 impl From<DirstateV2ParseError> for HgError { |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
178 fn from(_: DirstateV2ParseError) -> Self { |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
179 HgError::corrupted("dirstate-v2 parse error") |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
180 } |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
181 } |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
182 |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
183 impl From<DirstateV2ParseError> for crate::DirstateError { |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
184 fn from(error: DirstateV2ParseError) -> Self { |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
185 HgError::from(error).into() |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
186 } |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
187 } |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
188 |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
189 impl<'on_disk> Docket<'on_disk> { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
190 pub fn parents(&self) -> DirstateParents { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
191 use crate::Node; |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
192 let p1 = Node::try_from(&self.header.parent_1[..USED_NODE_ID_BYTES]) |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
193 .unwrap() |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
194 .clone(); |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
195 let p2 = Node::try_from(&self.header.parent_2[..USED_NODE_ID_BYTES]) |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
196 .unwrap() |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
197 .clone(); |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
198 DirstateParents { p1, p2 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
199 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
200 |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
201 pub fn tree_metadata(&self) -> &[u8] { |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
202 self.header.metadata.as_bytes() |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
203 } |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
204 |
47675
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
205 pub fn data_size(&self) -> usize { |
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
206 // This `unwrap` could only panic on a 16-bit CPU |
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
207 self.header.data_size.get().try_into().unwrap() |
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
208 } |
48aec076b8fb
dirstate-v2: Enforce data size read from the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
209 |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
210 pub fn data_filename(&self) -> String { |
47966
681851d6409b
dirstate-v2: Remove the `.d` suffix in data file names
Simon Sapin <simon.sapin@octobus.net>
parents:
47684
diff
changeset
|
211 String::from_utf8(format_bytes!(b"dirstate.{}", self.uuid)).unwrap() |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
212 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
213 } |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
214 |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
215 pub fn read_docket( |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
216 on_disk: &[u8], |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
217 ) -> Result<Docket<'_>, DirstateV2ParseError> { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
218 let (header, uuid) = |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
219 DocketHeader::from_bytes(on_disk).map_err(|_| DirstateV2ParseError)?; |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
220 let uuid_size = header.uuid_size as usize; |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
221 if header.marker == *V2_FORMAT_MARKER && uuid.len() == uuid_size { |
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
222 Ok(Docket { header, uuid }) |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
223 } else { |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
224 Err(DirstateV2ParseError) |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
225 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
226 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
227 |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
228 pub(super) fn read<'on_disk>( |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
229 on_disk: &'on_disk [u8], |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
230 metadata: &[u8], |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
231 ) -> Result<DirstateMap<'on_disk>, DirstateV2ParseError> { |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
232 if on_disk.is_empty() { |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
233 return Ok(DirstateMap::empty(on_disk)); |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
234 } |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
235 let (meta, _) = TreeMetadata::from_bytes(metadata) |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
236 .map_err(|_| DirstateV2ParseError)?; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
237 let dirstate_map = DirstateMap { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
238 on_disk, |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
239 root: dirstate_map::ChildNodes::OnDisk(read_nodes( |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
240 on_disk, |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
241 meta.root_nodes, |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
242 )?), |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
243 nodes_with_entry_count: meta.nodes_with_entry_count.get(), |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
244 nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(), |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
245 ignore_patterns_hash: meta.ignore_patterns_hash, |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
246 unreachable_bytes: meta.unreachable_bytes.get(), |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
247 }; |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47491
diff
changeset
|
248 Ok(dirstate_map) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
249 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
250 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
251 impl Node { |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
252 pub(super) fn full_path<'on_disk>( |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
253 &self, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
254 on_disk: &'on_disk [u8], |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
255 ) -> Result<&'on_disk HgPath, DirstateV2ParseError> { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
256 read_hg_path(on_disk, self.full_path) |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
257 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
258 |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
259 pub(super) fn base_name_start<'on_disk>( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
260 &self, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
261 ) -> Result<usize, DirstateV2ParseError> { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
262 let start = self.base_name_start.get(); |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
263 if start < self.full_path.len.get() { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
264 let start = usize::try_from(start) |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
265 // u32 -> usize, could only panic on a 16-bit CPU |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
266 .expect("dirstate-v2 base_name_start out of bounds"); |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
267 Ok(start) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
268 } else { |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
269 Err(DirstateV2ParseError) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
270 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
271 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
272 |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
273 pub(super) fn base_name<'on_disk>( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
274 &self, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
275 on_disk: &'on_disk [u8], |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
276 ) -> Result<&'on_disk HgPath, DirstateV2ParseError> { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
277 let full_path = self.full_path(on_disk)?; |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
278 let base_name_start = self.base_name_start()?; |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
279 Ok(HgPath::new(&full_path.as_bytes()[base_name_start..])) |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
280 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
281 |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
282 pub(super) fn path<'on_disk>( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
283 &self, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
284 on_disk: &'on_disk [u8], |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
285 ) -> Result<dirstate_map::NodeKey<'on_disk>, DirstateV2ParseError> { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
286 Ok(WithBasename::from_raw_parts( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
287 Cow::Borrowed(self.full_path(on_disk)?), |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
288 self.base_name_start()?, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
289 )) |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
290 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
291 |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
292 pub(super) fn has_copy_source<'on_disk>(&self) -> bool { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
293 self.copy_source.start.get() != 0 |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
294 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
295 |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
296 pub(super) fn copy_source<'on_disk>( |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
297 &self, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
298 on_disk: &'on_disk [u8], |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
299 ) -> Result<Option<&'on_disk HgPath>, DirstateV2ParseError> { |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
300 Ok(if self.has_copy_source() { |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
301 Some(read_hg_path(on_disk, self.copy_source)?) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
302 } else { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
303 None |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
304 }) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
305 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
306 |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
307 fn has_entry(&self) -> bool { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
308 self.flags.intersects( |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
309 Flags::WDIR_TRACKED | Flags::P1_TRACKED | Flags::P2_INFO, |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
310 ) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
311 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
312 |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
313 pub(super) fn node_data( |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
314 &self, |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
315 ) -> Result<dirstate_map::NodeData, DirstateV2ParseError> { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
316 if self.has_entry() { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
317 Ok(dirstate_map::NodeData::Entry(self.assume_entry())) |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
318 } else if let Some(mtime) = self.cached_directory_mtime()? { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
319 Ok(dirstate_map::NodeData::CachedDirectory { mtime }) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
320 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
321 Ok(dirstate_map::NodeData::None) |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
322 } |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
323 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
324 |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
325 pub(super) fn cached_directory_mtime( |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
326 &self, |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
327 ) -> Result<Option<TruncatedTimestamp>, DirstateV2ParseError> { |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
328 Ok( |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
329 if self.flags.contains(Flags::HAS_MTIME) && !self.has_entry() { |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
330 Some(self.data.as_timestamp()?) |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
331 } else { |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
332 None |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
333 }, |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
334 ) |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47348
diff
changeset
|
335 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47348
diff
changeset
|
336 |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
337 fn synthesize_unix_mode(&self) -> u32 { |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
338 let file_type = if self.flags.contains(Flags::MODE_IS_SYMLINK) { |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
339 libc::S_IFLNK |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
340 } else { |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
341 libc::S_IFREG |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
342 }; |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
343 let permisions = if self.flags.contains(Flags::MODE_EXEC_PERM) { |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
344 0o755 |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
345 } else { |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
346 0o644 |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
347 }; |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
348 file_type | permisions |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
349 } |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
350 |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
351 fn assume_entry(&self) -> DirstateEntry { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
352 // TODO: convert through raw bits instead? |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
353 let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
354 let p1_tracked = self.flags.contains(Flags::P1_TRACKED); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
355 let p2_info = self.flags.contains(Flags::P2_INFO); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
356 let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) { |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
357 Some((self.synthesize_unix_mode(), self.data.size.into())) |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
358 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
359 None |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
360 }; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
361 let mtime = if self.flags.contains(Flags::HAS_MTIME) { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
362 Some(self.data.mtime.into()) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
363 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
364 None |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
365 }; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
366 DirstateEntry::from_v2_data( |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
367 wdir_tracked, |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
368 p1_tracked, |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
369 p2_info, |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
370 mode_size, |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
371 mtime, |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47966
diff
changeset
|
372 ) |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
373 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
374 |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
375 pub(super) fn entry( |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
376 &self, |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
377 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
378 if self.has_entry() { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
379 Ok(Some(self.assume_entry())) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
380 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
381 Ok(None) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
382 } |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
383 } |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
384 |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
385 pub(super) fn children<'on_disk>( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
386 &self, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
387 on_disk: &'on_disk [u8], |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
388 ) -> Result<&'on_disk [Node], DirstateV2ParseError> { |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
389 read_nodes(on_disk, self.children) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
390 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
391 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
392 pub(super) fn to_in_memory_node<'on_disk>( |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
393 &self, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
394 on_disk: &'on_disk [u8], |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
395 ) -> Result<dirstate_map::Node<'on_disk>, DirstateV2ParseError> { |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
396 Ok(dirstate_map::Node { |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
397 children: dirstate_map::ChildNodes::OnDisk( |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
398 self.children(on_disk)?, |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
399 ), |
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
400 copy_source: self.copy_source(on_disk)?.map(Cow::Borrowed), |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
401 data: self.node_data()?, |
47478
ca8121d26732
dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents:
47476
diff
changeset
|
402 descendants_with_entry_count: self |
ca8121d26732
dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents:
47476
diff
changeset
|
403 .descendants_with_entry_count |
ca8121d26732
dirstate-tree: Keep a counter of descendant nodes that have an entry
Simon Sapin <simon.sapin@octobus.net>
parents:
47476
diff
changeset
|
404 .get(), |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
405 tracked_descendants_count: self.tracked_descendants_count.get(), |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
406 }) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
407 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
408 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
409 |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
410 impl Entry { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
411 fn from_dirstate_entry(entry: &DirstateEntry) -> (Flags, Self) { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
412 let (wdir_tracked, p1_tracked, p2_info, mode_size_opt, mtime_opt) = |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
413 entry.v2_data(); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
414 // TODO: convert throug raw flag bits instead? |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
415 let mut flags = Flags::empty(); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
416 flags.set(Flags::WDIR_TRACKED, wdir_tracked); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
417 flags.set(Flags::P1_TRACKED, p1_tracked); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
418 flags.set(Flags::P2_INFO, p2_info); |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
419 let (size, mtime); |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
420 if let Some((m, s)) = mode_size_opt { |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
421 let exec_perm = m & libc::S_IXUSR != 0; |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
422 let is_symlink = m & libc::S_IFMT == libc::S_IFLNK; |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
423 flags.set(Flags::MODE_EXEC_PERM, exec_perm); |
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
424 flags.set(Flags::MODE_IS_SYMLINK, is_symlink); |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
425 size = s; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
426 flags.insert(Flags::HAS_MODE_AND_SIZE) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
427 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
428 size = 0; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
429 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
430 if let Some(m) = mtime_opt { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
431 mtime = m; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
432 flags.insert(Flags::HAS_MTIME); |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
433 } else { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
434 mtime = 0; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
435 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
436 let raw_entry = Entry { |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
437 _padding: 0.into(), |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
438 size: size.into(), |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
439 mtime: mtime.into(), |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
440 }; |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
441 (flags, raw_entry) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
442 } |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
443 |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
444 fn from_timestamp(timestamp: TruncatedTimestamp) -> Self { |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
445 let packed = PackedTimestamp { |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
446 _padding: 0.into(), |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
447 truncated_seconds: timestamp.truncated_seconds().into(), |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
448 nanoseconds: timestamp.nanoseconds().into(), |
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
449 }; |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
450 // Safety: both types implement the `ByteCast` trait, so we could |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
451 // safely use `as_bytes` and `from_bytes` to do this conversion. Using |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
452 // `transmute` instead makes the compiler check that the two types |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
453 // have the same size, which eliminates the error case of |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
454 // `from_bytes`. |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
455 unsafe { std::mem::transmute::<PackedTimestamp, Entry>(packed) } |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
456 } |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
457 |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
458 fn as_timestamp(self) -> Result<TruncatedTimestamp, DirstateV2ParseError> { |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
459 // Safety: same as above in `from_timestamp` |
48192
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
460 let packed = |
d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
48191
diff
changeset
|
461 unsafe { std::mem::transmute::<Entry, PackedTimestamp>(self) }; |
48193
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
462 TruncatedTimestamp::from_already_truncated( |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
463 packed.truncated_seconds.get(), |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
464 packed.nanoseconds.get(), |
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48192
diff
changeset
|
465 ) |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
466 } |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
467 } |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
468 |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
469 fn read_hg_path( |
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
470 on_disk: &[u8], |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
471 slice: PathSlice, |
47337
0654b3b3d2b5
dirstate-v2: Parse the dirstate lazily, with copy-on-write nodes
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
472 ) -> Result<&HgPath, DirstateV2ParseError> { |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
473 read_slice(on_disk, slice.start, slice.len.get()).map(HgPath::new) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
474 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
475 |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
476 fn read_nodes( |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
477 on_disk: &[u8], |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
478 slice: ChildNodes, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
479 ) -> Result<&[Node], DirstateV2ParseError> { |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
480 read_slice(on_disk, slice.start, slice.len.get()) |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
481 } |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
482 |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
483 fn read_slice<T, Len>( |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
484 on_disk: &[u8], |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
485 start: Offset, |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
486 len: Len, |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
487 ) -> Result<&[T], DirstateV2ParseError> |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
488 where |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
489 T: BytesCast, |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
490 Len: TryInto<usize>, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
491 { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
492 // Either `usize::MAX` would result in "out of bounds" error since a single |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
493 // `&[u8]` cannot occupy the entire addess space. |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
494 let start = start.get().try_into().unwrap_or(std::usize::MAX); |
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
495 let len = len.try_into().unwrap_or(std::usize::MAX); |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
496 on_disk |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
497 .get(start..) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
498 .and_then(|bytes| T::slice_from_bytes(bytes, len).ok()) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
499 .map(|(slice, _rest)| slice) |
47334
18b3060fe598
dirstate-v2: Add a zero-size error type for dirstate v2 parse errors
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
500 .ok_or_else(|| DirstateV2ParseError) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
501 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
502 |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
503 pub(crate) fn for_each_tracked_path<'on_disk>( |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
504 on_disk: &'on_disk [u8], |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
505 metadata: &[u8], |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
506 mut f: impl FnMut(&'on_disk HgPath), |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
507 ) -> Result<(), DirstateV2ParseError> { |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
508 let (meta, _) = TreeMetadata::from_bytes(metadata) |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
509 .map_err(|_| DirstateV2ParseError)?; |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
510 fn recur<'on_disk>( |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
511 on_disk: &'on_disk [u8], |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
512 nodes: ChildNodes, |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
513 f: &mut impl FnMut(&'on_disk HgPath), |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
514 ) -> Result<(), DirstateV2ParseError> { |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
515 for node in read_nodes(on_disk, nodes)? { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
516 if let Some(entry) = node.entry()? { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
517 if entry.state().is_tracked() { |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
518 f(node.full_path(on_disk)?) |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
519 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
520 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
521 recur(on_disk, node.children, f)? |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
522 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
523 Ok(()) |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
524 } |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
525 recur(on_disk, meta.root_nodes, &mut f) |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
526 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
527 |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
528 /// Returns new data and metadata, together with whether that data should be |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
529 /// appended to the existing data file whose content is at |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
530 /// `dirstate_map.on_disk` (true), instead of written to a new data file |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
531 /// (false). |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
532 pub(super) fn write( |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
533 dirstate_map: &mut DirstateMap, |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
534 can_append: bool, |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
535 ) -> Result<(Vec<u8>, Vec<u8>, bool), DirstateError> { |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
536 let append = can_append && dirstate_map.write_should_append(); |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
537 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
538 // This ignores the space for paths, and for nodes without an entry. |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
539 // TODO: better estimate? Skip the `Vec` and write to a file directly? |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
540 let size_guess = std::mem::size_of::<Node>() |
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
541 * dirstate_map.nodes_with_entry_count as usize; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
542 |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
543 let mut writer = Writer { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
544 dirstate_map, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
545 append, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
546 out: Vec::with_capacity(size_guess), |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
547 }; |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
548 |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
549 let root_nodes = writer.write_nodes(dirstate_map.root.as_ref())?; |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
550 |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
551 let meta = TreeMetadata { |
47676
096ee2e260a3
dirstate-v2: Rename Header to Root, move it to the end of the data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47675
diff
changeset
|
552 root_nodes, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
553 nodes_with_entry_count: dirstate_map.nodes_with_entry_count.into(), |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
554 nodes_with_copy_source_count: dirstate_map |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
555 .nodes_with_copy_source_count |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
556 .into(), |
47681
d94118365ec5
dirstate-v2: Add heuristic for when to create a new data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47680
diff
changeset
|
557 unreachable_bytes: dirstate_map.unreachable_bytes.into(), |
47684
852262e2e7d9
dirstate-v2: Reserve a few bytes of space for future extensions
Simon Sapin <simon.sapin@octobus.net>
parents:
47682
diff
changeset
|
558 unused: [0; 4], |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47374
diff
changeset
|
559 ignore_patterns_hash: dirstate_map.ignore_patterns_hash, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
560 }; |
47682
78f7f0d490ee
dirstate-v2: Move fixed-size tree metadata into the docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47681
diff
changeset
|
561 Ok((writer.out, meta.as_bytes().to_vec(), append)) |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
562 } |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
563 |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
564 struct Writer<'dmap, 'on_disk> { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
565 dirstate_map: &'dmap DirstateMap<'on_disk>, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
566 append: bool, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
567 out: Vec<u8>, |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
568 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
569 |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
570 impl Writer<'_, '_> { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
571 fn write_nodes( |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
572 &mut self, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
573 nodes: dirstate_map::ChildNodesRef, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
574 ) -> Result<ChildNodes, DirstateError> { |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
575 // Reuse already-written nodes if possible |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
576 if self.append { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
577 if let dirstate_map::ChildNodesRef::OnDisk(nodes_slice) = nodes { |
47680
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
578 let start = self.on_disk_offset_of(nodes_slice).expect( |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
579 "dirstate-v2 OnDisk nodes not found within on_disk", |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
580 ); |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
581 let len = child_nodes_len_from_usize(nodes_slice.len()); |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
582 return Ok(ChildNodes { start, len }); |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
583 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
584 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
585 |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
586 // `dirstate_map::ChildNodes::InMemory` contains a `HashMap` which has |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
587 // undefined iteration order. Sort to enable binary search in the |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
588 // written file. |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
589 let nodes = nodes.sorted(); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
590 let nodes_len = nodes.len(); |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
591 |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
592 // First accumulate serialized nodes in a `Vec` |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
593 let mut on_disk_nodes = Vec::with_capacity(nodes_len); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
594 for node in nodes { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
595 let children = |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
596 self.write_nodes(node.children(self.dirstate_map.on_disk)?)?; |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
597 let full_path = node.full_path(self.dirstate_map.on_disk)?; |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
598 let full_path = self.write_path(full_path.as_bytes()); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
599 let copy_source = if let Some(source) = |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
600 node.copy_source(self.dirstate_map.on_disk)? |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
601 { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
602 self.write_path(source.as_bytes()) |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
603 } else { |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
604 PathSlice { |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
605 start: 0.into(), |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
606 len: 0.into(), |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
607 } |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
608 }; |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
609 on_disk_nodes.push(match node { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
610 NodeRef::InMemory(path, node) => { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
611 let (flags, data) = match &node.data { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
612 dirstate_map::NodeData::Entry(entry) => { |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
613 Entry::from_dirstate_entry(entry) |
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
614 } |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
615 dirstate_map::NodeData::CachedDirectory { mtime } => { |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
616 (Flags::HAS_MTIME, Entry::from_timestamp(*mtime)) |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
617 } |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
618 dirstate_map::NodeData::None => ( |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
619 Flags::empty(), |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
620 Entry { |
48195
4d5a13253d34
dirstate-v2: Replace the 32-bit `mode` field with two bits
Simon Sapin <simon.sapin@octobus.net>
parents:
48194
diff
changeset
|
621 _padding: 0.into(), |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
622 size: 0.into(), |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
623 mtime: 0.into(), |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
624 }, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
625 ), |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
626 }; |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
627 Node { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
628 children, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
629 copy_source, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
630 full_path, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
631 base_name_start: u16::try_from(path.base_name_start()) |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
632 // Could only panic for paths over 64 KiB |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
633 .expect("dirstate-v2 path length overflow") |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
634 .into(), |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
635 descendants_with_entry_count: node |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
636 .descendants_with_entry_count |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
637 .into(), |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
638 tracked_descendants_count: node |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
639 .tracked_descendants_count |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
640 .into(), |
48139
ab5a7fdbf75c
dirstate-v2: Store a bitfield on disk instead of v1-like state
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
641 flags, |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
642 data, |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
643 } |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
644 } |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
645 NodeRef::OnDisk(node) => Node { |
47348
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
646 children, |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
647 copy_source, |
a4de570e61fa
dirstate-v2: Allow tree nodes without an entry to store a timestamp
Simon Sapin <simon.sapin@octobus.net>
parents:
47337
diff
changeset
|
648 full_path, |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
649 ..*node |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
650 }, |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
651 }) |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
652 } |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
653 // … so we can write them contiguously, after writing everything else |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
654 // they refer to. |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
655 let start = self.current_offset(); |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
656 let len = child_nodes_len_from_usize(nodes_len); |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
657 self.out.extend(on_disk_nodes.as_bytes()); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
658 Ok(ChildNodes { start, len }) |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
659 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
660 |
47680
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
661 /// If the given slice of items is within `on_disk`, returns its offset |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
662 /// from the start of `on_disk`. |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
663 fn on_disk_offset_of<T>(&self, slice: &[T]) -> Option<Offset> |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
664 where |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
665 T: BytesCast, |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
666 { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
667 fn address_range(slice: &[u8]) -> std::ops::RangeInclusive<usize> { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
668 let start = slice.as_ptr() as usize; |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
669 let end = start + slice.len(); |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
670 start..=end |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
671 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
672 let slice_addresses = address_range(slice.as_bytes()); |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
673 let on_disk_addresses = address_range(self.dirstate_map.on_disk); |
47680
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
674 if on_disk_addresses.contains(slice_addresses.start()) |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
675 && on_disk_addresses.contains(slice_addresses.end()) |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
676 { |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
677 let offset = slice_addresses.start() - on_disk_addresses.start(); |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
678 Some(offset_from_usize(offset)) |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
679 } else { |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
680 None |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
681 } |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
682 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
683 |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
684 fn current_offset(&mut self) -> Offset { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
685 let mut offset = self.out.len(); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
686 if self.append { |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
687 offset += self.dirstate_map.on_disk.len() |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
688 } |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
689 offset_from_usize(offset) |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
690 } |
47677
da1c0cd68d53
dirstate-v2: shrink on-disk path lengths to 16-bits
Simon Sapin <simon.sapin@octobus.net>
parents:
47676
diff
changeset
|
691 |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
692 fn write_path(&mut self, slice: &[u8]) -> PathSlice { |
47680
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
693 let len = path_len_from_usize(slice.len()); |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
694 // Reuse an already-written path if possible |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
695 if self.append { |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
696 if let Some(start) = self.on_disk_offset_of(slice) { |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
697 return PathSlice { start, len }; |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
698 } |
a8b0f29dc0d7
dirstate-v2: Reuse existing paths when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47679
diff
changeset
|
699 } |
47678
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
700 let start = self.current_offset(); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
701 self.out.extend(slice.as_bytes()); |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
702 PathSlice { start, len } |
065e61628980
dirstate-v2: Support appending to the same data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47677
diff
changeset
|
703 } |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47280
diff
changeset
|
704 } |
47679
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
705 |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
706 fn offset_from_usize(x: usize) -> Offset { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
707 u32::try_from(x) |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
708 // Could only panic for a dirstate file larger than 4 GiB |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
709 .expect("dirstate-v2 offset overflow") |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
710 .into() |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
711 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
712 |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
713 fn child_nodes_len_from_usize(x: usize) -> Size { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
714 u32::try_from(x) |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
715 // Could only panic with over 4 billion nodes |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
716 .expect("dirstate-v2 slice length overflow") |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
717 .into() |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
718 } |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
719 |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
720 fn path_len_from_usize(x: usize) -> PathSize { |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
721 u16::try_from(x) |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
722 // Could only panic for paths over 64 KiB |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
723 .expect("dirstate-v2 path length overflow") |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
724 .into() |
731286dc5321
dirstate-v2: Reuse existing nodes when appending to a data file
Simon Sapin <simon.sapin@octobus.net>
parents:
47678
diff
changeset
|
725 } |