#[cfg(feature = "write-support")]
use crate::storage::write_engine::mutation::{ClusteringKey, DecoratedKey, RangeTombstone};
#[cfg(feature = "write-support")]
use crate::types::Value;
#[cfg(feature = "write-support")]
use std::cmp::Ordering;
#[cfg(feature = "write-support")]
use std::path::PathBuf;
#[cfg(feature = "write-support")]
use std::time::Duration;
#[cfg(feature = "write-support")]
#[derive(Debug, PartialEq, Eq)]
pub struct MergeEntry {
pub run_index: usize,
pub key: DecoratedKey,
pub clustering_key: Option<ClusteringKey>,
pub timestamp: i64,
pub row_data: RowData,
pub complex_deletions: Vec<ComplexDeletion>,
pub range_deletion: Option<RangeTombstone>,
pub row_deletion: Option<(i64, i32)>,
pub partition_deletion: Option<(i64, i32)>,
}
#[cfg(feature = "write-support")]
impl Clone for MergeEntry {
fn clone(&self) -> Self {
#[cfg(test)]
crate::storage::sstable::work_counters::merge_entry_clone_scope::record();
Self {
run_index: self.run_index,
key: self.key.clone(),
clustering_key: self.clustering_key.clone(),
timestamp: self.timestamp,
row_data: self.row_data.clone(),
complex_deletions: self.complex_deletions.clone(),
range_deletion: self.range_deletion.clone(),
row_deletion: self.row_deletion,
partition_deletion: self.partition_deletion,
}
}
}
impl MergeEntry {
pub fn new(
run_index: usize,
key: DecoratedKey,
clustering_key: Option<ClusteringKey>,
timestamp: i64,
row_data: RowData,
) -> Self {
Self {
run_index,
key,
clustering_key,
timestamp,
row_data,
complex_deletions: Vec::new(),
range_deletion: None,
row_deletion: None,
partition_deletion: None,
}
}
#[must_use]
pub fn with_complex_deletions(mut self, complex_deletions: Vec<ComplexDeletion>) -> Self {
self.complex_deletions = complex_deletions;
self
}
#[must_use]
pub fn with_row_deletion(mut self, deletion_time: i64, ldt: i32) -> Self {
self.row_deletion = Some((deletion_time, ldt));
self
}
#[must_use]
pub fn with_range_deletion(mut self, range_deletion: RangeTombstone) -> Self {
self.range_deletion = Some(range_deletion);
self
}
#[must_use]
pub fn with_partition_deletion(mut self, partition_deletion: (i64, i32)) -> Self {
self.partition_deletion = Some(partition_deletion);
self
}
#[must_use]
pub fn is_metadata_only_no_op(&self) -> bool {
matches!(&self.row_data, RowData::Live { cells } if cells.is_empty())
&& self.complex_deletions.is_empty()
&& self.range_deletion.is_none()
&& self.row_deletion.is_none()
&& self.partition_deletion.is_none()
}
#[must_use]
pub fn is_partition_delete_carrier(&self) -> bool {
self.partition_deletion.is_some()
}
}
#[cfg(feature = "write-support")]
impl Ord for MergeEntry {
fn cmp(&self, other: &Self) -> Ordering {
match self.key.token.cmp(&other.key.token) {
Ordering::Equal => {
match self.key.key.cmp(&other.key.key) {
Ordering::Equal => {
match (&self.clustering_key, &other.clustering_key) {
(None, None) => {
self.run_index.cmp(&other.run_index)
}
(None, Some(_)) => Ordering::Less,
(Some(_), None) => Ordering::Greater,
(Some(a), Some(b)) => {
match a.cmp(b) {
Ordering::Equal => {
self.run_index.cmp(&other.run_index)
}
other_ord => other_ord,
}
}
}
}
other_ord => other_ord,
}
}
other_ord => other_ord,
}
}
}
#[cfg(feature = "write-support")]
impl PartialOrd for MergeEntry {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(feature = "write-support")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RowData {
Live {
cells: Vec<CellData>,
},
Tombstone {
deletion_time: i64,
local_deletion_time: i32,
},
}
#[cfg(feature = "write-support")]
#[derive(Debug, PartialEq, Eq)]
pub struct CellData {
pub column: String,
pub value: Value,
pub timestamp: i64,
pub ttl: Option<u32>,
pub cell_path: Option<Vec<u8>>,
pub local_deletion_time: Option<i32>,
pub is_complex_element: bool,
pub is_deleted: bool,
pub has_empty_value: bool,
}
#[cfg(feature = "write-support")]
impl Clone for CellData {
fn clone(&self) -> Self {
#[cfg(test)]
crate::storage::sstable::work_counters::cell_data_clone_scope::record();
Self {
column: self.column.clone(),
value: self.value.clone(),
timestamp: self.timestamp,
ttl: self.ttl,
cell_path: self.cell_path.clone(),
local_deletion_time: self.local_deletion_time,
is_complex_element: self.is_complex_element,
is_deleted: self.is_deleted,
has_empty_value: self.has_empty_value,
}
}
}
#[cfg(feature = "write-support")]
impl CellData {
pub fn new(column: String, value: Value, timestamp: i64) -> Self {
Self {
column,
value,
timestamp,
ttl: None,
cell_path: None,
local_deletion_time: None,
is_complex_element: false,
is_deleted: false,
has_empty_value: false,
}
}
}
#[cfg(feature = "write-support")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ComplexDeletion {
pub column: String,
pub marked_for_delete_at: i64,
pub local_deletion_time: i32,
}
#[cfg(feature = "write-support")]
#[derive(Debug)]
pub enum MergeStep {
Partition {
key: DecoratedKey,
rows: Vec<MergeEntry>,
},
Complete,
}
#[cfg(feature = "write-support")]
#[derive(Debug, Clone)]
pub struct MergeStats {
pub input_files: usize,
pub output_partitions: u64,
pub output_rows: u64,
pub bytes_written: u64,
pub elapsed: Duration,
pub dropped_whole: Vec<PathBuf>,
}