meta_srv/procedure/repartition/plan.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
15use partition::expr::PartitionExpr;
16use serde::{Deserialize, Serialize};
17use store_api::storage::RegionId;
18
19use crate::procedure::repartition::group::GroupId;
20
21/// Metadata describing a region involved in the plan.
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
23pub struct RegionDescriptor {
24 /// The region id of the region involved in the plan.
25 pub region_id: RegionId,
26 /// The partition expression of the region.
27 pub partition_expr: PartitionExpr,
28}
29
30/// A plan entry for the region allocation phase, describing source regions
31/// and target partition expressions before allocation.
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
33pub struct AllocationPlanEntry {
34 /// The group id for this plan entry.
35 pub group_id: GroupId,
36 /// Source region descriptors involved in the plan.
37 pub source_regions: Vec<RegionDescriptor>,
38 /// The target partition expressions for the new or changed regions.
39 pub target_partition_exprs: Vec<PartitionExpr>,
40 /// The number of regions that need to be allocated (target count - source count, if positive).
41 pub regions_to_allocate: usize,
42 /// The number of regions that need to be deallocated (source count - target count, if positive).
43 pub regions_to_deallocate: usize,
44}
45
46/// A plan entry for the dispatch phase after region allocation,
47/// with concrete source and target region descriptors.
48#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49pub struct RepartitionPlanEntry {
50 /// The group id for this plan entry.
51 pub group_id: GroupId,
52 /// The source region descriptors involved in the plan.
53 pub source_regions: Vec<RegionDescriptor>,
54 /// The target region descriptors involved in the plan.
55 pub target_regions: Vec<RegionDescriptor>,
56 /// The region ids of the allocated regions.
57 pub allocated_region_ids: Vec<RegionId>,
58 /// The region ids of the regions that are pending deallocation.
59 pub pending_deallocate_region_ids: Vec<RegionId>,
60}
61
62impl RepartitionPlanEntry {
63 /// Converts an allocation plan entry into a repartition plan entry.
64 ///
65 /// The target regions are derived from the source regions and the target partition expressions.
66 /// The allocated region ids and pending deallocate region ids are empty.
67 pub fn from_allocation_plan_entry(
68 AllocationPlanEntry {
69 group_id,
70 source_regions,
71 target_partition_exprs,
72 regions_to_allocate,
73 regions_to_deallocate,
74 }: &AllocationPlanEntry,
75 ) -> Self {
76 debug_assert!(*regions_to_allocate == 0 && *regions_to_deallocate == 0);
77 let target_regions = source_regions
78 .iter()
79 .zip(target_partition_exprs.iter())
80 .map(|(source_region, target_partition_expr)| RegionDescriptor {
81 region_id: source_region.region_id,
82 partition_expr: target_partition_expr.clone(),
83 })
84 .collect::<Vec<_>>();
85
86 Self {
87 group_id: *group_id,
88 source_regions: source_regions.clone(),
89 target_regions,
90 allocated_region_ids: vec![],
91 pending_deallocate_region_ids: vec![],
92 }
93 }
94}