use std::path::{Path, PathBuf};
use super::bt_writer::{BtOptions, build_bt_from_seg};
use super::kvei_writer::build_kvei_from_seg;
use super::seg_writer::SegWriter;
use crate::error::{Error, Result};
use crate::seg::Seg;
#[derive(Debug, Clone, Copy, Default)]
pub struct DomainOptions {
pub bt: BtOptions,
pub salt: Option<u32>,
pub compress: bool,
}
#[derive(Debug, Clone)]
pub struct DomainPaths {
pub kv: PathBuf,
pub bt: PathBuf,
pub kvei: Option<PathBuf>,
}
pub struct DomainWriter {
kv_path: PathBuf,
seg: SegWriter,
opts: DomainOptions,
last_key: Option<Vec<u8>>,
key_count: u64,
}
impl DomainWriter {
pub fn create(kv_path: impl AsRef<Path>, opts: DomainOptions) -> Result<DomainWriter> {
let kv_path = kv_path.as_ref().to_path_buf();
let seg = SegWriter::create_with(&kv_path, opts.compress)?;
Ok(DomainWriter {
kv_path,
seg,
opts,
last_key: None,
key_count: 0,
})
}
pub fn add(&mut self, key: &[u8], value: &[u8]) -> Result<()> {
if let Some(last) = &self.last_key
&& key <= last.as_slice()
{
return Err(Error::format(format!(
"DomainWriter: keys must be strictly increasing (got {:02x?} after {:02x?})",
key, last
)));
}
self.seg.add_word(key)?;
self.seg.add_word(value)?;
self.last_key = Some(key.to_vec());
self.key_count += 1;
Ok(())
}
pub fn key_count(&self) -> u64 {
self.key_count
}
pub fn finish(self) -> Result<DomainPaths> {
let kv_path = self.kv_path;
let bt_path = kv_path.with_extension("bt");
let opts = self.opts;
self.seg.finish()?;
let seg = Seg::open(&kv_path)?;
build_bt_from_seg(&seg, &bt_path, opts.bt)?;
let kvei = match opts.salt {
Some(salt) => {
let kvei_path = kv_path.with_extension("kvei");
build_kvei_from_seg(&seg, salt, &kvei_path)?;
Some(kvei_path)
}
None => None,
};
Ok(DomainPaths {
kv: kv_path,
bt: bt_path,
kvei,
})
}
}