##// END OF EJS Templates
filelog: add a comment explaining a fast path in filerevisioncopied()...
filelog: add a comment explaining a fast path in filerevisioncopied() Differential Revision: https://phab.mercurial-scm.org/D11964

File last commit:

r49374:35c47015 default
r49377:5026a0d3 default
Show More
filelog.rs
117 lines | 3.7 KiB | application/rls-services+xml | RustLexer
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 use crate::errors::HgError;
use crate::repo::Repo;
use crate::revlog::path_encode::path_encode;
Simon Sapin
rhg: Expose FilelogEntry that wraps RevlogEntry...
r49374 use crate::revlog::revlog::RevlogEntry;
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 use crate::revlog::revlog::{Revlog, RevlogError};
use crate::revlog::NodePrefix;
use crate::revlog::Revision;
use crate::utils::files::get_path_from_bytes;
use crate::utils::hg_path::HgPath;
use crate::utils::SliceExt;
use std::path::PathBuf;
/// A specialized `Revlog` to work with file data logs.
pub struct Filelog {
/// The generic `revlog` format.
revlog: Revlog,
}
impl Filelog {
Simon Sapin
rust: Return HgError instead of RevlogError in revlog constructors...
r48777 pub fn open(repo: &Repo, file_path: &HgPath) -> Result<Self, HgError> {
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 let index_path = store_path(file_path, b".i");
let data_path = store_path(file_path, b".d");
let revlog = Revlog::open(repo, index_path, Some(&data_path))?;
Ok(Self { revlog })
}
Simon Sapin
rhg: Expose FilelogEntry that wraps RevlogEntry...
r49374 /// The given node ID is that of the file as found in a filelog, not of a
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 /// changeset.
Simon Sapin
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev...
r48783 pub fn data_for_node(
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 &self,
file_node: impl Into<NodePrefix>,
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 ) -> Result<FilelogRevisionData, RevlogError> {
Simon Sapin
rust: Rename the `Revlog::get_node_rev` method to `rev_from_node`...
r48782 let file_rev = self.revlog.rev_from_node(file_node.into())?;
Simon Sapin
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev...
r48783 self.data_for_rev(file_rev)
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 }
Simon Sapin
rhg: Expose FilelogEntry that wraps RevlogEntry...
r49374 /// The given revision is that of the file as found in a filelog, not of a
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 /// changeset.
Simon Sapin
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev...
r48783 pub fn data_for_rev(
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 &self,
file_rev: Revision,
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 ) -> Result<FilelogRevisionData, RevlogError> {
Simon Sapin
rhg: Add RevlogEntry::data that does delta resolution...
r49373 let data: Vec<u8> = self.revlog.get_rev_data(file_rev)?.into_owned();
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 Ok(FilelogRevisionData(data.into()))
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 }
Simon Sapin
rhg: Expose FilelogEntry that wraps RevlogEntry...
r49374
/// The given node ID is that of the file as found in a filelog, not of a
/// changeset.
pub fn entry_for_node(
&self,
file_node: impl Into<NodePrefix>,
) -> Result<FilelogEntry, RevlogError> {
let file_rev = self.revlog.rev_from_node(file_node.into())?;
self.entry_for_rev(file_rev)
}
/// The given revision is that of the file as found in a filelog, not of a
/// changeset.
pub fn entry_for_rev(
&self,
file_rev: Revision,
) -> Result<FilelogEntry, RevlogError> {
Ok(FilelogEntry(self.revlog.get_entry(file_rev)?))
}
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 }
fn store_path(hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
let encoded_bytes =
path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
get_path_from_bytes(&encoded_bytes).into()
}
Simon Sapin
rhg: Expose FilelogEntry that wraps RevlogEntry...
r49374 pub struct FilelogEntry<'a>(RevlogEntry<'a>);
impl FilelogEntry<'_> {
pub fn data(&self) -> Result<FilelogRevisionData, HgError> {
Ok(FilelogRevisionData(self.0.data()?.into_owned()))
}
}
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 /// The data for one revision in a filelog, uncompressed and delta-resolved.
pub struct FilelogRevisionData(Vec<u8>);
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 impl FilelogRevisionData {
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 /// Split into metadata and data
Arseniy Alekseyev
rhg: simplify split_metadata...
r49064 pub fn split(&self) -> Result<(Option<&[u8]>, &[u8]), HgError> {
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 const DELIMITER: &[u8; 2] = &[b'\x01', b'\n'];
if let Some(rest) = self.0.drop_prefix(DELIMITER) {
if let Some((metadata, data)) = rest.split_2_by_slice(DELIMITER) {
Arseniy Alekseyev
rhg: simplify split_metadata...
r49064 Ok((Some(metadata), data))
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 } else {
Err(HgError::corrupted(
"Missing metadata end delimiter in filelog entry",
))
}
} else {
Ok((None, &self.0))
}
}
/// Returns the file contents at this revision, stripped of any metadata
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 pub fn file_data(&self) -> Result<&[u8], HgError> {
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 let (_metadata, data) = self.split()?;
Ok(data)
}
Arseniy Alekseyev
rhg: internally, return a structured representation from hg cat...
r49051
/// Consume the entry, and convert it into data, discarding any metadata,
/// if present.
Simon Sapin
rhg: Rename some revlog-related types and methods...
r49372 pub fn into_file_data(self) -> Result<Vec<u8>, HgError> {
Arseniy Alekseyev
rhg: simplify split_metadata...
r49064 if let (Some(_metadata), data) = self.split()? {
Arseniy Alekseyev
rhg: internally, return a structured representation from hg cat...
r49051 Ok(data.to_owned())
} else {
Ok(self.0)
}
}
Simon Sapin
rust: Add a Filelog struct that wraps Revlog...
r48775 }