Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nydus-image: optimize the way to generate tarfs #1240

Merged
merged 2 commits into from
Apr 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions rafs/src/builder/core/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ impl Bootstrap {
if parent.is_dir() {
// Sort children list by name, so that we can improve performance in fs read_dir using
// binary search.
tree.children
.sort_by_key(|child| child.node.name().to_os_string());
tree.children.sort_by_key(|child| child.name.clone());
parent.inode.set_child_count(tree.children.len() as u32);
if ctx.fs_version.is_v5() {
parent.inode.set_child_index(index);
Expand Down
31 changes: 21 additions & 10 deletions rafs/src/builder/core/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//! lower tree (MetadataTree).
//! - Traverse the merged tree (OverlayTree) to dump bootstrap and data blobs.

use std::ffi::OsStr;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::sync::Arc;

Expand All @@ -36,15 +36,18 @@ use crate::metadata::{Inode, RafsInodeExt, RafsSuper};
pub struct Tree {
/// Filesystem node.
pub node: Node,
pub name: OsString,
/// Children tree nodes.
pub children: Vec<Tree>,
}

impl Tree {
/// Create a new instance of `Tree` from a filesystem node.
pub fn new(node: Node) -> Self {
let name = node.name().to_owned();
Tree {
node,
name,
children: Vec::new(),
}
}
Expand Down Expand Up @@ -86,6 +89,17 @@ impl Tree {
Ok(())
}

/// Get index of child node with specified `name`.
#[allow(clippy::manual_find)]
pub fn get_child_idx(&self, name: &OsStr) -> Option<usize> {
for idx in 0..self.children.len() {
if self.children[idx].name == name {
return Some(idx);
}
}
None
}

/// Apply new node (upper layer) to node tree (lower layer).
///
/// Support overlay defined in OCI image layer spec
Expand Down Expand Up @@ -133,7 +147,7 @@ impl Tree {
for idx in 0..self.children.len() {
let child = &mut self.children[idx];
// Skip if path component name not match
if target_paths[depth] != child.node.name() {
if target_paths[depth] != child.name {
continue;
}
// Modifications: Replace the node
Expand All @@ -154,13 +168,10 @@ impl Tree {
}

// Additions: Add new node to children
if depth == target_paths_len - 1 && target_paths[depth - 1] == self.node.name() {
if depth == target_paths_len - 1 && target_paths[depth - 1] == self.name {
let mut node = target.clone();
node.overlay = Overlay::UpperAddition;
self.children.push(Tree {
node,
children: Vec::new(),
});
self.children.push(Tree::new(node));
return Ok(true);
}

Expand Down Expand Up @@ -202,7 +213,7 @@ impl Tree {
// Handle Removals
if depth == target_paths_len - 1
&& whiteout_type.is_removal()
&& origin_name == Some(child.node.name())
&& origin_name == Some(&child.name)
{
// Remove the whole lower node
self.children.remove(idx);
Expand All @@ -215,7 +226,7 @@ impl Tree {
&& depth == target_paths_len - 2
{
if let Some(parent_name) = parent_name {
if parent_name == child.node.name() {
if parent_name == child.name {
child.node.overlay = Overlay::UpperOpaque;
// Remove children of the lower node
child.children.clear();
Expand All @@ -224,7 +235,7 @@ impl Tree {
}
} else if whiteout_type == WhiteoutType::OverlayFsOpaque
&& depth == target_paths_len - 1
&& target.name() == child.node.name()
&& target.name() == child.name
{
// Remove all children under the opaque directory
child.node.overlay = Overlay::UpperOpaque;
Expand Down
10 changes: 5 additions & 5 deletions rafs/src/builder/core/v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,14 @@ impl Node {
let mut d_size = 0;

// Sort all children if "." and ".." are not at the head after sorting.
if !tree.children.is_empty() && tree.children[0].node.name() < ".." {
if !tree.children.is_empty() && tree.children[0].name < *".." {
let mut children = Vec::with_capacity(tree.children.len() + 2);
let dot = OsString::from(".");
let dotdot = OsString::from("..");
children.push(dot.as_os_str());
children.push(dotdot.as_os_str());
for child in tree.children.iter() {
children.push(child.node.name());
children.push(&child.name);
}
children.sort_unstable();

Expand All @@ -187,7 +187,7 @@ impl Node {
+ "..".as_bytes().len()
+ size_of::<RafsV6Dirent>()) as u64;
for child in tree.children.iter() {
let len = child.node.name().as_bytes().len() + size_of::<RafsV6Dirent>();
let len = child.name.as_bytes().len() + size_of::<RafsV6Dirent>();
// erofs disk format requires dirent to be aligned to block size.
if (d_size % block_size) + len as u64 > block_size {
d_size = round_up(d_size as u64, block_size);
Expand Down Expand Up @@ -604,13 +604,13 @@ impl Bootstrap {
trace!(
"{:?} child {:?} offset {}, mode {}",
node.name(),
child.node.name(),
child.name,
child.node.v6_offset,
child.node.inode.mode()
);
node.v6_dirents.push((
child.node.v6_offset,
child.node.name().to_os_string(),
child.name.to_os_string(),
child.node.inode.mode(),
));
if child.node.is_dir() {
Expand Down
Loading