use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use crate::editorconfig::EditorConfig;
use crate::engine::rule_execution_context::rule_editor_config;
use crate::engine::rule_filter::{InternalRuleProvidersFilter, RuleExecutionRuleFilter, apply_rule_filters};
use crate::engine::visitor_provider::VisitorProvider;
use crate::rule::{RuleId, RuleV2};
use crate::rule_provider::RuleV2Provider;
const CAPACITY: usize = 16;
pub(crate) struct RuleSetup {
pub(crate) editor_config: EditorConfig,
pub(crate) rule_providers: Vec<RuleV2Provider>,
pub(crate) visitor_provider: VisitorProvider,
rule_editor_configs: Mutex<HashMap<RuleId, Arc<EditorConfig>>>,
}
impl RuleSetup {
pub(crate) fn rule_editor_config(&self, rule: &dyn RuleV2) -> Arc<EditorConfig> {
if let Some(cached) = self.rule_editor_configs.lock().unwrap().get(&rule.rule_id()) {
return cached.clone();
}
let built = Arc::new(rule_editor_config(&self.editor_config, &self.rule_providers, rule));
self.rule_editor_configs.lock().unwrap().insert(rule.rule_id(), built.clone());
built
}
}
#[derive(Default)]
pub(crate) struct RuleSetupCache {
entries: Mutex<Vec<Arc<RuleSetup>>>,
}
impl RuleSetupCache {
pub(crate) fn get(&self, editor_config: EditorConfig, engine_rule_providers: &[RuleV2Provider]) -> Arc<RuleSetup> {
if let Some(hit) = self.entries.lock().unwrap().iter().find(|s| s.editor_config == editor_config) {
return hit.clone();
}
let rule_providers = apply_rule_filters(
engine_rule_providers,
&[
&InternalRuleProvidersFilter::new(engine_rule_providers),
&RuleExecutionRuleFilter::new(&editor_config),
],
);
let setup = Arc::new(RuleSetup {
visitor_provider: VisitorProvider::new(&rule_providers),
editor_config,
rule_providers,
rule_editor_configs: Mutex::default(),
});
let mut entries = self.entries.lock().unwrap();
if entries.len() == CAPACITY {
entries.remove(0);
}
entries.push(setup.clone());
setup
}
}