# HG changeset patch # User Raphaël Gomès # Date 2023-08-10 09:01:07 # Node ID 27e773aa607dd698cf9155ef2b196bd156a31523 # Parent 1928b770e3e7b3ed96f558f3fa3b9a8526c0d062 rust: implement the `Graph` trait for all revlogs This is trivial and makes all the algorithms relying on the trait usable for more use cases. diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs --- a/rust/hg-core/src/revlog/changelog.rs +++ b/rust/hg-core/src/revlog/changelog.rs @@ -4,7 +4,7 @@ use crate::revlog::{Node, NodePrefix}; use crate::revlog::{Revlog, RevlogEntry, RevlogError}; use crate::utils::hg_path::HgPath; use crate::vfs::Vfs; -use crate::UncheckedRevision; +use crate::{Graph, GraphError, UncheckedRevision}; use itertools::Itertools; use std::ascii::escape_default; use std::borrow::Cow; @@ -76,6 +76,12 @@ impl Changelog { } } +impl Graph for Changelog { + fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { + self.revlog.parents(rev) + } +} + /// A specialized `RevlogEntry` for `changelog` data format /// /// This is a `RevlogEntry` with the added semantics that the associated diff --git a/rust/hg-core/src/revlog/filelog.rs b/rust/hg-core/src/revlog/filelog.rs --- a/rust/hg-core/src/revlog/filelog.rs +++ b/rust/hg-core/src/revlog/filelog.rs @@ -9,6 +9,8 @@ use crate::revlog::{Revlog, RevlogError} use crate::utils::files::get_path_from_bytes; use crate::utils::hg_path::HgPath; use crate::utils::SliceExt; +use crate::Graph; +use crate::GraphError; use crate::UncheckedRevision; use std::path::PathBuf; @@ -18,6 +20,12 @@ pub struct Filelog { revlog: Revlog, } +impl Graph for Filelog { + fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { + self.revlog.parents(rev) + } +} + impl Filelog { pub fn open_vfs( store_vfs: &crate::vfs::Vfs<'_>, diff --git a/rust/hg-core/src/revlog/index.rs b/rust/hg-core/src/revlog/index.rs --- a/rust/hg-core/src/revlog/index.rs +++ b/rust/hg-core/src/revlog/index.rs @@ -6,7 +6,7 @@ use byteorder::{BigEndian, ByteOrder}; use crate::errors::HgError; use crate::revlog::node::Node; use crate::revlog::{Revision, NULL_REVISION}; -use crate::UncheckedRevision; +use crate::{Graph, GraphError, RevlogIndex, UncheckedRevision}; pub const INDEX_ENTRY_SIZE: usize = 64; @@ -97,6 +97,23 @@ impl Debug for Index { } } +impl Graph for Index { + fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { + let err = || GraphError::ParentOutOfRange(rev); + match self.get_entry(rev) { + Some(entry) => { + // The C implementation checks that the parents are valid + // before returning + Ok([ + self.check_revision(entry.p1()).ok_or_else(err)?, + self.check_revision(entry.p2()).ok_or_else(err)?, + ]) + } + None => Ok([NULL_REVISION, NULL_REVISION]), + } + } +} + impl Index { /// Create an index from bytes. /// Calculate the start of each entry when is_inline is true. diff --git a/rust/hg-core/src/revlog/manifest.rs b/rust/hg-core/src/revlog/manifest.rs --- a/rust/hg-core/src/revlog/manifest.rs +++ b/rust/hg-core/src/revlog/manifest.rs @@ -4,7 +4,7 @@ use crate::revlog::{Revlog, RevlogError} use crate::utils::hg_path::HgPath; use crate::utils::SliceExt; use crate::vfs::Vfs; -use crate::{Revision, UncheckedRevision}; +use crate::{Graph, GraphError, Revision, UncheckedRevision}; /// A specialized `Revlog` to work with `manifest` data format. pub struct Manifestlog { @@ -12,6 +12,12 @@ pub struct Manifestlog { revlog: Revlog, } +impl Graph for Manifestlog { + fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { + self.revlog.parents(rev) + } +} + impl Manifestlog { /// Open the `manifest` of a repository given by its root. pub fn open(store_vfs: &Vfs, use_nodemap: bool) -> Result { diff --git a/rust/hg-core/src/revlog/mod.rs b/rust/hg-core/src/revlog/mod.rs --- a/rust/hg-core/src/revlog/mod.rs +++ b/rust/hg-core/src/revlog/mod.rs @@ -182,6 +182,12 @@ pub struct Revlog { nodemap: Option, } +impl Graph for Revlog { + fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { + self.index.parents(rev) + } +} + impl Revlog { /// Open a revlog index file. ///