use super::ConsumerConfig;
use crate::configs::config_holder::AutosaveLockWriteGuard;
use crate::configs::{ApplicationConfig, ApplicationConfigHolder, ConfigHolder, Persistable};
use crate::errors::SummaResult;
use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use std::path::PathBuf;
use tantivy::schema::Schema as Fields;
#[derive(Clone, Serialize, Deserialize)]
pub enum IndexEngine {
File(PathBuf),
Memory(Fields),
}
impl Debug for IndexEngine {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
IndexEngine::File(_) => "File",
IndexEngine::Memory(_) => "Memory",
}
)
}
}
#[derive(Builder, Clone, Serialize, Deserialize)]
pub struct IndexConfig {
#[builder(default = "None")]
pub autocommit_interval_ms: Option<u64>,
#[builder(default = "HashMap::new()")]
pub consumer_configs: HashMap<String, ConsumerConfig>,
#[builder(default = "Vec::new()")]
pub default_fields: Vec<String>,
pub index_engine: IndexEngine,
#[builder(default = "None")]
pub primary_key: Option<String>,
#[builder(default = "HashSet::new()")]
pub multi_fields: HashSet<String>,
#[builder(default = "None")]
pub stop_words: Option<Vec<String>>,
#[builder(default = "128 * 1024 * 1024")]
pub writer_heap_size_bytes: u64,
#[builder(default = "1")]
pub writer_threads: u64,
}
impl Debug for IndexConfig {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}", &serde_yaml::to_string(&self).unwrap())
}
}
#[derive(Clone)]
pub struct IndexConfigProxy {
application_config: ApplicationConfigHolder,
index_name: String,
}
impl IndexConfigProxy {
pub fn new(application_config: &ApplicationConfigHolder, index_name: &str) -> IndexConfigProxy {
IndexConfigProxy {
application_config: application_config.clone(),
index_name: index_name.to_owned(),
}
}
pub fn read(&self) -> IndexConfigReadProxy {
IndexConfigReadProxy {
application_config: self.application_config.read(),
index_name: self.index_name.to_owned(),
}
}
pub fn write(&self) -> IndexConfigWriteProxy {
IndexConfigWriteProxy {
application_config: self.application_config.write(),
index_name: self.index_name.to_owned(),
}
}
pub fn delete(self) -> IndexConfig {
self.application_config.write().autosave().indices.remove(&self.index_name).unwrap()
}
}
pub struct IndexConfigReadProxy<'a> {
application_config: RwLockReadGuard<'a, ConfigHolder<ApplicationConfig>>,
index_name: String,
}
impl<'a> IndexConfigReadProxy<'a> {
pub fn get(&self) -> &IndexConfig {
self.application_config.indices.get(&self.index_name).unwrap()
}
pub fn application_config(&self) -> &ConfigHolder<ApplicationConfig> {
self.application_config.deref()
}
}
impl<'a> Deref for IndexConfigReadProxy<'a> {
type Target = IndexConfig;
fn deref(&self) -> &Self::Target {
self.get()
}
}
pub struct IndexConfigWriteProxy<'a> {
application_config: RwLockWriteGuard<'a, ConfigHolder<ApplicationConfig>>,
index_name: String,
}
impl<'a> IndexConfigWriteProxy<'a> {
pub fn get(&self) -> &IndexConfig {
self.application_config.indices.get(&self.index_name).unwrap()
}
pub fn get_mut(&mut self) -> &mut IndexConfig {
self.application_config.indices.get_mut(&self.index_name).unwrap()
}
pub fn application_config(&self) -> &ConfigHolder<ApplicationConfig> {
self.application_config.deref()
}
pub fn autosave(&mut self) -> AutosaveLockWriteGuard<IndexConfigWriteProxy<'a>> {
AutosaveLockWriteGuard::new(self)
}
}
impl<'a> Persistable for IndexConfigWriteProxy<'a> {
fn save(&self) -> SummaResult<&Self> {
self.application_config.save()?;
Ok(self)
}
}
impl<'a> Deref for IndexConfigWriteProxy<'a> {
type Target = IndexConfig;
fn deref(&self) -> &Self::Target {
self.get()
}
}