Details
Details
- Reviewers
Alphare - Group Reviewers
hg-reviewers
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
| Alphare |
| hg-reviewers |
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | rust/hg-core/src/revlog/nodemap_docket.rs (12 lines) | |||
| M | rust/hg-core/src/revlog/revlog.rs (2 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| ea65c742e121 | dedd6ed19123 | Martin von Zweigbergk | Fri, Apr 1, 1:54 AM |
| Status | Author | Revision | |
|---|---|---|---|
| Needs Review | martinvonz | ||
| Needs Review | martinvonz | ||
| Accepted | martinvonz | ||
| Accepted | martinvonz | ||
| Needs Review | martinvonz | ||
| Needs Review | martinvonz | ||
| Needs Review | martinvonz | ||
| Needs Review | martinvonz | ||
| Needs Review | martinvonz | ||
| Closed | martinvonz | ||
| Accepted | martinvonz | ||
| Accepted | martinvonz | ||
| Needs Review | martinvonz | ||
| Accepted | martinvonz | ||
| Accepted | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz |
| use crate::errors::{HgError, HgResultExt}; | use crate::errors::{HgError, HgResultExt}; | ||||
| use bytes_cast::{unaligned, BytesCast}; | use bytes_cast::{unaligned, BytesCast}; | ||||
| use memmap2::Mmap; | use memmap2::Mmap; | ||||
| use std::path::{Path, PathBuf}; | use std::path::{Path, PathBuf}; | ||||
| use crate::repo::Repo; | |||||
| use crate::utils::strip_suffix; | use crate::utils::strip_suffix; | ||||
| use crate::vfs::Vfs; | |||||
| const ONDISK_VERSION: u8 = 1; | const ONDISK_VERSION: u8 = 1; | ||||
| pub(super) struct NodeMapDocket { | pub(super) struct NodeMapDocket { | ||||
| pub data_length: usize, | pub data_length: usize, | ||||
| // TODO: keep here more of the data from `parse()` when we need it | // TODO: keep here more of the data from `parse()` when we need it | ||||
| } | } | ||||
| /// | /// | ||||
| /// * This revlog does not have a `.n` docket file (it is not generated for | /// * This revlog does not have a `.n` docket file (it is not generated for | ||||
| /// small revlogs), or | /// small revlogs), or | ||||
| /// * The docket has an unsupported version number (repositories created by | /// * The docket has an unsupported version number (repositories created by | ||||
| /// later hg, maybe that should be a requirement instead?), or | /// later hg, maybe that should be a requirement instead?), or | ||||
| /// * The docket file points to a missing (likely deleted) data file (this | /// * The docket file points to a missing (likely deleted) data file (this | ||||
| /// can happen in a rare race condition). | /// can happen in a rare race condition). | ||||
| pub fn read_from_file( | pub fn read_from_file( | ||||
| repo: &Repo, | store_vfs: &Vfs, | ||||
| index_path: &Path, | index_path: &Path, | ||||
| ) -> Result<Option<(Self, Mmap)>, HgError> { | ) -> Result<Option<(Self, Mmap)>, HgError> { | ||||
| let docket_path = index_path.with_extension("n"); | let docket_path = index_path.with_extension("n"); | ||||
| let docket_bytes = if let Some(bytes) = | let docket_bytes = if let Some(bytes) = | ||||
| repo.store_vfs().read(&docket_path).io_not_found_as_none()? | store_vfs.read(&docket_path).io_not_found_as_none()? | ||||
| { | { | ||||
| bytes | bytes | ||||
| } else { | } else { | ||||
| return Ok(None); | return Ok(None); | ||||
| }; | }; | ||||
| let input = if let Some((&ONDISK_VERSION, rest)) = | let input = if let Some((&ONDISK_VERSION, rest)) = | ||||
| docket_bytes.split_first() | docket_bytes.split_first() | ||||
| let (_tip_node, _rest) = | let (_tip_node, _rest) = | ||||
| parse(u8::slice_from_bytes(rest, tip_node_size))?; | parse(u8::slice_from_bytes(rest, tip_node_size))?; | ||||
| let uid = parse(std::str::from_utf8(uid))?; | let uid = parse(std::str::from_utf8(uid))?; | ||||
| let docket = NodeMapDocket { data_length }; | let docket = NodeMapDocket { data_length }; | ||||
| let data_path = rawdata_path(&docket_path, uid); | let data_path = rawdata_path(&docket_path, uid); | ||||
| // TODO: use `vfs.read()` here when the `persistent-nodemap.mmap` | // TODO: use `vfs.read()` here when the `persistent-nodemap.mmap` | ||||
| // config is false? | // config is false? | ||||
| if let Some(mmap) = repo | if let Some(mmap) = | ||||
| .store_vfs() | store_vfs.mmap_open(&data_path).io_not_found_as_none()? | ||||
| .mmap_open(&data_path) | |||||
| .io_not_found_as_none()? | |||||
| { | { | ||||
| if mmap.len() >= data_length { | if mmap.len() >= data_length { | ||||
| Ok(Some((docket, mmap))) | Ok(Some((docket, mmap))) | ||||
| } else { | } else { | ||||
| Err(HgError::corrupted("persistent nodemap too short")) | Err(HgError::corrupted("persistent nodemap too short")) | ||||
| } | } | ||||
| } else { | } else { | ||||
| // Even if .hg/requires opted in, some revlogs are deemed small | // Even if .hg/requires opted in, some revlogs are deemed small | ||||
| None | None | ||||
| } else if !repo | } else if !repo | ||||
| .requirements() | .requirements() | ||||
| .contains(requirements::NODEMAP_REQUIREMENT) | .contains(requirements::NODEMAP_REQUIREMENT) | ||||
| { | { | ||||
| // If .hg/requires does not opt it, don’t try to open a nodemap | // If .hg/requires does not opt it, don’t try to open a nodemap | ||||
| None | None | ||||
| } else { | } else { | ||||
| NodeMapDocket::read_from_file(repo, index_path)?.map( | NodeMapDocket::read_from_file(&repo.store_vfs(), index_path)?.map( | ||||
| |(docket, data)| { | |(docket, data)| { | ||||
| nodemap::NodeTree::load_bytes( | nodemap::NodeTree::load_bytes( | ||||
| Box::new(data), | Box::new(data), | ||||
| docket.data_length, | docket.data_length, | ||||
| ) | ) | ||||
| }, | }, | ||||
| ) | ) | ||||
| }; | }; | ||||