History

conversions from Rc to arc for Handle (#301)

Sebastian Thiel committed 4 years ago

Commit c19331e1 parent 5f29c0f4 files · +80 −18Browse files

Unified · Split

4 files
  1. git-odb/src/cache.rs +22 −0
  2. git-odb/src/store_impls/dynamic/handle.rs +35 −0
  3. git-worktree/tests/worktree/index/checkout.rs +2 −5
  4. gitoxide-core/src/index/checkout.rs +21 −13
git-odb/src/cache.rs+22−0
@@ -1,3 +1,4 @@
1+use std::rc::Rc;
12 use std::{
23 cell::RefCell,
34 ops::{Deref, DerefMut},
@@ -16,6 +17,27 @@ pub type ObjectCache = dyn git_pack::cache::Object + Send + 'static; · 12 unmodified lines
1617 /// A constructor for boxed object caches.
1718 pub type NewObjectCacheFn = dyn Fn() -> Box<ObjectCache> + Send + Sync + 'static;
1819
20+impl Cache<crate::store::Handle<Rc<crate::Store>>> {
21+ /// Convert this cache's handle into one that keeps its store in an arc. This creates an entirely new store,
22+ /// so should be done early to avoid unnecessary work (and mappings).
23+ pub fn into_arc(self) -> std::io::Result<Cache<crate::store::Handle<Arc<crate::Store>>>> {
24+ let inner = self.inner.into_arc()?;
25+ Ok(Cache {
26+ inner,
27+ new_pack_cache: self.new_pack_cache,
28+ new_object_cache: self.new_object_cache,
29+ pack_cache: self.pack_cache,
30+ object_cache: self.object_cache,
31+ })
32+ }
33+}
34+impl Cache<crate::store::Handle<Arc<crate::Store>>> {
35+ /// No op, as we are containing an arc handle already.
36+ pub fn into_arc(self) -> std::io::Result<Cache<crate::store::Handle<Arc<crate::Store>>>> {
37+ Ok(self)
38+ }
39+}
40+
1941 impl<S> Cache<S> {
2042 /// Dissolve this instance, discard all caches, and return the inner implementation.
2143 pub fn into_inner(self) -> S {
git-odb/src/store_impls/dynamic/handle.rs+35−0
@@ -1,3 +1,5 @@
1+use std::convert::{TryFrom, TryInto};
2+use std::rc::Rc;
13 use std::{
24 cell::RefCell,
35 ops::Deref,
@@ -324,6 +326,39 @@ where · 320 unmodified lines
324326 }
325327 }
326328
329+impl TryFrom<&super::Store> for super::Store {
330+ type Error = std::io::Error;
331+
332+ fn try_from(s: &super::Store) -> Result<Self, Self::Error> {
333+ super::Store::at_opts(
334+ s.path(),
335+ crate::store::init::Options {
336+ slots: crate::store::init::Slots::Given(s.files.len().try_into().expect("BUG: too many slots")),
337+ object_hash: Default::default(),
338+ use_multi_pack_index: false,
339+ },
340+ )
341+ }
342+}
343+
344+impl super::Handle<Rc<super::Store>> {
345+ /// Convert a ref counted store into one that is ref-counted and thread-safe, by creating a new Store.
346+ pub fn into_arc(self) -> std::io::Result<super::Handle<Arc<super::Store>>> {
347+ let store = Arc::new(super::Store::try_from(self.store_ref())?);
348+ let mut cache = store.to_handle_arc();
349+ cache.refresh = self.refresh;
350+ cache.max_recursion_depth = self.max_recursion_depth;
351+ Ok(cache)
352+ }
353+}
354+
355+impl super::Handle<Arc<super::Store>> {
356+ /// Convert a ref counted store into one that is ref-counted and thread-safe, by creating a new Store
357+ pub fn into_arc(self) -> std::io::Result<super::Handle<Arc<super::Store>>> {
358+ Ok(self)
359+ }
360+}
361+
327362 impl<S> Clone for super::Handle<S>
328363 where
329364 S: Deref<Target = super::Store> + Clone,
git-worktree/tests/worktree/index/checkout.rs+2−5
@@ -270,7 +270,7 @@ fn allow_or_disallow_symlinks() -> crate::Result { · 269 unmodified lines
270270 fn keep_going_collects_results() {
271271 let mut opts = opts_from_probe();
272272 opts.keep_going = true;
273− let mut count = AtomicUsize::default();
273+ let count = AtomicUsize::default();
274274 let (_source_tree, destination, _index, outcome) = checkout_index_in_tmp_dir_opts(
275275 opts,
276276 "make_mixed_without_submodules",
@@ -454,10 +454,7 @@ fn checkout_index_in_tmp_dir_opts( · 177 unmodified lines
454454 let source_tree = fixture_path(name);
455455 let git_dir = source_tree.join(".git");
456456 let mut index = git_index::File::at(git_dir.join("index"), Default::default())?;
457− let odb = git_odb::at(git_dir.join("objects"))?
458− .into_inner()
459− .into_arc()
460− .to_cache_arc();
457+ let odb = git_odb::at(git_dir.join("objects"))?.into_inner().into_arc()?;
461458 let destination = tempfile::tempdir_in(std::env::current_dir()?)?;
462459 prep_dest(destination.path())?;
463460
gitoxide-core/src/index/checkout.rs+21−13
@@ -68,24 +68,29 @@ pub fn checkout_exclusive( · 67 unmodified lines
6868 bytes.init(None, git::progress::bytes());
6969
7070 let start = std::time::Instant::now();
71+ let no_repo = repo.is_none();
7172 let checkout::Outcome {
7273 errors,
7374 collisions,
7475 files_updated,
75− } = match &repo {
76+ bytes_written,
77+ } = match repo {
7678 Some(repo) => git::worktree::index::checkout(
7779 &mut index,
7880 dest_directory,
79− |oid, buf| {
80− repo.objects.find_blob(oid, buf).ok();
81− if empty_files {
82− // We always want to query the ODB here…
83− repo.objects.find_blob(oid, buf)?;
84− buf.clear();
85− // …but write nothing
86− Ok(git::objs::BlobRef { data: buf })
87− } else {
88− repo.objects.find_blob(oid, buf)
81+ {
82+ let objects = repo.objects.into_arc()?;
83+ move |oid, buf| {
84+ objects.find_blob(oid, buf).ok();
85+ if empty_files {
86+ // We always want to query the ODB here…
87+ objects.find_blob(oid, buf)?;
88+ buf.clear();
89+ // …but write nothing
90+ Ok(git::objs::BlobRef { data: buf })
91+ } else {
92+ objects.find_blob(oid, buf)
93+ }
8994 }
9095 },
9196 &mut files,
@@ -111,9 +116,9 @@ pub fn checkout_exclusive( · 19 unmodified lines
111116 bytes.show_throughput(start);
112117
113118 progress.done(format!(
114− "Created {} {} files{}",
119+ "Created {} {} files{} ({})",
115120 files_updated,
116− repo.is_none().then(|| "empty").unwrap_or_default(),
121+ no_repo.then(|| "empty").unwrap_or_default(),
117122 should_interrupt
118123 .load(Ordering::Relaxed)
119124 .then(|| {
@@ -123,6 +128,9 @@ pub fn checkout_exclusive( · 3 unmodified lines
123128 )
124129 })
125130 .unwrap_or_default(),
131+ git_features::progress::bytes()
132+ .unwrap()
133+ .display(bytes_written as usize, None, None)
126134 ));
127135
128136 if !(collisions.is_empty() && errors.is_empty()) {