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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//! Build a global index of a kff file
/* std use */
/* crate use */
/* project use */
use crate::error;
use crate::section;
use crate::KffRead;
/// Struct that manage and build a global index of a Kff file
#[derive(getset::Getters, getset::Setters, getset::MutGetters, std::default::Default)]
#[getset(get = "pub")]
pub struct GlobalIndex {
/// Pair of section type and position from begin of file
pair: Vec<(u8, u64)>,
}
impl GlobalIndex {
/// Create a GlobalIndex by scan all index in file
///
/// At the end of scan position in file is the start of the first_index
pub fn new<R>(inner: &mut R, first_index: u64) -> error::Result<Self>
where
R: std::io::Read + std::io::Seek + KffRead,
{
let mut pair = Vec::new();
inner.seek(std::io::SeekFrom::Start(first_index))?;
let section_type = inner.read_u8()?;
if section_type != b'i' {
return Err(error::Kff::NotAnIndex.into());
}
loop {
let local_index = section::Index::read(inner)?;
let relative_to = inner.stream_position()?;
pair.extend(
local_index
.pair()
.iter()
.map(|(t, pos)| (*t, (relative_to as i64 + *pos) as u64)),
);
if local_index.next_index() == &0 {
break;
} else {
inner.seek(std::io::SeekFrom::Current(
(*local_index.next_index()) as i64,
))?;
}
}
pair.sort_unstable_by_key(|k| k.1);
Ok(Self { pair })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn create() -> error::Result<()> {
let mut file = std::io::Cursor::new(vec![
b'i', // Index start
0, 0, 0, 0, 0, 0, 0, 3, // Number of value indexed
b'r', 0, 0, 0, 0, 0, 0, 0, 1, // Raw section
b'i', 0, 0, 0, 0, 0, 0, 0, 0, // Index refere to them self
b'm', 0, 0, 0, 0, 0, 0, 0, 3, // Minimizer section
0, 0, 0, 0, 0, 0, 0, 1, // Next index section
b'i', // Index start
0, 0, 0, 0, 0, 0, 0, 3, // Number of value indexed
b't', 255, 255, 255, 255, 255, 255, 255, 253, // a T section with value in past
b'r', 0, 0, 0, 0, 0, 0, 0, 1, // Raw section
b'm', 0, 0, 0, 0, 0, 0, 0, 3, // Minimizer section
0, 0, 0, 0, 0, 0, 0, 9, // Next index section
0, 0, 0, 0, 0, 0, 0, 0, // empty part
b'i', // Index start
0, 0, 0, 0, 0, 0, 0, 3, // Number of value indexed
b'm', 0, 0, 0, 0, 0, 0, 0, 3, // Minimizer section
b'r', 0, 0, 0, 0, 0, 0, 0, 1, // Raw section
b't', 255, 255, 255, 255, 255, 255, 255, 253, // a T section with value in past
0, 0, 0, 0, 0, 0, 0, 0, // Next index section
]);
let index = GlobalIndex::new(&mut file, 0)?;
assert_eq!(
index.pair(),
&vec![
(105, 44),
(114, 45),
(109, 47),
(116, 85),
(114, 89),
(109, 91),
(116, 137),
(114, 141),
(109, 143)
]
);
Ok(())
}
}