mod execution;
pub(in crate::db::executor) mod grouped;
mod post_access;
use crate::{
db::{
Db, GroupedRow, PersistedRow,
cursor::{ContinuationToken, GroupedContinuationToken},
data::DataRow,
direction::Direction,
executor::{ExecutionOptimization, KeyOrderComparator, OrderedKeyStreamBox},
response::EntityResponse,
},
error::InternalError,
traits::{EntityKind, EntityValue},
};
pub(in crate::db::executor) use execution::{
CoveringComponentScanState, CursorEmissionMode, DirectCoveringScanMaterializationRequest,
ExecutionInputs, ExecutionOutcomeMetrics, ExecutionRuntime, ExecutionRuntimeAdapter,
MaterializedExecutionAttempt, ProjectionMaterializationMode, ResolvedExecutionKeyStream,
RowCollectorMaterializationRequest, RuntimePageMaterializationRequest, StructuralCursorPage,
};
pub(in crate::db::executor) use grouped::{
GroupedFoldStage, GroupedPlannerPayload, GroupedRoutePayload, GroupedRouteStage,
GroupedRowRuntime, GroupedStreamStage, IndexSpecBundle, RowView, StructuralGroupedRowRuntime,
};
pub(in crate::db::executor) use post_access::PostAccessContract;
#[derive(Clone, Debug, Eq, PartialEq)]
pub(in crate::db) enum PageCursor {
Scalar(ContinuationToken),
Grouped(GroupedContinuationToken),
}
impl PageCursor {
#[must_use]
pub(in crate::db) const fn as_scalar(&self) -> Option<&ContinuationToken> {
match self {
Self::Scalar(token) => Some(token),
Self::Grouped(_) => None,
}
}
#[must_use]
pub(in crate::db) const fn as_grouped(&self) -> Option<&GroupedContinuationToken> {
match self {
Self::Scalar(_) => None,
Self::Grouped(token) => Some(token),
}
}
#[cfg(test)]
pub(in crate::db) fn encode(&self) -> Result<Vec<u8>, crate::db::cursor::TokenWireError> {
match self {
Self::Scalar(token) => token.encode(),
Self::Grouped(token) => token.encode(),
}
}
}
impl From<ContinuationToken> for PageCursor {
fn from(value: ContinuationToken) -> Self {
Self::Scalar(value)
}
}
impl From<GroupedContinuationToken> for PageCursor {
fn from(value: GroupedContinuationToken) -> Self {
Self::Grouped(value)
}
}
#[derive(Debug)]
pub(in crate::db) struct CursorPage<E: EntityKind> {
pub(in crate::db) items: EntityResponse<E>,
pub(in crate::db) next_cursor: Option<PageCursor>,
}
impl<E> CursorPage<E>
where
E: PersistedRow + EntityValue,
{
#[inline(never)]
pub(in crate::db::executor) fn from_data_rows(
data_rows: Vec<DataRow>,
next_cursor: Option<PageCursor>,
) -> Result<Self, InternalError> {
let items = EntityResponse::from_data_rows(data_rows)?;
Ok(Self { items, next_cursor })
}
}
impl StructuralCursorPage {
#[inline(never)]
pub(in crate::db::executor) fn into_entity_response<E>(
self,
) -> Result<EntityResponse<E>, InternalError>
where
E: PersistedRow + EntityValue,
{
let (data_rows, _) = self.into_parts();
EntityResponse::from_data_rows(data_rows)
}
#[inline(never)]
pub(in crate::db::executor) fn into_cursor_page<E>(self) -> Result<CursorPage<E>, InternalError>
where
E: PersistedRow + EntityValue,
{
let (data_rows, next_cursor) = self.into_parts();
CursorPage::from_data_rows(data_rows, next_cursor)
}
}
#[derive(Debug)]
pub(in crate::db) struct GroupedCursorPage {
pub(in crate::db) rows: Vec<GroupedRow>,
pub(in crate::db) next_cursor: Option<PageCursor>,
}
pub(in crate::db::executor) const fn key_stream_comparator_from_direction(
direction: Direction,
) -> KeyOrderComparator {
KeyOrderComparator::from_direction(direction)
}
pub(in crate::db::executor) struct FastPathKeyResult {
pub(in crate::db::executor) ordered_key_stream: OrderedKeyStreamBox,
pub(in crate::db::executor) rows_scanned: usize,
pub(in crate::db::executor) optimization: ExecutionOptimization,
}
#[derive(Clone)]
pub(in crate::db) struct LoadExecutor<E: EntityKind> {
pub(in crate::db::executor) db: Db<E::Canister>,
pub(in crate::db::executor) debug: bool,
}