diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-03-04 21:26:04 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-03-04 21:35:09 +0800 |
| commit | 22926ce29e3f8e040ec349401aeb6a77f32eae72 (patch) | |
| tree | 678753ec49a61fb9d3e2d8e869393dec90ea7ef4 /src/chunker/rw/storage/write.rs | |
Initialize Butchunker project structure and policy system
Diffstat (limited to 'src/chunker/rw/storage/write.rs')
| -rw-r--r-- | src/chunker/rw/storage/write.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/chunker/rw/storage/write.rs b/src/chunker/rw/storage/write.rs new file mode 100644 index 0000000..8b3acc7 --- /dev/null +++ b/src/chunker/rw/storage/write.rs @@ -0,0 +1,118 @@ +use std::{collections::HashMap, path::PathBuf}; + +use log::trace; + +use crate::{ + chunker::{ + constants::BUTCK_INDEX_FILE_SUFFIX, + context::ButckContext, + rw::{ + error::{ButckRWError, ButckRWErrorKind}, + storage::generate_unique_path, + }, + }, + storage::{simple::write_file_simple, stream::write_file_stream}, +}; + +pub mod simple; +pub mod stream; + +pub async fn write(ctx: ButckContext) -> Result<(), ButckRWError> { + if ctx.storage_path.is_none() { + return Err(ButckRWErrorKind::NoButckStorageFound.pack(ctx)); + } + if ctx.policy_name.is_none() { + return Err(ButckRWErrorKind::ChunkingPolicyNotSpecified.pack(ctx)); + } + if ctx.file_paths.len() > 1 && ctx.output_file.is_some() { + return Err(ButckRWErrorKind::OutputCountMismatch.pack(ctx)); + } + + // Cannot enable both memory-mapped and stream reading simultaneously. + // Stream reading uses butck_policies::chunk_stream_with, + // while memory-mapped or default reading uses butck_policies::chunk_with. + if ctx.memmap_read && ctx.stream_read.is_some() { + return Err(ButckRWErrorKind::ReadingMethodAmbiguous.pack(ctx)); + } + + let param_refs: HashMap<&str, &str> = ctx + .params + .iter() + .map(|(k, v)| (k.as_str(), v.as_str())) + .collect(); + + let tasks: Vec<_> = ctx + .file_paths + .iter() + .map(|path| async { + trace!("Preparing to write file `{}`", path.display()); + write_file(path, &ctx, ¶m_refs).await + }) + .collect(); + + let results = futures::future::join_all(tasks).await; + + for result in results { + if let Err(e) = result { + return Err(e.pack(ctx)); + } + } + + Ok(()) +} + +async fn write_file( + path: &PathBuf, + ctx: &ButckContext, + params: &HashMap<&str, &str>, +) -> Result<(), ButckRWErrorKind> { + if let Some(stream_read_size) = ctx.stream_read { + write_file_stream(path, stream_read_size, ctx, params).await + } else { + write_file_simple(path, ctx, params).await + } +} + +pub fn get_index_file_name(path: &PathBuf, ctx: &ButckContext) -> PathBuf { + let output_file = if let Some(output_file) = &ctx.output_file { + return output_file.clone(); + } else { + ctx.output_dir.join(path.file_name().unwrap_or_default()) + }; + + // Append .bidx suffix directly to the original file name + let desired_filename = if let Some(ext) = output_file.extension() { + let ext_str = ext.to_string_lossy(); + if ext_str.is_empty() { + format!( + "{}.{}", + output_file + .file_stem() + .unwrap_or_default() + .to_string_lossy(), + BUTCK_INDEX_FILE_SUFFIX + ) + } else { + format!( + "{}.{}.{}", + output_file + .file_stem() + .unwrap_or_default() + .to_string_lossy(), + ext_str, + BUTCK_INDEX_FILE_SUFFIX + ) + } + } else { + format!( + "{}.{}", + output_file + .file_name() + .unwrap_or_default() + .to_string_lossy(), + BUTCK_INDEX_FILE_SUFFIX + ) + }; + + generate_unique_path(&ctx.output_dir, &desired_filename) +} |
