use crate::db::access::{
execution_contract::{
AccessRouteClass, ExecutableAccessPath, ExecutableAccessPlan,
summary::summarize_executable_access_plan,
},
lowering::lower_executable_access_plan,
plan::AccessPlan,
};
use crate::db::executor::planning::route::LoadOrderRouteContract;
use std::fmt;
#[derive(Clone, Eq, PartialEq)]
pub(in crate::db) struct AccessStrategy<'a, K> {
executable: ExecutableAccessPlan<'a, K>,
class: AccessRouteClass,
}
impl<'a, K> AccessStrategy<'a, K> {
#[must_use]
pub(in crate::db) fn from_plan(plan: &'a AccessPlan<K>) -> Self {
let executable = lower_executable_access_plan(plan);
Self::from_executable(executable)
}
#[must_use]
pub(in crate::db) fn from_executable(executable: ExecutableAccessPlan<'a, K>) -> Self {
let class = executable.class();
Self { executable, class }
}
#[must_use]
pub(in crate::db) const fn executable(&self) -> &ExecutableAccessPlan<'a, K> {
&self.executable
}
#[must_use]
pub(in crate::db) fn into_executable(self) -> ExecutableAccessPlan<'a, K> {
self.executable
}
#[must_use]
pub(in crate::db) const fn class(&self) -> AccessRouteClass {
self.class
}
#[must_use]
pub(in crate::db) const fn as_path(&self) -> Option<&ExecutableAccessPath<'a, K>> {
self.executable.as_path()
}
#[must_use]
pub(in crate::db) const fn load_window_early_stop_hint(
&self,
continuation_applied: bool,
load_order_route_contract: LoadOrderRouteContract,
fetch_count: Option<usize>,
) -> Option<usize> {
if continuation_applied {
return None;
}
if !load_order_route_contract.allows_streaming_load() {
return None;
}
if !self.class().ordered() {
return None;
}
fetch_count
}
}
impl<K> AccessStrategy<'_, K>
where
K: fmt::Debug,
{
#[must_use]
pub(in crate::db) fn debug_summary(&self) -> String {
summarize_executable_access_plan(&self.executable)
}
}
impl<K> fmt::Debug for AccessStrategy<'_, K>
where
K: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AccessStrategy")
.field("summary", &self.debug_summary())
.field("class", &self.class)
.finish()
}
}