use crate::Error;
use std::fs;
use std::io;
use std::path::Path;
pub struct Builder<WK, WV> {
map_builder: fst::MapBuilder<WK>,
value_writer: WV,
value_cursor: usize,
committed_value_cursor: usize,
}
impl<WK, WV> Builder<WK, WV>
where
WK: io::Write,
WV: io::Write,
{
pub fn new(index_writer: WK, value_writer: WV) -> Result<Self, Error> {
Ok(Self {
map_builder: fst::MapBuilder::new(index_writer)?,
value_writer,
committed_value_cursor: 0,
value_cursor: 0,
})
}
pub fn insert(&mut self, key: &[u8], value: &[u8]) -> Result<(), Error> {
self.append_value_bytes(value)?;
self.commit_entry(key)
}
pub fn commit_entry(&mut self, key: &[u8]) -> Result<(), Error> {
self.map_builder
.insert(key, u64::try_from(self.committed_value_cursor).unwrap())?;
self.committed_value_cursor = self.value_cursor;
Ok(())
}
pub fn append_value_bytes(&mut self, value: &[u8]) -> Result<(), Error> {
self.value_writer.write_all(value)?;
self.value_cursor += value.len();
Ok(())
}
pub fn finish(mut self) -> Result<(), Error> {
self.value_writer.flush()?;
Ok(self.map_builder.finish()?)
}
}
pub type FileBuilder = Builder<io::BufWriter<fs::File>, io::BufWriter<fs::File>>;
impl FileBuilder {
pub fn create_files(
index_path: impl AsRef<Path>,
value_path: impl AsRef<Path>,
) -> Result<Self, Error> {
let index_writer = io::BufWriter::new(fs::File::create(index_path)?);
let value_writer = io::BufWriter::new(fs::File::create(value_path)?);
Builder::new(index_writer, value_writer)
}
}