2 个版本
0.1.1 | 2023 年 2 月 14 日 |
---|---|
0.1.0 | 2023 年 2 月 13 日 |
#2551 在 算法 中
在 mtcp-rs 中使用
13KB
86 行
备用缓冲区
Vec 的包装器,提供了以 &mut[T]
切片的形式访问向量的“备用”容量。
在底层向量的末尾分配“备用”容量并直接填充它很有用,例如通过从文件或流中 read()
,无需先初始化内存。一旦填充完成,向量可以被“扩展”到之前分配的备用容量中。
Crates.io
https://crates.io/crates/spare_buffer
API 文档
https://docs.rs/spare_buffer/latest/index.html
示例
https://github.com/dEajL3kA/spare_buffer/tree/master/examples
lib.rs
:
Vec 的包装器,提供了以 &mut[T]
切片的形式访问向量的“备用”容量。
在底层向量的末尾分配“备用”容量并直接填充它很有用,例如通过从文件或流中 read()
,无需先初始化内存。一旦填充完成,向量可以被“扩展”到之前分配的备用容量中。
以下两个步骤总是需要,通常在循环中执行
- 分配一个适当长度的新的“备用”缓冲区。
- 一旦“备用”缓冲区被一些有效数据填充,就 提交 它。
请注意,在步骤#1之后,"备用"缓冲区尚未被视为底层向量的有效部分。在步骤#2提交数据时,实际上是将"备用"缓冲区的内容追加到底层向量中,但不复制数据。
没有必要填充"备用"缓冲区的全部内容;只有前n
个元素可以提交。然而,所有要提交的元素必须已初始化,否则提交后底层向量的内容是未定义的!
示例#1
首先,用一个预分配的SpareBuffer
填充一些数字
fn main() {
let mut vec: Vec<u8> = Vec::with_capacity(128);
let mut buffer = SpareBuffer::from(&mut vec, None);
let spare = buffer.allocate_spare(NonZeroUsize::new(100).unwrap());
for i in 0..50 {
spare[i] = i as u8;
}
// Whoops: only &spare[0..50] was initialized, but 100 elements are committed!
buffer.commit(100).expect("Failed to commit!");
println!("Expect valid numbers:");
println!("{:?}\n", &vec[..50]);
println!("Expect \"unspecified\" garbage:");
println!("{:?}\n", &vec[50..]);
}
示例#2
使用SpareBuffer
逐块读取文件到向量,累积所有数据
fn main() {
let mut vec: Vec<u8> = Vec::with_capacity(1048576);
let mut buffer = SpareBuffer::from(&mut vec, NonZeroUsize::new(10485760));
let chunk_size = NonZeroUsize::new(4096).unwrap();
let mut file = File::open("input.dat").expect("Failed to open input file!");
loop {
let spare = buffer.allocate_spare(chunk_size);
let count = file.read(spare).expect("File read error encountered!");
if count > 0 {
buffer.commit(count).expect("Failed to commit!");
} else {
break; /* EOF*/
}
}
println!("Length: {:?}", vec.len());
}