Skip to content

Commit 6bfdea5

Browse files
committed
iterates through the Ancestor iterator to create the first nonexistent directory and uses a boxed slice to pre-allocate memory for uncreated directories and iterate through & create them efficiently
1 parent 0c95d41 commit 6bfdea5

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

library/std/src/fs.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,32 +3333,27 @@ impl DirBuilder {
33333333
return Ok(());
33343334
}
33353335

3336-
let mut uncreated_dirs = Vec::new();
3337-
let mut current = path;
3336+
let ancestors = path.ancestors();
3337+
let mut uncreated_dir_ctr = 0;
33383338

3339-
loop {
3340-
match self.inner.mkdir(current) {
3339+
for ancestor in ancestors {
3340+
if ancestor == Path::new("") {
3341+
break;
3342+
}
3343+
3344+
match self.inner.mkdir(ancestor) {
33413345
Ok(()) => break,
3342-
Err(e) if e.kind() == io::ErrorKind::NotFound => {}
3346+
Err(e) if e.kind() == io::ErrorKind::NotFound => uncreated_dir_ctr += 1,
33433347
// we check if the err is AlreadyExists for two reasons
33443348
// - in case the path exists as a *file*
33453349
// - and to avoid calls to .is_dir() in case of other errs
33463350
// (i.e. PermissionDenied)
3347-
Err(e) if e.kind() == io::ErrorKind::AlreadyExists && current.is_dir() => break,
3351+
Err(e) if e.kind() == io::ErrorKind::AlreadyExists && ancestor.is_dir() => break,
33483352
Err(e) => return Err(e),
33493353
}
3350-
3351-
if let Some(parent) = current.parent() {
3352-
if parent == Path::new("") {
3353-
break;
3354-
}
3355-
uncreated_dirs.push(current);
3356-
current = parent;
3357-
} else {
3358-
break;
3359-
}
33603354
}
33613355

3356+
let uncreated_dirs: Box<[_]> = ancestors.take(uncreated_dir_ctr).collect();
33623357
for uncreated_dir in uncreated_dirs.iter().rev() {
33633358
if let Err(e) = self.inner.mkdir(uncreated_dir) {
33643359
if !uncreated_dir.is_dir() {

0 commit comments

Comments
 (0)