blob: eb5978cc8903d5d66afe43f199d0b60647046984 [file]
use std::sync::atomic::Ordering;
use crate::streaming::partitions::partition::Partition;
use crate::streaming::partitions::COMPONENT;
use crate::streaming::segments::*;
use error_set::ErrContext;
use iggy::error::IggyError;
use iggy::utils::timestamp::IggyTimestamp;
use tracing::info;
pub struct DeletedSegment {
pub end_offset: u64,
pub messages_count: u64,
}
impl Partition {
pub fn get_segments_count(&self) -> u32 {
self.segments.len() as u32
}
pub fn get_segments(&self) -> &Vec<Segment> {
&self.segments
}
pub fn get_segments_mut(&mut self) -> &mut Vec<Segment> {
&mut self.segments
}
pub fn get_segment(&self, start_offset: u64) -> Option<&Segment> {
self.segments
.iter()
.find(|s| s.start_offset == start_offset)
}
pub fn get_segment_mut(&mut self, start_offset: u64) -> Option<&mut Segment> {
self.segments
.iter_mut()
.find(|s| s.start_offset == start_offset)
}
pub async fn get_expired_segments_start_offsets(&self, now: IggyTimestamp) -> Vec<u64> {
let mut expired_segments = Vec::new();
for segment in &self.segments {
if segment.is_expired(now).await {
expired_segments.push(segment.start_offset);
}
}
expired_segments.sort();
expired_segments
}
pub async fn add_persisted_segment(&mut self, start_offset: u64) -> Result<(), IggyError> {
info!(
"Creating the new segment for partition with ID: {}, stream with ID: {}, topic with ID: {}...",
self.partition_id, self.stream_id, self.topic_id
);
let mut new_segment = Segment::create(
self.stream_id,
self.topic_id,
self.partition_id,
start_offset,
self.config.clone(),
self.message_expiry,
self.size_of_parent_stream.clone(),
self.size_of_parent_topic.clone(),
self.size_bytes.clone(),
self.messages_count_of_parent_stream.clone(),
self.messages_count_of_parent_topic.clone(),
self.messages_count.clone(),
);
new_segment.persist().await.with_error_context(|error| {
format!("{COMPONENT} (error: {error}) - failed to persist new segment: {new_segment}",)
})?;
self.segments.push(new_segment);
self.segments_count_of_parent_stream
.fetch_add(1, Ordering::SeqCst);
self.segments
.sort_by(|a, b| a.start_offset.cmp(&b.start_offset));
Ok(())
}
pub async fn delete_segment(&mut self, start_offset: u64) -> Result<DeletedSegment, IggyError> {
let deleted_segment;
{
let segment = self.get_segment_mut(start_offset);
if segment.is_none() {
return Err(IggyError::SegmentNotFound);
}
let segment = segment.unwrap();
segment.delete().await.with_error_context(|error| {
format!("{COMPONENT} (error: {error}) - failed to delete segment: {segment}",)
})?;
deleted_segment = DeletedSegment {
end_offset: segment.end_offset,
messages_count: segment.get_messages_count(),
};
}
self.segments_count_of_parent_stream
.fetch_sub(1, Ordering::SeqCst);
self.segments.retain(|s| s.start_offset != start_offset);
self.segments
.sort_by(|a, b| a.start_offset.cmp(&b.start_offset));
info!(
"Segment with start offset: {} has been deleted from partition with ID: {}, stream with ID: {}, topic with ID: {}",
start_offset, self.partition_id, self.stream_id, self.topic_id
);
Ok(deleted_segment)
}
}