Skip to main content

rat_quickdb/cache/
key_generator.rs

1
2//! 缓存键生成模块
3//!
4//! 提供各种缓存键的生成策略和实现
5
6use crate::types::{
7    CacheConfig, DataValue, IdType, QueryCondition, QueryConditionGroup, QueryConditionGroupWithConfig, QueryConditionWithConfig, QueryOptions,
8    SortDirection,
9};
10use rat_logger::debug;
11use std::vec::Vec;
12
13// 从 cache_manager.rs 中引入 CACHE_KEY_PREFIX 和 CacheManager
14use super::cache_manager::{CACHE_KEY_PREFIX, CacheManager};
15
16impl CacheManager {
17    /// 生成缓存键
18    pub(crate) fn generate_cache_key(&self, table: &str, id: &IdType, operation: &str) -> String {
19        let id_str = match id {
20            IdType::Number(n) => n.to_string(),
21            IdType::String(s) => s.clone(),
22        };
23        format!("{}:{}:{}:{}", CACHE_KEY_PREFIX, table, operation, id_str)
24    }
25
26    /// 生成查询缓存键 - 优化版本,避免复杂序列化
27    pub fn generate_query_cache_key(
28        &self,
29        table: &str,
30        conditions: &[QueryConditionWithConfig],
31        options: &QueryOptions,
32    ) -> String {
33        let query_signature = self.build_query_signature(options);
34        let conditions_signature = self.build_conditions_signature(conditions);
35        // 添加版本标识避免脏数据问题
36        let key = format!(
37            "{}:{}:query:{}:{}:{}",
38            CACHE_KEY_PREFIX, table, conditions_signature, query_signature, self.config.version
39        );
40        debug!("生成查询缓存键: table={}, key={}", table, key);
41        key
42    }
43
44    /// 生成条件组合查询缓存键(完整版)
45    pub fn generate_condition_groups_with_config_cache_key(
46        &self,
47        table: &str,
48        condition_groups: &[QueryConditionGroupWithConfig],
49        options: &QueryOptions,
50    ) -> String {
51        let query_signature = self.build_query_signature(options);
52        let groups_signature = self.build_condition_groups_with_config_signature(condition_groups);
53        let key = format!(
54            "{}:{}:groups:{}:{}",
55            CACHE_KEY_PREFIX, table, groups_signature, query_signature
56        );
57        debug!("生成条件组合查询缓存键(完整版): table={}, key={}", table, key);
58        key
59    }
60
61    /// 生成条件组合查询缓存键
62    pub fn generate_condition_groups_cache_key(
63        &self,
64        table: &str,
65        condition_groups: &[QueryConditionGroup],
66        options: &QueryOptions,
67    ) -> String {
68        let query_signature = self.build_query_signature(options);
69        let groups_signature = self.build_condition_groups_signature(condition_groups);
70        let key = format!(
71            "{}:{}:groups:{}:{}",
72            CACHE_KEY_PREFIX, table, groups_signature, query_signature
73        );
74        debug!("生成条件组合查询缓存键: table={}, key={}", table, key);
75        key
76    }
77
78    /// 构建查询签名 - 高效版本,避免JSON序列化
79    fn build_query_signature(&self, options: &QueryOptions) -> String {
80        let mut parts = Vec::new();
81
82        // 分页信息
83        if let Some(pagination) = &options.pagination {
84            parts.push(format!("p{}_{}", pagination.skip, pagination.limit));
85        }
86
87        // 排序信息
88        if !options.sort.is_empty() {
89            let sort_str = options
90                .sort
91                .iter()
92                .map(|s| {
93                    format!(
94                        "{}{}",
95                        s.field,
96                        match s.direction {
97                            SortDirection::Asc => "a",
98                            SortDirection::Desc => "d",
99                        }
100                    )
101                })
102                .collect::<Vec<_>>()
103                .join(",");
104            parts.push(format!("s{}", sort_str));
105        }
106
107        // 投影信息
108        if !options.fields.is_empty() {
109            let proj_str = options.fields.join(",");
110            parts.push(format!("f{}", proj_str));
111        }
112
113        // 连接部分生成最终签名
114        if parts.is_empty() {
115            "default".to_string()
116        } else {
117            parts.join("_")
118        }
119    }
120
121    /// 构建条件签名
122    fn build_conditions_signature(&self, conditions: &[QueryConditionWithConfig]) -> String {
123        if conditions.is_empty() {
124            return "no_cond".to_string();
125        }
126
127        let mut signature = String::new();
128        for (i, condition) in conditions.iter().enumerate() {
129            if i > 0 {
130                signature.push('_');
131            }
132            signature.push_str(&format!(
133                "{}{:?}{}",
134                condition.field,
135                condition.operator,
136                match &condition.value {
137                    DataValue::String(s) => s.clone(), // 修复:不截断字符串,使用完整值
138                    DataValue::Int(n) => n.to_string(),
139                    DataValue::Float(f) => f.to_string(),
140                    DataValue::Bool(b) => b.to_string(),
141                    _ => "val".to_string(),
142                }
143            ));
144        }
145        signature
146    }
147
148    /// 构建条件组合签名(完整版)
149    fn build_condition_groups_with_config_signature(&self, condition_groups: &[QueryConditionGroupWithConfig]) -> String {
150        if condition_groups.is_empty() {
151            return "no_groups".to_string();
152        }
153
154        let mut signature = String::new();
155        for (i, group) in condition_groups.iter().enumerate() {
156            if i > 0 {
157                signature.push('_');
158            }
159            match group {
160                QueryConditionGroupWithConfig::Single(condition) => {
161                    signature.push_str(&format!(
162                        "s{}{:?}{}{}",
163                        condition.field,
164                        condition.operator,
165                        if condition.case_insensitive { "ci" } else { "cs" },
166                        match &condition.value {
167                            DataValue::String(s) => s.clone(),
168                            DataValue::Int(n) => n.to_string(),
169                            DataValue::Float(f) => f.to_string(),
170                            DataValue::Bool(b) => b.to_string(),
171                            _ => "val".to_string(),
172                        }
173                    ));
174                }
175                QueryConditionGroupWithConfig::GroupWithConfig {
176                    conditions,
177                    operator,
178                } => {
179                    signature.push_str(&format!("g{:?}_", operator));
180                    for (j, condition) in conditions.iter().enumerate() {
181                        if j > 0 {
182                            signature.push('|');
183                        }
184                        match condition {
185                            QueryConditionGroupWithConfig::Single(cond) => {
186                                signature.push_str(&format!(
187                                    "{}{:?}{}{}",
188                                    cond.field,
189                                    cond.operator,
190                                    if cond.case_insensitive { "ci" } else { "cs" },
191                                    match &cond.value {
192                                        DataValue::String(s) => s.clone(),
193                                        DataValue::Int(n) => n.to_string(),
194                                        DataValue::Float(f) => f.to_string(),
195                                        DataValue::Bool(b) => b.to_string(),
196                                        _ => "val".to_string(),
197                                    }
198                                ));
199                            }
200                            QueryConditionGroupWithConfig::GroupWithConfig { .. } => {
201                                signature.push_str("nested");
202                            }
203                        }
204                    }
205                }
206            }
207        }
208        signature
209    }
210
211    /// 构建条件组合签名
212    fn build_condition_groups_signature(&self, condition_groups: &[QueryConditionGroup]) -> String {
213        if condition_groups.is_empty() {
214            return "no_groups".to_string();
215        }
216
217        let mut signature = String::new();
218        for (i, group) in condition_groups.iter().enumerate() {
219            if i > 0 {
220                signature.push('_');
221            }
222            match group {
223                QueryConditionGroup::Single(condition) => {
224                    signature.push_str(&format!(
225                        "s{}{:?}{}",
226                        condition.field,
227                        condition.operator,
228                        match &condition.value {
229                            DataValue::String(s) => s.clone(), // 修复:不截断字符串,使用完整值
230                            DataValue::Int(n) => n.to_string(),
231                            DataValue::Float(f) => f.to_string(),
232                            DataValue::Bool(b) => b.to_string(),
233                            _ => "val".to_string(),
234                        }
235                    ));
236                }
237                QueryConditionGroup::Group {
238                    conditions,
239                    operator,
240                } => {
241                    signature.push_str(&format!("g{:?}_", operator));
242                    for (j, condition) in conditions.iter().enumerate() {
243                        if j > 0 {
244                            signature.push('|');
245                        }
246                        match condition {
247                            QueryConditionGroup::Single(cond) => {
248                                signature.push_str(&format!(
249                                    "{}{:?}{}",
250                                    cond.field,
251                                    cond.operator,
252                                    match &cond.value {
253                                        DataValue::String(s) => s.clone(),
254                                        DataValue::Int(n) => n.to_string(),
255                                        DataValue::Float(f) => f.to_string(),
256                                        DataValue::Bool(b) => b.to_string(),
257                                        _ => "val".to_string(),
258                                    }
259                                ));
260                            }
261                            QueryConditionGroup::Group { .. } => {
262                                // 递归处理嵌套组合(简化处理)
263                                signature.push_str("nested");
264                            }
265                        }
266                    }
267                }
268            }
269        }
270        signature
271    }
272}