Skip to content

Commit

Permalink
rafs: avoid unnecessary memory copy by using VecDeque
Browse files Browse the repository at this point in the history
Vec::insert(0, node) will cause unnecessary memory copy, so use
VecDeque instead.

Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
  • Loading branch information
jiangliu committed Mar 16, 2023
1 parent a861ec7 commit 269d3cc
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 25 deletions.
8 changes: 4 additions & 4 deletions rafs/src/builder/compact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::collections::{HashMap, VecDeque};
use std::io::Write;
use std::ops::Deref;
use std::path::PathBuf;
Expand Down Expand Up @@ -252,7 +252,7 @@ pub struct BlobCompactor {
/// new blobs
new_blob_mgr: BlobManager,
/// inode list
nodes: Vec<Node>,
nodes: VecDeque<Node>,
/// chunk --> list<node_idx, chunk_idx in node>
c2nodes: HashMap<ChunkKey, Vec<(usize, usize)>>,
/// original blob index --> list<node_idx, chunk_idx in node>
Expand All @@ -265,7 +265,7 @@ impl BlobCompactor {
pub fn new(
version: RafsVersion,
ori_blob_mgr: BlobManager,
nodes: Vec<Node>,
nodes: VecDeque<Node>,
backend: Arc<dyn BlobBackend + Send + Sync>,
digester: digest::Algorithm,
) -> Result<Self> {
Expand Down Expand Up @@ -596,7 +596,7 @@ impl BlobCompactor {
let tree = Tree::from_bootstrap(&rs, &mut _dict)?;
let mut bootstrap = Bootstrap::new()?;
bootstrap.build(&mut build_ctx, &mut bootstrap_ctx, tree)?;
let mut nodes = Vec::new();
let mut nodes = VecDeque::new();
// move out nodes
std::mem::swap(&mut bootstrap_ctx.nodes, &mut nodes);
let mut compactor = Self::new(
Expand Down
3 changes: 2 additions & 1 deletion rafs/src/builder/core/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

use std::borrow::Cow;
use std::collections::VecDeque;
use std::io::Write;
use std::slice;

Expand All @@ -27,7 +28,7 @@ impl Blob {
/// Dump blob file and generate chunks
pub(crate) fn dump(
ctx: &BuildContext,
nodes: &mut [Node],
nodes: &mut VecDeque<Node>,
blob_mgr: &mut BlobManager,
blob_writer: &mut ArtifactWriter,
) -> Result<()> {
Expand Down
15 changes: 8 additions & 7 deletions rafs/src/builder/core/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::collections::VecDeque;
use std::ffi::OsString;

use anyhow::{Context, Error, Result};
Expand Down Expand Up @@ -52,7 +53,7 @@ impl Bootstrap {
) -> Result<()> {
// used to compute nid(ino) for v6
let root_offset = bootstrap_ctx.offset;
let mut nodes = Vec::with_capacity(0x10000);
let mut nodes = VecDeque::with_capacity(0x10000);

// Special handling of the root inode
assert!(tree.node.is_dir());
Expand All @@ -63,7 +64,7 @@ impl Bootstrap {
tree.node.inode.set_ino(RAFS_V5_ROOT_INODE);
}
ctx.prefetch.insert_if_need(&tree.node);
nodes.push(tree.node.clone());
nodes.push_back(tree.node.clone());

Self::build_rafs(ctx, bootstrap_ctx, &mut tree, &mut nodes)?;
if ctx.fs_version.is_v6() && !bootstrap_ctx.layered {
Expand Down Expand Up @@ -147,7 +148,7 @@ impl Bootstrap {
ctx: &mut BuildContext,
bootstrap_ctx: &mut BootstrapContext,
tree: &mut Tree,
nodes: &mut Vec<Node>,
nodes: &mut VecDeque<Node>,
) -> Result<()> {
let index = nodes.len() as u32 + 1;
let parent = &mut nodes[tree.node.index as usize - 1];
Expand Down Expand Up @@ -231,14 +232,14 @@ impl Bootstrap {
(true, Some(whiteout_type)) => {
// Insert removal operations at the head, so they will be handled first when
// applying to lower layer.
nodes.insert(0, child.node.clone());
nodes.push_front(child.node.clone());
if whiteout_type == WhiteoutType::OverlayFsOpaque {
// For the overlayfs opaque, we need to remove the lower node that has the
// same name first, then apply upper node to the node tree of lower layer.
child
.node
.remove_xattr(&OsString::from(OVERLAYFS_WHITEOUT_OPAQUE));
nodes.push(child.node.clone());
nodes.push_back(child.node.clone());
}
}
(false, Some(whiteout_type)) => {
Expand All @@ -248,9 +249,9 @@ impl Bootstrap {
.node
.remove_xattr(&OsString::from(OVERLAYFS_WHITEOUT_OPAQUE));
}
nodes.push(child.node.clone());
nodes.push_back(child.node.clone());
}
_ => nodes.push(child.node.clone()),
_ => nodes.push_back(child.node.clone()),
}

ctx.prefetch.insert_if_need(&child.node);
Expand Down
4 changes: 2 additions & 2 deletions rafs/src/builder/core/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ pub struct BootstrapContext {
/// Cache node index for hardlinks, HashMap<(layer_index, real_inode, dev), Vec<index>>.
pub(crate) inode_map: HashMap<(u16, Inode, u64), Vec<u64>>,
/// Store all nodes in ascendant order, indexed by (node.index - 1).
pub nodes: Vec<Node>,
pub nodes: VecDeque<Node>,
/// Current position to write in f_bootstrap
pub(crate) offset: u64,
pub(crate) writer: Box<dyn RafsIoWrite>,
Expand All @@ -979,7 +979,7 @@ impl BootstrapContext {
Ok(Self {
layered,
inode_map: HashMap::new(),
nodes: Vec::new(),
nodes: VecDeque::new(),
offset: EROFS_BLOCK_SIZE_4096,
writer,
v6_available_blocks: vec![
Expand Down
6 changes: 5 additions & 1 deletion rafs/src/builder/core/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use std::collections::VecDeque;

use super::node::Node;
use crate::builder::{Overlay, Prefetch};
Expand All @@ -11,7 +12,10 @@ use crate::builder::{Overlay, Prefetch};
pub struct BlobLayout {}

impl BlobLayout {
pub fn layout_blob_simple(prefetch: &Prefetch, nodes: &[Node]) -> Result<(Vec<usize>, usize)> {
pub fn layout_blob_simple(
prefetch: &Prefetch,
nodes: &VecDeque<Node>,
) -> Result<(Vec<usize>, usize)> {
let mut inodes = Vec::with_capacity(nodes.len());

// Put all prefetch inodes at the head
Expand Down
6 changes: 3 additions & 3 deletions rafs/src/builder/core/prefetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::collections::BTreeMap;
use std::collections::{BTreeMap, VecDeque};
use std::path::PathBuf;
use std::str::FromStr;

Expand Down Expand Up @@ -181,7 +181,7 @@ impl Prefetch {
}

/// Generate filesystem layer prefetch list for RAFS v5.
pub fn get_v5_prefetch_table(&mut self, nodes: &[Node]) -> Option<RafsV5PrefetchTable> {
pub fn get_v5_prefetch_table(&mut self, nodes: &VecDeque<Node>) -> Option<RafsV5PrefetchTable> {
if self.policy == PrefetchPolicy::Fs {
let mut prefetch_table = RafsV5PrefetchTable::new();
for i in self.patterns.values().filter_map(|v| *v) {
Expand All @@ -199,7 +199,7 @@ impl Prefetch {
/// Generate filesystem layer prefetch list for RAFS v6.
pub fn get_v6_prefetch_table(
&mut self,
nodes: &[Node],
nodes: &VecDeque<Node>,
meta_addr: u64,
) -> Option<RafsV6PrefetchTable> {
if self.policy == PrefetchPolicy::Fs {
Expand Down
4 changes: 2 additions & 2 deletions rafs/src/builder/core/v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::collections::BTreeMap;
use std::collections::{BTreeMap, VecDeque};
use std::ffi::{OsStr, OsString};
use std::io::SeekFrom;
use std::mem::size_of;
Expand Down Expand Up @@ -556,7 +556,7 @@ impl BuildContext {
}

impl Bootstrap {
pub(crate) fn v6_update_dirents(nodes: &mut Vec<Node>, tree: &Tree, parent_offset: u64) {
pub(crate) fn v6_update_dirents(nodes: &mut VecDeque<Node>, tree: &Tree, parent_offset: u64) {
let node = &mut nodes[tree.node.index as usize - 1];
let node_offset = node.v6_offset;
if !node.is_dir() {
Expand Down
10 changes: 5 additions & 5 deletions rafs/src/builder/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
//
// SPDX-License-Identifier: Apache-2.0

use std::collections::btree_map::Entry;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::collections::HashSet;
use std::collections::{HashMap, VecDeque};
use std::convert::TryFrom;
use std::path::{Path, PathBuf};
use std::sync::Arc;
Expand Down Expand Up @@ -211,7 +211,7 @@ impl Merger {
}

if let Some(tree) = &mut tree {
let mut nodes = Vec::new();
let mut nodes = VecDeque::new();
rs.walk_directory::<PathBuf>(
rs.superblock.root_ino(),
None,
Expand Down Expand Up @@ -245,8 +245,8 @@ impl Merger {
match node.whiteout_type(WhiteoutSpec::Oci) {
// Insert whiteouts at the head, so they will be handled first when
// applying to lower layer.
Some(_) => nodes.insert(0, node),
_ => nodes.push(node),
Some(_) => nodes.push_front(node),
_ => nodes.push_back(node),
}
Ok(())
},
Expand Down

0 comments on commit 269d3cc

Please sign in to comment.