History

provide a platform for multiple queries at a dir cache level (#301)

This allows to perform work only once while allowing subsequent queries to the cached information, like `is_excluded()` or `attributes()`.

Sebastian Thiel committed 4 years ago

Commit 48be3821 parent dc12f883 files · +29 −20Browse files

Unified · Split

3 files
  1. git-worktree/src/fs/cache.rs +21 −4
  2. git-worktree/src/index/entry.rs +1 −1
  3. git-worktree/tests/worktree/fs/cache.rs +7 −15
git-worktree/src/fs/cache.rs+21−4
@@ -11,6 +11,23 @@ pub enum Mode { · 10 unmodified lines
1111 ProvideAttributesAndIgnore,
1212 }
1313
14+pub struct Platform<'a> {
15+ parent: &'a Cache,
16+}
17+
18+impl<'a> Platform<'a> {
19+ /// The full path to `relative` will be returned for use on the file system.
20+ pub fn leading_dir(&self) -> &'a Path {
21+ self.parent.stack.current()
22+ }
23+}
24+
25+impl<'a> std::fmt::Debug for Platform<'a> {
26+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27+ std::fmt::Debug::fmt(&self.leading_dir(), f)
28+ }
29+}
30+
1431 impl Cache {
1532 /// Create a new instance with `root` being the base for all future paths we handle, assuming it to be valid which includes
1633 /// symbolic links to be included in it as well.
@@ -28,12 +45,12 @@ impl Cache { · 11 unmodified lines
2845 /// Append the `relative` path to the root directory the cache contains and efficiently create leading directories
2946 /// unless `mode` indicates `relative` points to a directory itself in which case the entire resulting path is created as directory.
3047 ///
31− /// The full path to `relative` will be returned for use on the file system.
32− pub fn append_relative_path_assure_leading_dir(
48+ /// Provide access to cached information for that `relative` entry via the platform returned.
49+ pub fn at_entry(
3350 &mut self,
3451 relative: impl AsRef<Path>,
3552 mode: git_index::entry::Mode,
36− ) -> std::io::Result<&Path> {
53+ ) -> std::io::Result<Platform<'_>> {
3754 #[cfg(debug_assertions)]
3855 let mkdir_calls = &mut self.test_mkdir_calls;
3956 let unlink_on_collision = self.unlink_on_collision;
@@ -51,7 +68,7 @@ impl Cache { · 11 unmodified lines
5168 },
5269 |_| {},
5370 )?;
54− Ok(self.stack.current())
71+ Ok(Platform { parent: self })
5572 }
5673 }
5774
git-worktree/src/index/entry.rs+1−1
@@ -37,7 +37,7 @@ where · 36 unmodified lines
3737 git_features::path::from_byte_slice(entry_path).map_err(|_| index::checkout::Error::IllformedUtf8 {
3838 path: entry_path.to_owned(),
3939 })?;
40− let dest = path_cache.append_relative_path_assure_leading_dir(dest_relative, entry.mode)?;
40+ let dest = path_cache.at_entry(dest_relative, entry.mode)?.leading_dir();
4141
4242 let object_size = match entry.mode {
4343 git_index::entry::Mode::FILE | git_index::entry::Mode::FILE_EXECUTABLE => {
git-worktree/tests/worktree/fs/cache.rs+7−15
@@ -15,9 +15,7 @@ mod create_directory { · 14 unmodified lines
1515 );
1616 assert_eq!(cache.test_mkdir_calls, 0);
1717
18− let path = cache
19− .append_relative_path_assure_leading_dir("hello", Mode::FILE)
20− .unwrap();
18+ let path = cache.at_entry("hello", Mode::FILE).unwrap().leading_dir();
2119 assert!(!path.parent().unwrap().exists(), "prefix itself is never created");
2220 assert_eq!(cache.test_mkdir_calls, 0);
2321 }
@@ -34,8 +32,9 @@ mod create_directory { · 10 unmodified lines
3432 ("link", Mode::SYMLINK),
3533 ] {
3634 let path = cache
37− .append_relative_path_assure_leading_dir(Path::new("dir").join(name), *mode)
38− .unwrap();
35+ .at_entry(Path::new("dir").join(name), *mode)
36+ .unwrap()
37+ .leading_dir();
3938 assert!(path.parent().unwrap().is_dir(), "dir exists");
4039 }
4140
@@ -47,9 +46,7 @@ mod create_directory { · 5 unmodified lines
4746 let (mut cache, tmp) = new_cache();
4847 std::fs::create_dir(tmp.path().join("dir")).unwrap();
4948
50− let path = cache
51− .append_relative_path_assure_leading_dir("dir/file", Mode::FILE)
52− .unwrap();
49+ let path = cache.at_entry("dir/file", Mode::FILE).unwrap().leading_dir();
5350 assert!(path.parent().unwrap().is_dir(), "directory is still present");
5451 assert!(!path.exists(), "it won't create the file");
5552 assert_eq!(cache.test_mkdir_calls, 1);
@@ -67,10 +64,7 @@ mod create_directory { · 11 unmodified lines
6764 cache.unlink_on_collision = false;
6865 let relative_path = format!("{}/file", dirname);
6966 assert_eq!(
70− cache
71− .append_relative_path_assure_leading_dir(&relative_path, Mode::FILE)
72− .unwrap_err()
73− .kind(),
67+ cache.at_entry(&relative_path, Mode::FILE).unwrap_err().kind(),
7468 std::io::ErrorKind::AlreadyExists
7569 );
7670 }
@@ -82,9 +76,7 @@ mod create_directory { · 5 unmodified lines
8276 for dirname in &["link-to-dir", "file-in-dir"] {
8377 cache.unlink_on_collision = true;
8478 let relative_path = format!("{}/file", dirname);
85− let path = cache
86− .append_relative_path_assure_leading_dir(&relative_path, Mode::FILE)
87− .unwrap();
79+ let path = cache.at_entry(&relative_path, Mode::FILE).unwrap().leading_dir();
8880 assert!(path.parent().unwrap().is_dir(), "directory was forcefully created");
8981 assert!(!path.exists());
9082 }