mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 18:27:38 +00:00
repo: get change id index from revset instead of building it in repo
This replaces the direct use of `IdIndex` in `ReadonlyRepo` by use of `Revset::change_id_index()`. I made the `Index` trait require `Send` and `Sync` in order to be able to store an instance of it in `ReadonlyRepo` (via `ChangeIdIndex`) and still have that be `Send` and `Sync`. We could alternatively store the `ChangeIdIndex` in a `Mutex`. Now that will be up to the `ChangeIdIndex` instead.
This commit is contained in:
parent
27a7fccefa
commit
68cff2fa22
4 changed files with 30 additions and 24 deletions
|
@ -799,7 +799,7 @@ impl MutableIndex for MutableIndexImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait IndexSegment {
|
trait IndexSegment: Send + Sync {
|
||||||
fn segment_num_parent_commits(&self) -> u32;
|
fn segment_num_parent_commits(&self) -> u32;
|
||||||
|
|
||||||
fn segment_num_commits(&self) -> u32;
|
fn segment_num_commits(&self) -> u32;
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub trait IndexStore: Send + Sync + Debug {
|
||||||
) -> Result<Box<dyn ReadonlyIndex>, IndexWriteError>;
|
) -> Result<Box<dyn ReadonlyIndex>, IndexWriteError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Index {
|
pub trait Index: Send + Sync {
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
|
||||||
fn commit_id_to_pos(&self, commit_id: &CommitId) -> Option<IndexPosition>;
|
fn commit_id_to_pos(&self, commit_id: &CommitId) -> Option<IndexPosition>;
|
||||||
|
|
|
@ -15,7 +15,9 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::pin::Pin;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
|
||||||
|
@ -28,7 +30,7 @@ use crate::backend::{Backend, BackendError, BackendResult, ChangeId, CommitId, O
|
||||||
use crate::commit::Commit;
|
use crate::commit::Commit;
|
||||||
use crate::commit_builder::CommitBuilder;
|
use crate::commit_builder::CommitBuilder;
|
||||||
use crate::dag_walk::topo_order_reverse;
|
use crate::dag_walk::topo_order_reverse;
|
||||||
use crate::default_index_store::{DefaultIndexStore, IndexPosition};
|
use crate::default_index_store::DefaultIndexStore;
|
||||||
use crate::git_backend::GitBackend;
|
use crate::git_backend::GitBackend;
|
||||||
use crate::index::{HexPrefix, Index, IndexStore, MutableIndex, PrefixResolution, ReadonlyIndex};
|
use crate::index::{HexPrefix, Index, IndexStore, MutableIndex, PrefixResolution, ReadonlyIndex};
|
||||||
use crate::local_backend::LocalBackend;
|
use crate::local_backend::LocalBackend;
|
||||||
|
@ -36,6 +38,7 @@ use crate::op_heads_store::{self, OpHeadResolutionError, OpHeadsStore};
|
||||||
use crate::op_store::{BranchTarget, OpStore, OperationId, RefTarget, WorkspaceId};
|
use crate::op_store::{BranchTarget, OpStore, OperationId, RefTarget, WorkspaceId};
|
||||||
use crate::operation::Operation;
|
use crate::operation::Operation;
|
||||||
use crate::refs::merge_ref_targets;
|
use crate::refs::merge_ref_targets;
|
||||||
|
use crate::revset::{ChangeIdIndex, Revset, RevsetExpression};
|
||||||
use crate::rewrite::DescendantRebaser;
|
use crate::rewrite::DescendantRebaser;
|
||||||
use crate::settings::{RepoSettings, UserSettings};
|
use crate::settings::{RepoSettings, UserSettings};
|
||||||
use crate::simple_op_heads_store::SimpleOpHeadsStore;
|
use crate::simple_op_heads_store::SimpleOpHeadsStore;
|
||||||
|
@ -77,9 +80,10 @@ pub struct ReadonlyRepo {
|
||||||
operation: Operation,
|
operation: Operation,
|
||||||
settings: RepoSettings,
|
settings: RepoSettings,
|
||||||
index_store: Arc<dyn IndexStore>,
|
index_store: Arc<dyn IndexStore>,
|
||||||
index: OnceCell<Box<dyn ReadonlyIndex>>,
|
index: OnceCell<Pin<Box<dyn ReadonlyIndex>>>,
|
||||||
|
// Declared after `change_id_index` since it must outlive it on drop.
|
||||||
|
change_id_index: OnceCell<Box<dyn ChangeIdIndex>>,
|
||||||
// TODO: This should eventually become part of the index and not be stored fully in memory.
|
// TODO: This should eventually become part of the index and not be stored fully in memory.
|
||||||
change_id_index: OnceCell<ChangeIdIndex>,
|
|
||||||
view: View,
|
view: View,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,21 +213,27 @@ impl ReadonlyRepo {
|
||||||
pub fn readonly_index(&self) -> &dyn ReadonlyIndex {
|
pub fn readonly_index(&self) -> &dyn ReadonlyIndex {
|
||||||
self.index
|
self.index
|
||||||
.get_or_init(|| {
|
.get_or_init(|| {
|
||||||
self.index_store
|
Box::into_pin(
|
||||||
.get_index_at_op(&self.operation, &self.store)
|
self.index_store
|
||||||
|
.get_index_at_op(&self.operation, &self.store),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.as_ref()
|
.deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_id_index(&self) -> &ChangeIdIndex {
|
fn change_id_index<'a>(&'a self) -> &'a (dyn ChangeIdIndex + 'a) {
|
||||||
self.change_id_index.get_or_init(|| {
|
let change_id_index: &'a (dyn ChangeIdIndex + 'a) = self
|
||||||
let heads = self.view().heads().iter().cloned().collect_vec();
|
.change_id_index
|
||||||
let walk = self.readonly_index().as_index().walk_revs(&heads, &[]);
|
.get_or_init(|| {
|
||||||
IdIndex::from_vec(
|
let revset: Box<dyn Revset<'a>> = RevsetExpression::all().evaluate(self).unwrap();
|
||||||
walk.map(|entry| (entry.change_id(), entry.position()))
|
let change_id_index: Box<dyn ChangeIdIndex + 'a> = revset.change_id_index();
|
||||||
.collect(),
|
// evaluate() above only borrows the index, not the whole repo
|
||||||
)
|
let change_id_index: Box<dyn ChangeIdIndex> =
|
||||||
})
|
unsafe { std::mem::transmute(change_id_index) };
|
||||||
|
change_id_index
|
||||||
|
})
|
||||||
|
.as_ref();
|
||||||
|
change_id_index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_heads_store(&self) -> &Arc<dyn OpHeadsStore> {
|
pub fn op_heads_store(&self) -> &Arc<dyn OpHeadsStore> {
|
||||||
|
@ -277,9 +287,7 @@ impl Repo for ReadonlyRepo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<Vec<CommitId>> {
|
fn resolve_change_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<Vec<CommitId>> {
|
||||||
let index = self.index();
|
self.change_id_index().resolve_prefix(prefix)
|
||||||
self.change_id_index()
|
|
||||||
.resolve_prefix_with(prefix, |&pos| index.entry_by_pos(pos).commit_id())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shortest_unique_change_id_prefix_len(&self, target_id: &ChangeId) -> usize {
|
fn shortest_unique_change_id_prefix_len(&self, target_id: &ChangeId) -> usize {
|
||||||
|
@ -578,7 +586,7 @@ impl RepoLoader {
|
||||||
operation,
|
operation,
|
||||||
settings: self.repo_settings.clone(),
|
settings: self.repo_settings.clone(),
|
||||||
index_store: self.index_store.clone(),
|
index_store: self.index_store.clone(),
|
||||||
index: OnceCell::with_value(index),
|
index: OnceCell::with_value(Box::into_pin(index)),
|
||||||
change_id_index: OnceCell::new(),
|
change_id_index: OnceCell::new(),
|
||||||
view,
|
view,
|
||||||
};
|
};
|
||||||
|
@ -1272,8 +1280,6 @@ mod dirty_cell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChangeIdIndex = IdIndex<ChangeId, IndexPosition>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct IdIndex<K, V>(Vec<(K, V)>);
|
pub struct IdIndex<K, V>(Vec<(K, V)>);
|
||||||
|
|
||||||
|
|
|
@ -1582,7 +1582,7 @@ pub trait Revset<'index> {
|
||||||
fn is_empty(&self) -> bool;
|
fn is_empty(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ChangeIdIndex {
|
pub trait ChangeIdIndex: Send + Sync {
|
||||||
/// Resolve an unambiguous change ID prefix to the commit IDs in the revset.
|
/// Resolve an unambiguous change ID prefix to the commit IDs in the revset.
|
||||||
fn resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<Vec<CommitId>>;
|
fn resolve_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<Vec<CommitId>>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue