use super::estimator::CostEstimator;
use super::types::TableIndexInfo;
use crate::statistics::TableStatistics;
impl CostEstimator {
pub fn estimate_insert(
&self,
row_count: usize,
table_stats: &TableStatistics,
index_info: &TableIndexInfo,
) -> f64 {
let rows = row_count as f64;
let tuple_cost = rows * self.insert_tuple_cost;
let hash_index_cost =
rows * index_info.hash_index_count as f64 * self.hash_index_update_cost;
let btree_index_cost =
rows * index_info.btree_index_count as f64 * self.btree_index_update_cost;
let columnar_cost = if index_info.is_native_columnar {
table_stats.row_count as f64 * self.columnar_rebuild_cost
} else {
self.columnar_cache_invalidation_cost
};
let wal_size_factor = index_info.wal_size_factor();
let wal_cost = rows * self.wal_write_cost * wal_size_factor + self.wal_sync_cost;
tuple_cost + hash_index_cost + btree_index_cost + columnar_cost + wal_cost
}
pub fn estimate_update(
&self,
row_count: usize,
table_stats: &TableStatistics,
index_info: &TableIndexInfo,
indexes_affected_ratio: f64,
) -> f64 {
let rows = row_count as f64;
let tuple_cost = rows * self.update_tuple_cost;
let hash_index_cost = rows
* index_info.hash_index_count as f64
* self.hash_index_update_cost
* 2.0
* indexes_affected_ratio;
let btree_index_cost = rows
* index_info.btree_index_count as f64
* self.btree_index_update_cost
* 2.0
* indexes_affected_ratio;
let columnar_cost = if index_info.is_native_columnar {
table_stats.row_count as f64 * self.columnar_rebuild_cost
} else {
self.columnar_cache_invalidation_cost
};
let wal_size_factor = index_info.wal_size_factor();
let wal_cost = rows * self.wal_write_cost * wal_size_factor + self.wal_sync_cost;
tuple_cost + hash_index_cost + btree_index_cost + columnar_cost + wal_cost
}
pub fn estimate_delete(
&self,
row_count: usize,
table_stats: &TableStatistics,
index_info: &TableIndexInfo,
) -> f64 {
let rows = row_count as f64;
let total_rows = table_stats.row_count as f64;
let tuple_cost = rows * self.delete_tuple_cost;
let hash_index_cost =
rows * index_info.hash_index_count as f64 * self.hash_index_update_cost;
let btree_index_cost =
rows * index_info.btree_index_count as f64 * self.btree_index_update_cost;
let columnar_cost = if index_info.is_native_columnar {
(total_rows - rows).max(0.0) * self.columnar_rebuild_cost
} else {
self.columnar_cache_invalidation_cost
};
let current_deleted = total_rows * index_info.deleted_ratio;
let new_deleted = current_deleted + rows;
let new_deleted_ratio = if total_rows > 0.0 { new_deleted / total_rows } else { 0.0 };
let compaction_cost = if new_deleted_ratio > 0.5 {
let remaining_rows = (total_rows - new_deleted).max(0.0);
let rebuild_cost =
remaining_rows * self.cpu_tuple_cost * self.compaction_cost_multiplier;
let hash_rebuild_cost =
remaining_rows * index_info.hash_index_count as f64 * self.hash_index_update_cost;
rebuild_cost + hash_rebuild_cost
} else {
0.0
};
let wal_size_factor = index_info.wal_size_factor();
let wal_cost = rows * self.wal_write_cost * wal_size_factor + self.wal_sync_cost;
tuple_cost + hash_index_cost + btree_index_cost + columnar_cost + compaction_cost + wal_cost
}
}