use std::sync::Arc;
use fjall::config::{
BlockSizePolicy, CompressionPolicy, HashRatioPolicy, PinningPolicy, RestartIntervalPolicy,
};
use fjall::{
CompressionType, Database, Keyspace as FjallKeyspace, KeyspaceCreateOptions,
KvSeparationOptions,
};
use crate::conf::{Conf, parse_compression_type};
use crate::error::{Error, Result};
pub const DATA: &str = "data";
pub const META: &str = "meta";
#[derive(Clone)]
pub struct Keyspace {
pub data: FjallKeyspace,
pub meta: FjallKeyspace,
}
impl Keyspace {
pub fn open(db: &Arc<Database>, conf: &Conf) -> Result<Self> {
let comp_type = parse_compression_type(conf.compression.as_deref(), CompressionType::Lz4);
let data_comp_policy = match comp_type {
CompressionType::None => CompressionPolicy::disabled(),
CompressionType::Lz4 => CompressionPolicy::new([
CompressionType::None,
CompressionType::None,
CompressionType::Lz4,
]),
};
let manual_persist = conf.manual_journal_persist.unwrap_or(false);
let data_policy = data_comp_policy.clone();
let data = db
.keyspace(DATA, move || {
KeyspaceCreateOptions::default()
.data_block_size_policy(BlockSizePolicy::all(4 * 1024))
.data_block_compression_policy(data_policy)
.data_block_hash_ratio_policy(HashRatioPolicy::all(0.75))
.data_block_restart_interval_policy(RestartIntervalPolicy::new([8, 16]))
.index_block_pinning_policy(PinningPolicy::all(true))
.filter_block_pinning_policy(PinningPolicy::all(true))
.max_memtable_size(64 * 1024 * 1024)
.manual_journal_persist(manual_persist)
.with_kv_separation(Some(
KvSeparationOptions::default()
.separation_threshold(4096)
.compression(CompressionType::Lz4),
))
})
.map_err(|e| Error::internal_with_source("Failed to open data keyspace", e))?;
let meta = db
.keyspace(META, move || {
KeyspaceCreateOptions::default()
.data_block_size_policy(BlockSizePolicy::all(4 * 1024))
.data_block_compression_policy(data_comp_policy)
.data_block_hash_ratio_policy(HashRatioPolicy::all(0.75))
.data_block_restart_interval_policy(RestartIntervalPolicy::new([8, 16]))
.index_block_pinning_policy(PinningPolicy::all(true))
.filter_block_pinning_policy(PinningPolicy::all(true))
.max_memtable_size(32 * 1024 * 1024)
.manual_journal_persist(manual_persist)
})
.map_err(|e| Error::internal_with_source("Failed to open meta keyspace", e))?;
Ok(Self { data, meta })
}
}