metric_engine/engine/
region_metadata.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
15//! Implementation of retrieving logical region's region metadata.
16
17use std::collections::HashMap;
18
19use store_api::metadata::ColumnMetadata;
20use store_api::storage::RegionId;
21
22use crate::engine::MetricEngineInner;
23use crate::error::Result;
24
25impl MetricEngineInner {
26    /// Load column metadata of a logical region.
27    ///
28    /// The return value is ordered on column name.
29    pub async fn load_logical_columns(
30        &self,
31        physical_region_id: RegionId,
32        logical_region_id: RegionId,
33    ) -> Result<Vec<ColumnMetadata>> {
34        // First try to load from state cache
35        if let Some(columns) = self
36            .state
37            .read()
38            .unwrap()
39            .logical_columns()
40            .get(&logical_region_id)
41        {
42            return Ok(columns.clone());
43        }
44
45        // Else load from metadata region and update the cache.
46        let _read_guard = self
47            .metadata_region
48            .read_lock_logical_region(logical_region_id)
49            .await?;
50        // Load logical and physical columns, and intersect them to get logical column metadata.
51        let logical_column_metadata = self
52            .metadata_region
53            .logical_columns(physical_region_id, logical_region_id)
54            .await?
55            .into_iter()
56            .map(|(_, column_metadata)| column_metadata)
57            .collect::<Vec<_>>();
58
59        // Update cache
60        let mut mutable_state = self.state.write().unwrap();
61        // Merge with existing cached columns.
62        let existing_columns = mutable_state
63            .logical_columns()
64            .get(&logical_region_id)
65            .cloned()
66            .unwrap_or_default()
67            .into_iter();
68        let mut dedup_columns = logical_column_metadata
69            .into_iter()
70            .chain(existing_columns)
71            .map(|c| (c.column_id, c))
72            .collect::<HashMap<_, _>>()
73            .values()
74            .cloned()
75            .collect::<Vec<_>>();
76        // Sort columns on column name to ensure the order
77        dedup_columns.sort_unstable_by(|c1, c2| c1.column_schema.name.cmp(&c2.column_schema.name));
78        mutable_state.set_logical_columns(logical_region_id, dedup_columns.clone());
79
80        Ok(dedup_columns)
81    }
82
83    /// Load logical column names of a logical region.
84    ///
85    /// The return value is ordered on column name alphabetically.
86    pub async fn load_logical_column_names(
87        &self,
88        physical_region_id: RegionId,
89        logical_region_id: RegionId,
90    ) -> Result<Vec<String>> {
91        // First try to load from state cache
92        if let Some(columns) = self
93            .state
94            .read()
95            .unwrap()
96            .logical_columns()
97            .get(&logical_region_id)
98        {
99            return Ok(columns
100                .iter()
101                .map(|c| c.column_schema.name.clone())
102                .collect());
103        }
104
105        // Else load from metadata region
106        let columns = self
107            .load_logical_columns(physical_region_id, logical_region_id)
108            .await?
109            .into_iter()
110            .map(|c| c.column_schema.name)
111            .collect::<Vec<_>>();
112
113        Ok(columns)
114    }
115}