use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Clone, Debug)]
pub struct RebalanceOptions {
pub background: bool,
pub batch_size: usize,
pub max_pause_ns: u64,
}
impl Default for RebalanceOptions {
fn default() -> Self {
Self {
background: false,
batch_size: 1024,
max_pause_ns: 0,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RebalanceReport {
pub from_shards: usize,
pub to_shards: usize,
pub moved_entries: usize,
pub elapsed_ms: u128,
}
#[derive(Clone, Debug, PartialEq)]
pub struct RebalanceStatus {
pub state: &'static str,
pub progress: f64,
pub moved_shards: usize,
pub total_shards: usize,
}
pub(crate) const REBALANCE_STATE_IDLE: usize = 0;
pub(crate) const REBALANCE_STATE_MIGRATING: usize = 1;
#[derive(Debug)]
pub(crate) struct RebalanceTracker {
state: AtomicUsize,
moved_shards: AtomicUsize,
total_shards: AtomicUsize,
}
impl RebalanceTracker {
pub(crate) fn new() -> Self {
Self {
state: AtomicUsize::new(REBALANCE_STATE_IDLE),
moved_shards: AtomicUsize::new(0),
total_shards: AtomicUsize::new(0),
}
}
pub(crate) fn begin(&self, total_shards: usize) {
self.total_shards.store(total_shards, Ordering::Relaxed);
self.moved_shards.store(0, Ordering::Relaxed);
self.state
.store(REBALANCE_STATE_MIGRATING, Ordering::Relaxed);
}
pub(crate) fn step(&self) {
self.moved_shards.fetch_add(1, Ordering::Relaxed);
}
pub(crate) fn is_migrating(&self) -> bool {
self.state.load(Ordering::Relaxed) == REBALANCE_STATE_MIGRATING
}
pub(crate) fn finish(&self) {
self.state.store(REBALANCE_STATE_IDLE, Ordering::Relaxed);
self.total_shards.store(0, Ordering::Relaxed);
self.moved_shards.store(0, Ordering::Relaxed);
}
pub(crate) fn snapshot(&self) -> RebalanceStatus {
let state_num = self.state.load(Ordering::Relaxed);
let moved = self.moved_shards.load(Ordering::Relaxed);
let total = self.total_shards.load(Ordering::Relaxed);
let progress = if total == 0 {
0.0
} else {
moved as f64 / total as f64
};
RebalanceStatus {
state: if state_num == REBALANCE_STATE_MIGRATING {
"migrating"
} else {
"idle"
},
progress,
moved_shards: moved,
total_shards: total,
}
}
}