mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-03 20:02:54 +00:00
feat: define region group and sequence (#2100)
* define region group Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * define region sequence Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * check partition number Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * fix clippy Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * test region seq and group Signed-off-by: Ruihang Xia <waynestxia@gmail.com> --------- Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
@@ -469,6 +469,9 @@ pub enum Error {
|
||||
source: SendError<Message>,
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[snafu(display("Too many partitions, location: {}", location))]
|
||||
TooManyPartitions { location: Location },
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -525,7 +528,8 @@ impl ErrorExt for Error {
|
||||
| Error::ParseNum { .. }
|
||||
| Error::UnsupportedSelectorType { .. }
|
||||
| Error::InvalidArguments { .. }
|
||||
| Error::InvalidHeartbeatRequest { .. } => StatusCode::InvalidArguments,
|
||||
| Error::InvalidHeartbeatRequest { .. }
|
||||
| Error::TooManyPartitions { .. } => StatusCode::InvalidArguments,
|
||||
Error::LeaseKeyFromUtf8 { .. }
|
||||
| Error::LeaseValueFromUtf8 { .. }
|
||||
| Error::StatKeyFromUtf8 { .. }
|
||||
|
||||
@@ -24,14 +24,15 @@ use common_meta::rpc::ddl::{
|
||||
use common_meta::rpc::router;
|
||||
use common_meta::table_name::TableName;
|
||||
use common_telemetry::{info, warn};
|
||||
use snafu::{OptionExt, ResultExt};
|
||||
use snafu::{ensure, OptionExt, ResultExt};
|
||||
use store_api::storage::MAX_REGION_SEQ;
|
||||
use table::metadata::RawTableInfo;
|
||||
use tonic::{Request, Response};
|
||||
|
||||
use super::store::kv::KvStoreRef;
|
||||
use super::GrpcResult;
|
||||
use crate::ddl::DdlManagerRef;
|
||||
use crate::error::{self, Result, TableMetadataManagerSnafu};
|
||||
use crate::error::{self, Result, TableMetadataManagerSnafu, TooManyPartitionsSnafu};
|
||||
use crate::metasrv::{MetaSrv, SelectorContext, SelectorRef};
|
||||
use crate::sequence::SequenceRef;
|
||||
use crate::table_routes::get_table_route_value;
|
||||
@@ -192,6 +193,10 @@ async fn handle_create_table_route(
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
ensure!(
|
||||
partitions.len() <= MAX_REGION_SEQ as usize,
|
||||
TooManyPartitionsSnafu
|
||||
);
|
||||
let region_routes = partitions
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
|
||||
@@ -19,16 +19,36 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::storage::{consts, ColumnDefaultConstraint, ColumnSchema, ConcreteDataType};
|
||||
|
||||
/// Id of column, unique in each region.
|
||||
/// Id of column. Unique in each region.
|
||||
pub type ColumnId = u32;
|
||||
/// Id of column family, unique in each region.
|
||||
/// Id of column family. Unique in each region.
|
||||
pub type ColumnFamilyId = u32;
|
||||
/// Sequence number of regions under the same table.
|
||||
/// Group number of one region. Unique in each region.
|
||||
pub type RegionGroup = u8;
|
||||
/// Sequence number of region inside one table. Unique in each table.
|
||||
/// The first 8 bits are preserved for [RegionGroup].
|
||||
pub type RegionSeq = u32;
|
||||
/// Id of regions under the same table. Unique in each table.
|
||||
/// Is composed by [RegionGroup] and [RegionSeq].
|
||||
pub type RegionNumber = u32;
|
||||
/// Id of table.
|
||||
/// Id of table. Universal unique.
|
||||
pub type TableId = u32;
|
||||
|
||||
/// Id of the region. It's generated by concatenating table id and region number.
|
||||
const REGION_GROUP_MASK: u32 = 0b1111_1111 << 24;
|
||||
const REGION_SEQ_MASK: u32 = (0b1 << 24) - 1;
|
||||
|
||||
/// The max valid region sequence number.
|
||||
pub const MAX_REGION_SEQ: u32 = REGION_SEQ_MASK;
|
||||
|
||||
/// Id of the region. It's generated by concatenating table id, region group and region number.
|
||||
///
|
||||
/// ```plaintext
|
||||
/// 63 31 23 0
|
||||
/// ┌────────────────────────────────────┬──────────┬──────────────────┐
|
||||
/// │ Table Id(32) │ Group(8) │ Sequence(24) │
|
||||
/// └────────────────────────────────────┴──────────┴──────────────────┘
|
||||
/// Region Number(32)
|
||||
/// ```
|
||||
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct RegionId(u64);
|
||||
|
||||
@@ -48,6 +68,16 @@ impl RegionId {
|
||||
self.0 as RegionNumber
|
||||
}
|
||||
|
||||
/// Returns the group number of the region
|
||||
pub const fn region_group(&self) -> RegionGroup {
|
||||
((self.region_number() & REGION_GROUP_MASK) >> 24) as RegionGroup
|
||||
}
|
||||
|
||||
/// Return the sequence number of the region
|
||||
pub const fn region_sequence(&self) -> RegionSeq {
|
||||
self.region_number() & REGION_SEQ_MASK
|
||||
}
|
||||
|
||||
/// Returns the region id as u64.
|
||||
pub const fn as_u64(&self) -> u64 {
|
||||
self.0
|
||||
@@ -57,6 +87,19 @@ impl RegionId {
|
||||
pub const fn from_u64(id: u64) -> RegionId {
|
||||
RegionId(id)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub const fn with_group_and_seq(
|
||||
table_id: TableId,
|
||||
group: RegionGroup,
|
||||
seq: RegionSeq,
|
||||
) -> RegionId {
|
||||
RegionId(
|
||||
((table_id as u64) << 32)
|
||||
| ((group as u32) << 24) as u64
|
||||
| (seq & REGION_SEQ_MASK) as u64,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for RegionId {
|
||||
@@ -411,4 +454,22 @@ mod tests {
|
||||
let parsed: RegionId = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(region_id, parsed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retrieve_region_group_and_seq() {
|
||||
let region_id = RegionId::with_group_and_seq(111, 222, 333);
|
||||
assert_eq!(111, region_id.table_id());
|
||||
assert_eq!(222, region_id.region_group());
|
||||
assert_eq!(333, region_id.region_sequence());
|
||||
|
||||
let expected_region_number = 222 << 24 | 333;
|
||||
assert_eq!(expected_region_number, region_id.region_number());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_large_region_sequence() {
|
||||
// region sequence larger than `MAX_REGION_SEQ` will be masked into valid range
|
||||
let region_id = RegionId::with_group_and_seq(111, 222, u32::MAX);
|
||||
assert_eq!(MAX_REGION_SEQ, region_id.region_sequence());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user