#cdc #chunking #chunk #rabin

yanked cdc-rs

基于Rabin指纹的内容定义分块

使用旧版Rust 2015

0.0.1 2016年9月22日

#6#rabin

MIT 许可证

16KB
312

描述

这个Rust包包含用于执行内容定义分块(CDC)的有用类。

内容定义分块

CDC是指你在数据流中寻找一些特定的模式,并使用它们作为分隔符来将文件切分成小块。

当你的数据发生变化,你想基于之前版本表达新版本时,这很有用:一种方法是引用未更改的先前数据的块,以及包含修改位的新块。

包中包含的内容

从低级到高级

  • 一个 RollingHash64 特征,用于64位哈希值的滚动哈希。

  • Rabin64,一个64位哈希值的Rabin指纹滚动哈希实现。

  • Separator,一个描述数据流中分隔符位置的结构的结构体。

  • SeparatorIter,一个适配器,它接受一个 Iterator<Item=u8> 作为输入,并列出找到的所有分隔符。

  • Chunk,一个描述数据流块(索引和大小)的结构的结构体。

  • ChunkIter,一个适配器,它接受一个 Iterator<Item=Separator> 作为输入,并列出块。

实现细节

  • 这个库不会切割任何文件,它只提供如何做到这一点的信息。

  • 你可以更改 Rabin64 使用的默认窗口大小,以及 SeparatorIter 如何选择分隔符。

  • 这个包的设计不是最终的,并且将来可能会发生变化。

性能

在性能方面,调试构建和发布构建之间有很大的差异。记住,当你测试库时,使用 cargo run --release

我可能会在某个时候尝试提高库的性能,但到目前为止,它们对我的个人使用来说已经足够好了。

入门

使用示例

extern crate cdc_rs;

use std::u64;
use std::cmp::{min, max};
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

use cdc_rs::*;

fn find_chunks_in_file<S: Into<String>>(path: S) -> io::Result<()> {
    let f = try!(File::open(path.into()));
    let stream_length = f.metadata().unwrap().len();
    let reader: BufReader<File> = BufReader::new(f);
    let byte_iter = reader.bytes().map(|b| b.unwrap());
    let separator_iter = SeparatorIter::new(byte_iter);
    let chunk_iter = ChunkIter::new(separator_iter, stream_length);

    let mut nb_chunk = 0;
    let mut total_size = 0;
    let mut smallest_size = u64::MAX;
    let mut largest_size = 0;
    let expected_size = 1 << 13;
    let mut size_variance = 0;
    for chunk in chunk_iter {
        println!("Index: {}, size: {:6}, separator_hash: {:016x}", chunk.index, chunk.size, chunk.separator_hash);
        nb_chunk += 1;
        total_size += chunk.size;
        smallest_size = min(smallest_size, chunk.size);
        largest_size = max(largest_size, chunk.size);
        size_variance += (chunk.size - expected_size).pow(2);
    }

    println!("{} chunks with an average size of {} bytes.", nb_chunk, total_size / nb_chunk);
    println!("Expected chunk size: {} bytes", expected_size);
    println!("Smallest chunk: {} bytes.", smallest_size);
    println!("Largest chunk: {} bytes.", largest_size);
    println!("Standard size deviation: {} bytes.",
        (size_variance as f64 / nb_chunk as f64).sqrt() as u64);

	Ok(())
}

fn main() {
	find_chunks_in_file("my_large_file.bin").unwrap();
}

许可证

此软件根据 MIT 许可证 授权。

无运行时依赖