Mercurial > hg
comparison rust/hg-core/src/dirstate_tree/on_disk.rs @ 47476:f23eafb036af
dirstate-v2: Use 32-bit integers instead of 64-bit for offsets
This saves 12 bytes per node. (Nodes representing files or directories.)
These are offsets to other parts of the file. This would only be a limitation
for a `.hg/dirstate` file larger than 4 GiB, which would only happen for a
repository with dozens of millions of files and directories.
Differential Revision: https://phab.mercurial-scm.org/D10920
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 28 Jun 2021 15:41:50 +0200 |
parents | 94e38822d395 |
children | ca8121d26732 |
comparison
equal
deleted
inserted
replaced
47475:94e38822d395 | 47476:f23eafb036af |
---|---|
15 use crate::utils::hg_path::HgPath; | 15 use crate::utils::hg_path::HgPath; |
16 use crate::DirstateEntry; | 16 use crate::DirstateEntry; |
17 use crate::DirstateError; | 17 use crate::DirstateError; |
18 use crate::DirstateParents; | 18 use crate::DirstateParents; |
19 use crate::EntryState; | 19 use crate::EntryState; |
20 use bytes_cast::unaligned::{I32Be, I64Be, U32Be, U64Be}; | 20 use bytes_cast::unaligned::{I32Be, I64Be, U32Be}; |
21 use bytes_cast::BytesCast; | 21 use bytes_cast::BytesCast; |
22 use std::borrow::Cow; | 22 use std::borrow::Cow; |
23 use std::convert::TryFrom; | 23 use std::convert::TryFrom; |
24 use std::time::{Duration, SystemTime, UNIX_EPOCH}; | 24 use std::time::{Duration, SystemTime, UNIX_EPOCH}; |
25 | 25 |
133 nanoseconds: U32Be, | 133 nanoseconds: U32Be, |
134 } | 134 } |
135 | 135 |
136 /// Counted in bytes from the start of the file | 136 /// Counted in bytes from the start of the file |
137 /// | 137 /// |
138 /// NOTE: If we decide to never support `.hg/dirstate` files larger than 4 GiB | 138 /// NOTE: not supporting `.hg/dirstate` files larger than 4 GiB. |
139 /// we could save space by using `U32Be` instead. | 139 type Offset = U32Be; |
140 type Offset = U64Be; | |
141 | 140 |
142 /// Counted in number of items | 141 /// Counted in number of items |
143 /// | 142 /// |
144 /// NOTE: not supporting directories with more than 4 billion direct children, | 143 /// NOTE: not supporting directories with more than 4 billion direct children, |
145 /// or filenames more than 4 GiB. | 144 /// or filenames more than 4 GiB. |
170 /// Either nothing if `start == 0`, or a `HgPath` of `len` bytes | 169 /// Either nothing if `start == 0`, or a `HgPath` of `len` bytes |
171 type OptPathSlice = Slice; | 170 type OptPathSlice = Slice; |
172 | 171 |
173 /// Make sure that size-affecting changes are made knowingly | 172 /// Make sure that size-affecting changes are made knowingly |
174 fn _static_assert_size_of() { | 173 fn _static_assert_size_of() { |
175 let _ = std::mem::transmute::<Header, [u8; 92]>; | 174 let _ = std::mem::transmute::<Header, [u8; 88]>; |
176 let _ = std::mem::transmute::<Node, [u8; 57]>; | 175 let _ = std::mem::transmute::<Node, [u8; 45]>; |
177 } | 176 } |
178 | 177 |
179 /// Unexpected file format found in `.hg/dirstate` with the "v2" format. | 178 /// Unexpected file format found in `.hg/dirstate` with the "v2" format. |
180 /// | 179 /// |
181 /// This should only happen if Mercurial is buggy or a repository is corrupted. | 180 /// This should only happen if Mercurial is buggy or a repository is corrupted. |
587 | 586 |
588 fn write_slice<T>(slice: &[T], out: &mut Vec<u8>) -> Slice | 587 fn write_slice<T>(slice: &[T], out: &mut Vec<u8>) -> Slice |
589 where | 588 where |
590 T: BytesCast, | 589 T: BytesCast, |
591 { | 590 { |
592 let start = u64::try_from(out.len()) | 591 let start = u32::try_from(out.len()) |
593 // Could only panic on a 128-bit CPU with a dirstate over 16 EiB | 592 // Could only panic for a dirstate file larger than 4 GiB |
594 .expect("dirstate-v2 offset overflow") | 593 .expect("dirstate-v2 offset overflow") |
595 .into(); | 594 .into(); |
596 let len = u32::try_from(slice.len()) | 595 let len = u32::try_from(slice.len()) |
597 // Could only panic for paths over 4 GiB or nodes with over 4 billions | 596 // Could only panic for paths over 4 GiB or nodes with over 4 billions |
598 // child nodes | 597 // child nodes |