mononoke: add reverse mapping from bonsai to hg in walker state

Summary: Add an accessor so that we keep a reverse mapping of the WalkState::bcs_to_hg member as a cache of bonsai to hg mappings and also populate it on derivations.

Differential Revision: D27800533

fbshipit-source-id: f9b1c279a78ce3791013c3c83a32251fdc3ad77f
This commit is contained in:
Alex Hornby 2021-04-20 02:59:50 -07:00 committed by Facebook GitHub Bot
parent f137dbee04
commit 00f0ac3bbc
4 changed files with 55 additions and 2 deletions

View File

@ -93,6 +93,12 @@ impl<T: Send + Sync> VisitOne for SamplingWalkVisitor<T> {
) -> Result<bool, Error> {
self.inner.is_public(ctx, phases_store, bcs_id).await
}
fn get_hg_from_bonsai(&self, bcs_id: &ChangesetId) -> Option<HgChangesetId> {
self.inner.get_hg_from_bonsai(bcs_id)
}
fn record_hg_from_bonsai(&self, bcs_id: &ChangesetId, hg_cs_id: HgChangesetId) {
self.inner.record_hg_from_bonsai(bcs_id, hg_cs_id)
}
async fn get_bonsai_from_hg(
&self,
ctx: &CoreContext,

View File

@ -180,6 +180,7 @@ pub struct WalkState {
// State
chunk_bcs: StateMap<InternedId<ChangesetId>>,
deferred_bcs: ValueMap<InternedId<ChangesetId>, HashSet<OutgoingEdge>>,
bcs_to_hg: ValueMap<InternedId<ChangesetId>, HgChangesetId>,
hg_to_bcs: ValueMap<InternedId<HgChangesetId>, ChangesetId>,
visited_bcs: StateMap<InternedId<ChangesetId>>,
visited_bcs_mapping: StateMap<InternedId<ChangesetId>>,
@ -237,6 +238,7 @@ impl WalkState {
// State
chunk_bcs: StateMap::with_hasher(fac.clone()),
deferred_bcs: ValueMap::with_hasher(fac.clone()),
bcs_to_hg: ValueMap::with_hasher(fac.clone()),
hg_to_bcs: ValueMap::with_hasher(fac.clone()),
visited_bcs: StateMap::with_hasher(fac.clone()),
visited_bcs_mapping: StateMap::with_hasher(fac.clone()),
@ -402,6 +404,7 @@ impl WalkState {
InternedType::HgChangesetId => {
self.hg_cs_ids.clear();
self.hg_to_bcs.clear();
self.bcs_to_hg.clear();
self.clear_mapping(NodeType::HgChangeset);
self.clear_mapping(NodeType::HgBonsaiMapping);
self.clear_mapping(NodeType::HgChangesetViaBonsai);
@ -671,6 +674,16 @@ impl VisitOne for WalkState {
}
}
fn get_hg_from_bonsai(&self, bcs_id: &ChangesetId) -> Option<HgChangesetId> {
let bcs_int = self.bcs_ids.interned(bcs_id);
self.bcs_to_hg.get(&bcs_int).map(|v| *v.value())
}
fn record_hg_from_bonsai(&self, bcs_id: &ChangesetId, hg_cs_id: HgChangesetId) {
let bcs_int = self.bcs_ids.interned(bcs_id);
self.bcs_to_hg.insert(bcs_int, hg_cs_id);
}
async fn get_bonsai_from_hg(
&self,
ctx: &CoreContext,
@ -686,7 +699,9 @@ impl VisitOne for WalkState {
.get_bonsai_from_hg(ctx, repo_id, hg_cs_id.clone())
.await?;
if let Some(bcs_id) = bcs_id {
let bcs_int = self.bcs_ids.interned(&bcs_id);
self.hg_to_bcs.insert(hg_int, bcs_id);
self.bcs_to_hg.insert(bcs_int, *hg_cs_id);
bcs_id
} else {
bail!("Can't have hg without bonsai for {}", hg_cs_id);

View File

@ -223,6 +223,14 @@ impl VisitOne for ValidatingVisitor {
self.inner.is_public(ctx, phases_store, bcs_id).await
}
fn get_hg_from_bonsai(&self, bcs_id: &ChangesetId) -> Option<HgChangesetId> {
self.inner.get_hg_from_bonsai(bcs_id)
}
fn record_hg_from_bonsai(&self, bcs_id: &ChangesetId, hg_cs_id: HgChangesetId) {
self.inner.record_hg_from_bonsai(bcs_id, hg_cs_id)
}
async fn get_bonsai_from_hg(
&self,
ctx: &CoreContext,

View File

@ -127,6 +127,12 @@ pub trait VisitOne {
bcs_id: &ChangesetId,
) -> Result<bool, Error>;
/// This only checks if its in the state, it doesn't load it from storage as unlike get_bonsai_from_hg it might require derivation
fn get_hg_from_bonsai(&self, bcs_id: &ChangesetId) -> Option<HgChangesetId>;
/// Record the derived HgChangesetId in the visitor state if we know it
fn record_hg_from_bonsai(&self, bcs_id: &ChangesetId, hg_cs_id: HgChangesetId);
/// Gets the (possibly preloaded) hg to bonsai mapping
async fn get_bonsai_from_hg(
&self,
@ -698,14 +704,24 @@ async fn bonsai_to_hg_mapping_step<'a, V: 'a + VisitOne>(
}
let maybe_hg_cs_id = if filenode_known_derived || !checker.with_filenodes {
maybe_derived::<MappedHgChangesetId>(ctx, repo, bcs_id, enable_derive).await?
let from_state = checker.get_hg_from_bonsai(&bcs_id);
if from_state.is_some() {
from_state
} else {
let derived = maybe_derived::<MappedHgChangesetId>(ctx, repo, bcs_id, enable_derive)
.await?
.map(|v| v.0);
if let Some(derived) = derived {
checker.record_hg_from_bonsai(&bcs_id, derived);
}
derived
}
} else {
None
};
Ok(match maybe_hg_cs_id {
Some(hg_cs_id) => {
let hg_cs_id = hg_cs_id.0;
let mut edges = vec![];
// This seems like a nonsense edge, but its a way to establish HgChangesetId on the way to Bonsai Changeset
// which is useful in LFS validation. The edge is disabled by default.
@ -1530,6 +1546,14 @@ impl<V: VisitOne> Checker<V> {
self.visitor.in_chunk(bcs_id)
}
fn get_hg_from_bonsai(&self, bcs_id: &ChangesetId) -> Option<HgChangesetId> {
self.visitor.get_hg_from_bonsai(bcs_id)
}
fn record_hg_from_bonsai(&self, bcs_id: &ChangesetId, hg_cs_id: HgChangesetId) {
self.visitor.record_hg_from_bonsai(bcs_id, hg_cs_id)
}
async fn get_bonsai_from_hg(
&self,
ctx: &CoreContext,