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 @@
1use std::rc::Rc;
1use std::{2use std::{
2 cell::RefCell,3 cell::RefCell,
3 ops::{Deref, DerefMut},4 ops::{Deref, DerefMut},
@@ -16,6 +17,27 @@ pub type ObjectCache = dyn git_pack::cache::Object + Send + 'static; · 12 unmodified lines
16/// A constructor for boxed object caches.17/// A constructor for boxed object caches.
17pub type NewObjectCacheFn = dyn Fn() -> Box<ObjectCache> + Send + Sync + 'static;18pub type NewObjectCacheFn = dyn Fn() -> Box<ObjectCache> + Send + Sync + 'static;
18 19
20impl 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}
34impl 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
19impl<S> Cache<S> {41impl<S> Cache<S> {
20 /// Dissolve this instance, discard all caches, and return the inner implementation.42 /// Dissolve this instance, discard all caches, and return the inner implementation.
21 pub fn into_inner(self) -> S {43 pub fn into_inner(self) -> S {
git-odb/src/store_impls/dynamic/handle.rs+35−0
@@ -1,3 +1,5 @@
1use std::convert::{TryFrom, TryInto};
2use std::rc::Rc;
1use std::{3use std::{
2 cell::RefCell,4 cell::RefCell,
3 ops::Deref,5 ops::Deref,
@@ -324,6 +326,39 @@ where · 320 unmodified lines
324 }326 }
325}327}
326 328
329impl 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
344impl 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
355impl 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
327impl<S> Clone for super::Handle<S>362impl<S> Clone for super::Handle<S>
328where363where
329 S: Deref<Target = super::Store> + Clone,364 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
270fn keep_going_collects_results() {270fn keep_going_collects_results() {
271 let mut opts = opts_from_probe();271 let mut opts = opts_from_probe();
272 opts.keep_going = true;272 opts.keep_going = true;
273 let mut count = AtomicUsize::default();273 let count = AtomicUsize::default();
274 let (_source_tree, destination, _index, outcome) = checkout_index_in_tmp_dir_opts(274 let (_source_tree, destination, _index, outcome) = checkout_index_in_tmp_dir_opts(
275 opts,275 opts,
276 "make_mixed_without_submodules",276 "make_mixed_without_submodules",
@@ -454,10 +454,7 @@ fn checkout_index_in_tmp_dir_opts( · 177 unmodified lines
454 let source_tree = fixture_path(name);454 let source_tree = fixture_path(name);
455 let git_dir = source_tree.join(".git");455 let git_dir = source_tree.join(".git");
456 let mut index = git_index::File::at(git_dir.join("index"), Default::default())?;456 let mut index = git_index::File::at(git_dir.join("index"), Default::default())?;
457 let odb = git_odb::at(git_dir.join("objects"))?457 let odb = git_odb::at(git_dir.join("objects"))?.into_inner().into_arc()?;
458 .into_inner()
459 .into_arc()
460 .to_cache_arc();
461 let destination = tempfile::tempdir_in(std::env::current_dir()?)?;458 let destination = tempfile::tempdir_in(std::env::current_dir()?)?;
462 prep_dest(destination.path())?;459 prep_dest(destination.path())?;
463 460
gitoxide-core/src/index/checkout.rs+21−13
@@ -68,24 +68,29 @@ pub fn checkout_exclusive( · 67 unmodified lines
68 bytes.init(None, git::progress::bytes());68 bytes.init(None, git::progress::bytes());
69 69
70 let start = std::time::Instant::now();70 let start = std::time::Instant::now();
71 let no_repo = repo.is_none();
71 let checkout::Outcome {72 let checkout::Outcome {
72 errors,73 errors,
73 collisions,74 collisions,
74 files_updated,75 files_updated,
75 } = match &repo {76 bytes_written,
77 } = match repo {
76 Some(repo) => git::worktree::index::checkout(78 Some(repo) => git::worktree::index::checkout(
77 &mut index,79 &mut index,
78 dest_directory,80 dest_directory,
79 |oid, buf| {81 {
80 repo.objects.find_blob(oid, buf).ok();82 let objects = repo.objects.into_arc()?;
81 if empty_files {83 move |oid, buf| {
82 // We always want to query the ODB here…84 objects.find_blob(oid, buf).ok();
83 repo.objects.find_blob(oid, buf)?;85 if empty_files {
84 buf.clear();86 // We always want to query the ODB here…
85 // …but write nothing87 objects.find_blob(oid, buf)?;
86 Ok(git::objs::BlobRef { data: buf })88 buf.clear();
87 } else {89 // …but write nothing
88 repo.objects.find_blob(oid, buf)90 Ok(git::objs::BlobRef { data: buf })
91 } else {
92 objects.find_blob(oid, buf)
93 }
89 }94 }
90 },95 },
91 &mut files,96 &mut files,
@@ -111,9 +116,9 @@ pub fn checkout_exclusive( · 19 unmodified lines
111 bytes.show_throughput(start);116 bytes.show_throughput(start);
112 117
113 progress.done(format!(118 progress.done(format!(
114 "Created {} {} files{}",119 "Created {} {} files{} ({})",
115 files_updated,120 files_updated,
116 repo.is_none().then(|| "empty").unwrap_or_default(),121 no_repo.then(|| "empty").unwrap_or_default(),
117 should_interrupt122 should_interrupt
118 .load(Ordering::Relaxed)123 .load(Ordering::Relaxed)
119 .then(|| {124 .then(|| {
@@ -123,6 +128,9 @@ pub fn checkout_exclusive( · 3 unmodified lines
123 )128 )
124 })129 })
125 .unwrap_or_default(),130 .unwrap_or_default(),
131 git_features::progress::bytes()
132 .unwrap()
133 .display(bytes_written as usize, None, None)
126 ));134 ));
127 135
128 if !(collisions.is_empty() && errors.is_empty()) {136 if !(collisions.is_empty() && errors.is_empty()) {