Skip to main content

cache/
lib.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15pub mod error;
16
17use std::hash::Hash;
18use std::sync::Arc;
19use std::time::Duration;
20
21use catalog::kvbackend::new_table_cache;
22use common_meta::cache::{
23    CacheRegistry, CacheRegistryBuilder, LayeredCacheRegistry, LayeredCacheRegistryBuilder,
24    new_schema_cache, new_table_flownode_set_cache, new_table_info_cache, new_table_name_cache,
25    new_table_route_cache, new_table_schema_cache, new_view_info_cache,
26};
27use common_meta::kv_backend::KvBackendRef;
28use moka::future::{Cache, CacheBuilder};
29use partition::cache::new_partition_info_cache;
30use snafu::OptionExt;
31
32use crate::error::Result;
33
34const DEFAULT_CACHE_MAX_CAPACITY: u64 = 65536;
35const DEFAULT_CACHE_TTL: Duration = Duration::from_secs(10 * 60);
36const DEFAULT_CACHE_TTI: Duration = Duration::from_secs(5 * 60);
37
38fn default_cache<K: Send + Sync + Hash + Eq + 'static, V: Send + Sync + Clone + 'static>()
39-> Cache<K, V> {
40    CacheBuilder::new(DEFAULT_CACHE_MAX_CAPACITY)
41        .time_to_live(DEFAULT_CACHE_TTL)
42        .time_to_idle(DEFAULT_CACHE_TTI)
43        .build()
44}
45
46pub const TABLE_INFO_CACHE_NAME: &str = "table_info_cache";
47pub const VIEW_INFO_CACHE_NAME: &str = "view_info_cache";
48pub const TABLE_NAME_CACHE_NAME: &str = "table_name_cache";
49pub const TABLE_CACHE_NAME: &str = "table_cache";
50pub const SCHEMA_CACHE_NAME: &str = "schema_cache";
51pub const TABLE_SCHEMA_NAME_CACHE_NAME: &str = "table_schema_name_cache";
52pub const TABLE_FLOWNODE_SET_CACHE_NAME: &str = "table_flownode_set_cache";
53pub const TABLE_ROUTE_CACHE_NAME: &str = "table_route_cache";
54pub const PARTITION_INFO_CACHE_NAME: &str = "partition_info_cache";
55
56/// Builds the datanode cache registry with base metadata caches before derived caches.
57///
58/// Invalidating the base layer first prevents a concurrent query from refilling a derived cache
59/// from stale metadata after that derived cache has been invalidated.
60pub fn build_datanode_layered_cache_registry(kv_backend: KvBackendRef) -> LayeredCacheRegistry {
61    let cache = CacheBuilder::new(DEFAULT_CACHE_MAX_CAPACITY).build();
62    let table_id_schema_cache = Arc::new(new_table_schema_cache(
63        TABLE_SCHEMA_NAME_CACHE_NAME.to_string(),
64        cache,
65        kv_backend.clone(),
66    ));
67
68    let cache = default_cache();
69    let schema_cache = Arc::new(new_schema_cache(
70        SCHEMA_CACHE_NAME.to_string(),
71        cache,
72        kv_backend.clone(),
73    ));
74
75    let cache = default_cache();
76    let table_info_cache = Arc::new(new_table_info_cache(
77        TABLE_INFO_CACHE_NAME.to_string(),
78        cache,
79        kv_backend.clone(),
80    ));
81
82    let cache = default_cache();
83    let table_name_cache = Arc::new(new_table_name_cache(
84        TABLE_NAME_CACHE_NAME.to_string(),
85        cache,
86        kv_backend.clone(),
87    ));
88
89    let cache = default_cache();
90    let table_route_cache = Arc::new(new_table_route_cache(
91        TABLE_ROUTE_CACHE_NAME.to_string(),
92        cache,
93        kv_backend.clone(),
94    ));
95
96    let cache = default_cache();
97    let table_cache = Arc::new(new_table_cache(
98        TABLE_CACHE_NAME.to_string(),
99        cache,
100        table_info_cache.clone(),
101        table_name_cache.clone(),
102    ));
103
104    let cache = default_cache();
105    let partition_info_cache = Arc::new(new_partition_info_cache(
106        PARTITION_INFO_CACHE_NAME.to_string(),
107        cache,
108        table_route_cache.clone(),
109    ));
110
111    let base_registry = CacheRegistryBuilder::default()
112        .add_cache(table_id_schema_cache)
113        .add_cache(schema_cache)
114        .add_cache(table_info_cache)
115        .add_cache(table_name_cache)
116        .add_cache(table_route_cache)
117        .build();
118    let derived_registry = CacheRegistryBuilder::default()
119        .add_cache(table_cache)
120        .add_cache(partition_info_cache)
121        .build();
122
123    LayeredCacheRegistryBuilder::default()
124        .add_cache_registry(base_registry)
125        .add_cache_registry(derived_registry)
126        .build()
127}
128
129/// Builds cache registry for frontend and datanode, including:
130/// - Table info cache
131/// - Table name cache
132/// - Table route cache
133/// - Table flow node cache
134/// - View cache
135/// - Schema cache
136pub fn build_fundamental_cache_registry(kv_backend: KvBackendRef) -> CacheRegistry {
137    // Builds table info cache
138    let cache = default_cache();
139    let table_info_cache = Arc::new(new_table_info_cache(
140        TABLE_INFO_CACHE_NAME.to_string(),
141        cache,
142        kv_backend.clone(),
143    ));
144
145    // Builds table name cache
146    let cache = default_cache();
147    let table_name_cache = Arc::new(new_table_name_cache(
148        TABLE_NAME_CACHE_NAME.to_string(),
149        cache,
150        kv_backend.clone(),
151    ));
152
153    // Builds table route cache
154    let cache = default_cache();
155    let table_route_cache = Arc::new(new_table_route_cache(
156        TABLE_ROUTE_CACHE_NAME.to_string(),
157        cache,
158        kv_backend.clone(),
159    ));
160
161    // Builds table flownode set cache
162    let cache = default_cache();
163    let table_flownode_set_cache = Arc::new(new_table_flownode_set_cache(
164        TABLE_FLOWNODE_SET_CACHE_NAME.to_string(),
165        cache,
166        kv_backend.clone(),
167    ));
168    // Builds the view info cache
169    let cache = default_cache();
170    let view_info_cache = Arc::new(new_view_info_cache(
171        VIEW_INFO_CACHE_NAME.to_string(),
172        cache,
173        kv_backend.clone(),
174    ));
175
176    // Builds schema cache
177    let cache = default_cache();
178    let schema_cache = Arc::new(new_schema_cache(
179        SCHEMA_CACHE_NAME.to_string(),
180        cache,
181        kv_backend.clone(),
182    ));
183
184    let table_id_schema_cache = Arc::new(new_table_schema_cache(
185        TABLE_SCHEMA_NAME_CACHE_NAME.to_string(),
186        CacheBuilder::new(DEFAULT_CACHE_MAX_CAPACITY).build(),
187        kv_backend,
188    ));
189    CacheRegistryBuilder::default()
190        .add_cache(table_info_cache)
191        .add_cache(table_name_cache)
192        .add_cache(table_route_cache)
193        .add_cache(view_info_cache)
194        .add_cache(table_flownode_set_cache)
195        .add_cache(schema_cache)
196        .add_cache(table_id_schema_cache)
197        .build()
198}
199
200// TODO(weny): Make the cache configurable.
201pub fn with_default_composite_cache_registry(
202    builder: LayeredCacheRegistryBuilder,
203) -> Result<LayeredCacheRegistryBuilder> {
204    let table_info_cache = builder.get().context(error::CacheRequiredSnafu {
205        name: TABLE_INFO_CACHE_NAME,
206    })?;
207    let table_name_cache = builder.get().context(error::CacheRequiredSnafu {
208        name: TABLE_NAME_CACHE_NAME,
209    })?;
210    let table_route_cache = builder.get().context(error::CacheRequiredSnafu {
211        name: TABLE_ROUTE_CACHE_NAME,
212    })?;
213
214    // Builds table cache
215    let cache = default_cache();
216    let table_cache = Arc::new(new_table_cache(
217        TABLE_CACHE_NAME.to_string(),
218        cache,
219        table_info_cache,
220        table_name_cache,
221    ));
222
223    let cache = default_cache();
224    let partition_info_cache = Arc::new(new_partition_info_cache(
225        PARTITION_INFO_CACHE_NAME.to_string(),
226        cache,
227        table_route_cache,
228    ));
229
230    let registry = CacheRegistryBuilder::default()
231        .add_cache(table_cache)
232        .add_cache(partition_info_cache)
233        .build();
234
235    Ok(builder.add_cache_registry(registry))
236}