summaryrefslogtreecommitdiff
path: root/src/chunker/rw/storage.rs
blob: 135ad4c47c27027ab190828071a6f3c6b0e6fc77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
pub mod bidx;
pub mod build;
pub mod hash;
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,
}

/// Calculate the storage path of a chunk file based on its hash value
pub fn get_chunk_path(storage_dir: &Path, hash_hex: &str) -> PathBuf {
    let first_slice = &hash_hex[0..2];
    storage_dir.join(first_slice).join(hash_hex)
}

/// Calculate the storage path of a chunk file based on its hash byte array
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)
}

/// Generate a unique file path, adding a numeric suffix if the file already exists
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
}