use crate::types::{AbsoluteOffset, ReservationId}; use crate::FailedReservationInfo; use bytes::Bytes; use std::collections::{BTreeMap, HashMap, HashSet};
#[derive(Debug)] pub struct GroupState {
pub total_size: usize,
pub reservations: HashSet<ReservationId>,
pub reservation_metadata: HashMap<ReservationId, (AbsoluteOffset, usize)>,
pub committed_data: BTreeMap<AbsoluteOffset, (ReservationId, usize, BTreeMap<usize, Bytes>)>,
pub failed_infos: Vec<FailedReservationInfo>,
pub is_sealed: bool,
}
impl GroupState {
pub fn new() -> Self {
GroupState {
total_size: 0, reservations: HashSet::new(), reservation_metadata: HashMap::new(), committed_data: BTreeMap::new(), failed_infos: Vec::new(), is_sealed: false, }
}
pub fn add_reservation(&mut self, res_id: ReservationId, offset: AbsoluteOffset, size: usize) {
self.reservations.insert(res_id);
self.reservation_metadata.insert(res_id, (offset, size));
self.total_size += size;
}
pub fn remove_pending_reservation(&mut self, res_id: ReservationId) -> bool {
self.reservations.remove(&res_id) }
pub fn get_reservation_metadata(
&self,
res_id: ReservationId,
) -> Option<(AbsoluteOffset, usize)> {
self.reservation_metadata.get(&res_id).cloned()
}
pub fn has_pending_reservation(&self, res_id: ReservationId) -> bool {
self.reservations.contains(&res_id)
}
pub fn add_committed_data(
&mut self,
offset: AbsoluteOffset, res_id: ReservationId,
size: usize,
chunks: BTreeMap<usize, Bytes>, ) {
self.committed_data.insert(offset, (res_id, size, chunks));
}
pub fn has_committed_data(&self, offset: AbsoluteOffset) -> bool {
self.committed_data.contains_key(&offset)
}
pub fn add_failed_info(&mut self, info: FailedReservationInfo) {
self.failed_infos.push(info);
}
pub fn should_seal(&self, min_size: usize) -> bool {
!self.is_sealed && self.total_size >= min_size
}
pub fn seal(&mut self) {
self.is_sealed = true;
}
pub fn is_complete(&self) -> bool {
self.is_sealed && self.reservations.is_empty()
}
pub fn is_empty(&self) -> bool {
self.reservations.is_empty() && self.committed_data.is_empty() && self.failed_infos.is_empty() && self.reservation_metadata.is_empty() }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_group_state_new() {
let group_state = GroupState::new();
assert_eq!(group_state.total_size, 0, "初始 total_size 应为 0");
assert!(group_state.reservations.is_empty(), "初始 reservations 应为空");
assert!(group_state.reservation_metadata.is_empty(), "初始 reservation_metadata 应为空");
assert!(group_state.committed_data.is_empty(), "初始 committed_data 应为空");
assert!(group_state.failed_infos.is_empty(), "初始 failed_infos 应为空");
assert!(!group_state.is_sealed, "初始 is_sealed 应为 false");
}
}