metric_engine/engine/
drop.rs1use snafu::ResultExt;
18use store_api::region_engine::RegionEngine;
19use store_api::region_request::{AffectedRows, RegionDropRequest, RegionRequest};
20use store_api::storage::RegionId;
21
22use crate::engine::MetricEngineInner;
23use crate::error::{
24 CloseMitoRegionSnafu, LogicalRegionNotFoundSnafu, PhysicalRegionBusySnafu, Result,
25};
26use crate::metrics::PHYSICAL_REGION_COUNT;
27use crate::utils;
28
29impl MetricEngineInner {
30 pub async fn drop_region(
31 &self,
32 region_id: RegionId,
33 req: RegionDropRequest,
34 ) -> Result<AffectedRows> {
35 let data_region_id = utils::to_data_region_id(region_id);
36 let fast_path = req.fast_path;
37
38 let (is_physical_region, is_physical_region_busy) = {
40 if let Some(state) = self
41 .state
42 .read()
43 .unwrap()
44 .physical_region_states()
45 .get(&data_region_id)
46 {
47 (true, !state.logical_regions().is_empty())
48 } else {
49 (false, true)
51 }
52 };
53
54 if is_physical_region {
55 if is_physical_region_busy && !fast_path {
57 return Err(PhysicalRegionBusySnafu {
59 region_id: data_region_id,
60 }
61 .build());
62 }
63
64 return self.drop_physical_region(data_region_id).await;
65 }
66
67 if fast_path {
68 self.state
73 .write()
74 .unwrap()
75 .remove_logical_region(region_id)?;
76
77 Ok(0)
78 } else {
79 let metadata_region_id = self
80 .state
81 .read()
82 .unwrap()
83 .logical_regions()
84 .get(®ion_id)
85 .copied();
86 if let Some(metadata_region_id) = metadata_region_id {
87 self.drop_logical_region(region_id, metadata_region_id)
88 .await
89 } else {
90 Err(LogicalRegionNotFoundSnafu { region_id }.build())
91 }
92 }
93 }
94
95 async fn drop_physical_region(&self, region_id: RegionId) -> Result<AffectedRows> {
96 let data_region_id = utils::to_data_region_id(region_id);
97 let metadata_region_id = utils::to_metadata_region_id(region_id);
98
99 self.mito
103 .handle_request(
104 data_region_id,
105 RegionRequest::Drop(RegionDropRequest { fast_path: false }),
106 )
107 .await
108 .with_context(|_| CloseMitoRegionSnafu { region_id })?;
109 self.mito
110 .handle_request(
111 metadata_region_id,
112 RegionRequest::Drop(RegionDropRequest { fast_path: false }),
113 )
114 .await
115 .with_context(|_| CloseMitoRegionSnafu { region_id })?;
116
117 PHYSICAL_REGION_COUNT.dec();
118
119 self.state
121 .write()
122 .unwrap()
123 .remove_physical_region(data_region_id)?;
124
125 Ok(0)
126 }
127
128 async fn drop_logical_region(
129 &self,
130 logical_region_id: RegionId,
131 physical_region_id: RegionId,
132 ) -> Result<AffectedRows> {
133 self.metadata_region
135 .remove_logical_region(physical_region_id, logical_region_id)
136 .await?;
137
138 self.state
140 .write()
141 .unwrap()
142 .remove_logical_region(logical_region_id)?;
143
144 Ok(0)
145 }
146}