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.rs | |
Initialize Butchunker project structure and policy system
Diffstat (limited to 'src/chunker/rw/storage.rs')
| -rw-r--r-- | src/chunker/rw/storage.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/chunker/rw/storage.rs b/src/chunker/rw/storage.rs new file mode 100644 index 0000000..13452d0 --- /dev/null +++ b/src/chunker/rw/storage.rs @@ -0,0 +1,88 @@ +pub mod build; +pub mod write; + +pub use build::build; +pub use write::write; + +use std::path::{Path, PathBuf}; + +/// Information about a chunk for index file +#[derive(Debug, Clone)] +pub struct ChunkInfo { + /// Index of the chunk in the file + pub index: usize, + /// Hash of the chunk (hex string) + pub hash: String, + /// Size of the chunk in bytes + pub size: usize, + /// Start position in the original file + pub start: usize, + /// End position in the original file (exclusive) + pub end: usize, +} + +/// 根据hash值计算chunk文件的存储路径 +/// +/// # 参数 +/// - `storage_dir`: 存储目录 +/// - `hash_hex`: chunk的hash值(16进制字符串) +/// +/// # 返回 +/// 返回chunk文件的完整路径 +pub fn get_chunk_path(storage_dir: &Path, hash_hex: &str) -> PathBuf { + let first_slice = &hash_hex[0..2]; + let second_slice = &hash_hex[2..4]; + storage_dir + .join(first_slice) + .join(second_slice) + .join(hash_hex) +} + +/// 根据hash字节数组计算chunk文件的存储路径 +/// +/// # 参数 +/// - `storage_dir`: 存储目录 +/// - `hash_bytes`: chunk的hash值(字节数组) +/// +/// # 返回 +/// 返回chunk文件的完整路径 +pub fn get_chunk_path_from_bytes(storage_dir: &Path, hash_bytes: &[u8; 32]) -> PathBuf { + let hash_hex = hex::encode(hash_bytes); + get_chunk_path(storage_dir, &hash_hex) +} + +/// 生成唯一的文件路径,如果文件已存在则添加数字后缀 +/// +/// # 参数 +/// - `output_dir`: 输出目录 +/// - `desired_filename`: 期望的文件名 +/// +/// # 返回 +/// 返回唯一的文件路径 +pub fn generate_unique_path(output_dir: &Path, desired_filename: &str) -> PathBuf { + let desired_path = output_dir.join(desired_filename); + let mut candidate = desired_path.clone(); + + let mut counter = 1; + while candidate.exists() { + let path_buf = PathBuf::from(desired_filename); + if let Some(stem) = path_buf.file_stem() { + if let Some(ext) = path_buf.extension() { + let ext_str = ext.to_string_lossy(); + let new_name = if ext_str.is_empty() { + format!("{}_{}", stem.to_string_lossy(), counter) + } else { + format!("{}.{}_{}", stem.to_string_lossy(), ext_str, counter) + }; + candidate = output_dir.join(new_name); + } else { + candidate = output_dir.join(format!("{}_{}", stem.to_string_lossy(), counter)); + } + } else { + candidate = output_dir.join(format!("{}_{}", desired_filename, counter)); + } + counter += 1; + } + + candidate +} |
