tdm_server_rust/db/
shard.rs1use crate::db::DbConn;
14
15pub const EDITOR_UNIT_PARTITIONS: u32 = 8;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct ShardKey {
23 pub manga_id: Option<i32>,
25 pub episode_id: i32,
27}
28
29impl ShardKey {
30 pub fn from_episode(episode_id: i32) -> Self {
32 Self {
33 manga_id: None,
34 episode_id,
35 }
36 }
37
38 pub fn partition(&self, partitions: u32) -> u32 {
42 let v = self.episode_id as i64;
45 (v.rem_euclid(partitions as i64)) as u32
46 }
47}
48
49#[derive(Clone)]
54pub struct ShardRouter {
55 primary: DbConn,
57}
58
59impl ShardRouter {
60 pub fn single(primary: DbConn) -> Self {
62 Self { primary }
63 }
64
65 pub fn conn_for(&self, _key: ShardKey) -> &DbConn {
67 &self.primary
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
77 fn same_episode_routes_to_same_partition() {
78 let first = ShardKey::from_episode(123_456).partition(EDITOR_UNIT_PARTITIONS);
79 let second = ShardKey::from_episode(123_456).partition(EDITOR_UNIT_PARTITIONS);
80 assert_eq!(first, second);
81 assert!(first < EDITOR_UNIT_PARTITIONS);
82 }
83
84 #[test]
86 fn partition_always_in_range() {
87 for id in [-7, -1, 0, 1, 7, 8, i32::MAX] {
88 let p = ShardKey::from_episode(id).partition(EDITOR_UNIT_PARTITIONS);
89 assert!(
90 p < EDITOR_UNIT_PARTITIONS,
91 "episode_id={id} 越界 partition={p}"
92 );
93 }
94 }
95}