summaryrefslogtreecommitdiff
path: root/src/chunker/rw/storage/write.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/chunker/rw/storage/write.rs')
-rw-r--r--src/chunker/rw/storage/write.rs118
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, &param_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)
+}