use std::collections::VecDeque;
use super::{Frame, OwnedFrame};
const MAX_BACKUP_SIZE: usize = 256 * 1024 * 1024;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Backup {
max_backup_size: usize,
current_backup_size: usize,
frames: VecDeque<OwnedFrame>,
sent_cnt: u64,
received_cnt: u64,
frozen: bool,
}
impl Default for Backup {
fn default() -> Self {
Self::new()
}
}
impl Backup {
pub fn new() -> Self {
Self {
max_backup_size: MAX_BACKUP_SIZE,
current_backup_size: 0,
frames: VecDeque::new(),
sent_cnt: 0,
received_cnt: 0,
frozen: false,
}
}
pub fn clear(&mut self) {
if !self.frozen {
self.current_backup_size = 0;
self.frames.clear();
self.sent_cnt = 0;
self.received_cnt = 0;
}
}
#[inline]
pub fn is_frozen(&self) -> bool {
self.frozen
}
#[inline]
pub fn set_frozen(&mut self, frozen: bool) {
self.frozen = frozen;
}
#[inline]
pub fn freeze(&mut self) {
self.frozen = true;
}
#[inline]
pub fn unfreeze(&mut self) {
self.frozen = false;
}
pub fn set_max_backup_size(&mut self, size: usize) {
if !self.frozen {
self.max_backup_size = size;
}
}
pub fn max_backup_size(&self) -> usize {
self.max_backup_size
}
pub(crate) fn increment_sent_cnt(&mut self) {
if !self.frozen {
self.sent_cnt += 1;
}
}
pub(crate) fn sent_cnt(&self) -> u64 {
self.sent_cnt
}
pub(super) fn increment_received_cnt(&mut self) {
if !self.frozen {
self.received_cnt += 1;
}
}
pub(crate) fn received_cnt(&self) -> u64 {
self.received_cnt
}
pub(super) fn set_received_cnt(&mut self, cnt: u64) {
if !self.frozen {
self.received_cnt = cnt;
}
}
pub(crate) fn push_frame(&mut self, frame: Frame) {
if self.max_backup_size > 0 && !self.frozen {
self.current_backup_size += frame.len();
self.frames.push_back(frame.into_owned());
while self.current_backup_size > self.max_backup_size {
match self.frames.pop_front() {
Some(frame) => {
self.current_backup_size -= frame.len();
}
None => {
self.current_backup_size = 0;
break;
}
}
}
}
}
pub(super) fn frame_cnt(&self) -> usize {
self.frames.len()
}
pub(super) fn frames(&self) -> impl Iterator<Item = &Frame> {
self.frames.iter()
}
pub(super) fn truncate_front(&mut self, size: usize) {
if !self.frozen {
while self.frames.len() > size {
if let Some(frame) = self.frames.pop_front() {
self.current_backup_size -=
std::cmp::min(frame.len(), self.current_backup_size);
}
}
}
}
}