Skip to content

Commit

Permalink
nydus-image:Optimize Chunkdict Save
Browse files Browse the repository at this point in the history
Refactor the Deduplicate implementation to only
initialize config when inserting chunk data.
Simplify code for better maintainability.

Signed-off-by: Lin Wang <[email protected]>
  • Loading branch information
cslinwang committed Sep 19, 2023
1 parent d2fcfcd commit 8054586
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 29 deletions.
27 changes: 20 additions & 7 deletions src/bin/nydus-image/deduplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,35 @@ impl Database for SqliteDatabase {
}

pub struct Deduplicate<D: Database + Send + Sync> {
sb: RafsSuper,
sb: Option<RafsSuper>,
db: D,
}

const IN_MEMORY_DB_URL: &str = ":memory:";

impl Deduplicate<SqliteDatabase> {
pub fn new(bootstrap_path: &Path, config: Arc<ConfigV2>, db_url: &str) -> anyhow::Result<Self> {
let (sb, _) = RafsSuper::load_from_file(bootstrap_path, config, false)?;
pub fn new(db_url: &str) -> anyhow::Result<Self> {
let db = if db_url == IN_MEMORY_DB_URL {
SqliteDatabase::new_in_memory()?
} else {
SqliteDatabase::new(db_url)?
};
Ok(Self { sb, db })
Ok(Self { sb: None, db })
}

pub fn save_metadata(&mut self) -> anyhow::Result<Vec<Arc<BlobInfo>>> {
pub fn save_metadata(
&mut self,
bootstrap_path: &Path,
config: Arc<ConfigV2>,
) -> anyhow::Result<Vec<Arc<BlobInfo>>> {
let (sb, _) = RafsSuper::load_from_file(bootstrap_path, config, false)?;
self.sb = Some(sb);
self.create_tables()?;
let blob_infos = self.sb.superblock.get_blob_infos();
let sb = self
.sb
.as_ref()
.ok_or_else(|| anyhow!("RafsSuper is not initialized"))?;
let blob_infos = sb.superblock.get_blob_infos();
self.insert_blobs(&blob_infos)?;
self.insert_chunks(&blob_infos)?;
Ok(blob_infos)
Expand Down Expand Up @@ -195,7 +204,11 @@ impl Deduplicate<SqliteDatabase> {
}
Ok(())
};
let tree = Tree::from_bootstrap(&self.sb, &mut ())
let sb = self
.sb
.as_ref()
.ok_or_else(|| anyhow!("RafsSuper is not initialized"))?;
let tree = Tree::from_bootstrap(sb, &mut ())
.context("Failed to load bootstrap for deduplication.")?;
tree.walk_dfs_pre(process_chunk)?;
Ok(())
Expand Down
28 changes: 6 additions & 22 deletions src/bin/nydus-image/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use nydus_builder::{
use nydus_rafs::metadata::{RafsSuper, RafsSuperConfig, RafsVersion};
use nydus_storage::backend::localfs::LocalFs;
use nydus_storage::backend::BlobBackend;
use nydus_storage::device::{BlobFeatures, BlobInfo};
use nydus_storage::device::BlobFeatures;
use nydus_storage::factory::BlobFactory;
use nydus_storage::meta::{format_blob_features, BatchContextGenerator};
use nydus_storage::{RAFS_DEFAULT_CHUNK_SIZE, RAFS_MAX_CHUNK_SIZE};
Expand Down Expand Up @@ -369,7 +369,6 @@ fn prepare_cmd_args(bti_string: &'static str) -> App {
.short('B')
.long("bootstrap")
.help("File path of RAFS meta blob/bootstrap")
.conflicts_with("BOOTSTRAP")
.required(false),
)
.arg(
Expand Down Expand Up @@ -399,7 +398,7 @@ fn prepare_cmd_args(bti_string: &'static str) -> App {
)
.arg(arg_output_json.clone())
)
);
);

let app = app.subcommand(
App::new("merge")
Expand Down Expand Up @@ -1151,32 +1150,17 @@ impl Command {
bail!("Invalid database URL: {}", db_url);
}

let blobs: Vec<Arc<BlobInfo>> = match db_strs[0] {
match db_strs[0] {
"sqlite" => {
let mut deduplicate: Deduplicate<SqliteDatabase> =
Deduplicate::<SqliteDatabase>::new(bootstrap_path, config, db_strs[1])?;
deduplicate.save_metadata()?
Deduplicate::<SqliteDatabase>::new(db_strs[1])?;
deduplicate.save_metadata(bootstrap_path, config)?
}
_ => {
bail!("Unsupported database type: {}, please use a valid database URI, such as 'sqlite:///path/to/database.db'.", db_strs[0])
}
};
info!("RAFS filesystem metadata is saved:");

let mut blob_ids = Vec::new();
for (idx, blob) in blobs.iter().enumerate() {
info!(
"\t {}: {}, compressed data size 0x{:x}, compressed file size 0x{:x}, uncompressed file size 0x{:x}, chunks: 0x{:x}, features: {}.",
idx,
blob.blob_id(),
blob.compressed_data_size(),
blob.compressed_size(),
blob.uncompressed_size(),
blob.chunk_count(),
format_blob_features(blob.features()),
);
blob_ids.push(blob.blob_id().to_string());
}
info!("Chunkdict metadata is saved at: {:?}", db_url);
Ok(())
}

Expand Down

0 comments on commit 8054586

Please sign in to comment.