dag: int_version -> storage_version

Summary:
Document that the "version" comes from the storage layer, and the storage
"append-only" concept is different from the commit graph "append-only".

Reviewed By: zzl0

Differential Revision: D47482811

fbshipit-source-id: 89cd2df5ee3a786d060d258505c965dcdc9f655a
This commit is contained in:
Jun Wu 2023-07-17 11:51:18 -07:00 committed by Facebook GitHub Bot
parent 3a40763fa1
commit 76cd92ead7
5 changed files with 30 additions and 19 deletions

View File

@ -54,11 +54,11 @@ use crate::ops::DagPersistent;
use crate::ops::DagStrip;
use crate::ops::IdConvert;
use crate::ops::IdMapSnapshot;
use crate::ops::IntVersion;
use crate::ops::Open;
use crate::ops::Parents;
use crate::ops::Persist;
use crate::ops::PrefixLookup;
use crate::ops::StorageVersion;
use crate::ops::ToIdSet;
use crate::ops::TryClone;
use crate::protocol;
@ -170,7 +170,7 @@ where
IdDag<IS>: TryClone + 'static,
M: TryClone + IdMapAssignHead + Persist + Send + Sync + 'static,
P: Open<OpenTarget = Self> + Send + Sync + 'static,
S: TryClone + IntVersion + Persist + Send + Sync + 'static,
S: TryClone + StorageVersion + Persist + Send + Sync + 'static,
{
/// Add vertexes and their ancestors to the on-disk DAG.
///
@ -194,12 +194,12 @@ where
// checked there are no in-memory changes at the beginning.
//
// Also see comments in `NameDagState::lock()`.
let old_version = self.state.int_version();
let old_version = self.state.storage_version();
let lock = self.state.lock()?;
let map_lock = self.map.lock()?;
let dag_lock = self.dag.lock()?;
self.state.reload(&lock)?;
let new_version = self.state.int_version();
let new_version = self.state.storage_version();
if old_version != new_version {
self.invalidate_snapshot();
self.invalidate_missing_vertex_cache();
@ -365,12 +365,12 @@ where
IS: Send + Sync + 'static,
M: Send + Sync + 'static,
P: Send + Sync + 'static,
S: IntVersion + Send + Sync + 'static,
S: StorageVersion + Send + Sync + 'static,
{
/// Attempt to reuse caches from `other` if two `NameDag`s are compatible.
/// Usually called when `self` is newly created.
fn maybe_reuse_caches_from(&mut self, other: &Self) {
if self.state.int_version() != other.state.int_version()
if self.state.storage_version() != other.state.storage_version()
|| self.persisted_id_set.as_spans() != other.persisted_id_set.as_spans()
{
tracing::debug!(target: "dag::cache", "cannot reuse cache");
@ -498,7 +498,7 @@ where
IdDag<IS>: TryClone,
M: TryClone + Persist + IdMapWrite + IdConvert + Send + Sync + 'static,
P: TryClone + Open<OpenTarget = Self> + Send + Sync + 'static,
S: TryClone + IntVersion + Persist + Send + Sync + 'static,
S: TryClone + StorageVersion + Persist + Send + Sync + 'static,
{
async fn strip(&mut self, set: &NameSet) -> Result<()> {
if !self.pending_heads.is_empty() {
@ -687,7 +687,7 @@ where
IdDag<IS>: TryClone,
M: TryClone + IdMapAssignHead + Persist + Send + Sync + 'static,
P: Open<OpenTarget = Self> + TryClone + Send + Sync + 'static,
S: IntVersion + TryClone + Persist + Send + Sync + 'static,
S: StorageVersion + TryClone + Persist + Send + Sync + 'static,
{
async fn import_pull_data(
&mut self,

View File

@ -18,9 +18,9 @@ use crate::errors::bug;
use crate::iddag::IdDag;
use crate::iddagstore::IndexedLogStore;
use crate::idmap::IdMap;
use crate::ops::IntVersion;
use crate::ops::Open;
use crate::ops::Persist;
use crate::ops::StorageVersion;
use crate::ops::TryClone;
use crate::Result;
@ -115,8 +115,8 @@ impl Persist for NameDagState {
}
}
impl IntVersion for NameDagState {
fn int_version(&self) -> (u64, u64) {
impl StorageVersion for NameDagState {
fn storage_version(&self) -> (u64, u64) {
match &self.mlog {
Some(mlog) => mlog.version(),
None => (0, 0),

View File

@ -13,9 +13,9 @@ use super::NameDagBuilder;
use crate::iddag::IdDag;
use crate::iddagstore::InProcessStore;
use crate::idmap::MemIdMap;
use crate::ops::IntVersion;
use crate::ops::Open;
use crate::ops::Persist;
use crate::ops::StorageVersion;
use crate::Result;
/// In-memory version of [`NameDag`].
@ -82,8 +82,8 @@ impl Persist for MemNameDagState {
}
}
impl IntVersion for MemNameDagState {
fn int_version(&self) -> (u64, u64) {
impl StorageVersion for MemNameDagState {
fn storage_version(&self) -> (u64, u64) {
self.version
}
}

View File

@ -608,11 +608,18 @@ pub trait Open: Clone {
fn open(&self) -> Result<Self::OpenTarget>;
}
/// Has an integer tuple version that can be used to test if the data was
/// changed. If the first number changes, it means incompatible changes.
/// If only the second number increases, it means append-only changes.
pub trait IntVersion {
fn int_version(&self) -> (u64, u64);
/// Has a tuple version that can be used to test if the data was changed.
pub trait StorageVersion {
/// Version tracked by the underlying low-level storage (ex. indexedlog).
/// `(epoch, length)`.
/// - If `epoch` is changed, then a non-append-only change has happened,
/// all caches should be invalidated.
/// - If `length` is increased but `epoch` has changed, then the storage
/// layer got an append-only change. Note: the append-only change at
/// the storage layer does *not* mean append-only at the commit graph
/// layer, since the strip operation that removes commits could be
/// implemented by appending special data to the storage layer.
fn storage_version(&self) -> (u64, u64);
}
/// Fallible clone.

View File

@ -63,6 +63,10 @@ impl VerLink {
}
/// Bumps the `VerLink` for backward-compatible (ex. append-only) changes.
/// Note the "append-only" means only adding commits without "stripping"
/// or "rewriting" commits. It is different from the "append-only" concept
/// from the storage layer, because the "stripping" or "rewriting" might
/// be implemented as "appending" special data on the storage layer.
pub fn bump(&mut self) {
match Arc::get_mut(&mut self.inner) {
// This is an optimization to avoid increasing the length of the