use std::sync::Arc;
use crate::{
engine::computation_graph::{
ActiveComputationGuard, computing::QueryComputing, database::Timestamp,
},
query::QueryID,
};
#[derive(Clone)]
pub enum CallerReason {
RequireValue(#[allow(unused)] Option<waitgroup::Worker>),
Repair,
}
impl std::fmt::Debug for CallerReason {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RequireValue(_) => {
f.debug_tuple("RequireValue").finish_non_exhaustive()
}
Self::Repair => f.debug_tuple("Repair").finish(),
}
}
}
#[derive(Debug, Clone)]
pub struct QueryCaller {
query_id: QueryID,
computing: Option<Arc<QueryComputing>>,
reason: CallerReason,
pedantic_repair: bool,
}
impl QueryCaller {
pub const fn new_with_pedantic_repair(
query_id: QueryID,
reason: CallerReason,
computing: Arc<QueryComputing>,
pedantic_repair: bool,
) -> Self {
Self { query_id, computing: Some(computing), reason, pedantic_repair }
}
pub const fn new_external_input(
query_id: QueryID,
worker: waitgroup::Worker,
) -> Self {
Self {
query_id,
computing: None,
reason: CallerReason::RequireValue(Some(worker)),
pedantic_repair: false,
}
}
pub const fn pedantic_repair(&self) -> bool { self.pedantic_repair }
pub const fn try_computing(&self) -> Option<&Arc<QueryComputing>> {
self.computing.as_ref()
}
#[must_use]
pub const fn computing(&self) -> &Arc<QueryComputing> {
self.computing
.as_ref()
.expect("`ExternalInput` cannot call other queries")
}
#[must_use]
pub const fn query_id(&self) -> QueryID { self.query_id }
#[must_use]
pub const fn require_value(&self) -> bool {
matches!(self.reason, CallerReason::RequireValue { .. })
}
}
#[derive(Debug, Clone)]
pub struct CallerInformation {
kind: CallerKind,
timestamp: Timestamp,
active_computation_guard: Option<ActiveComputationGuard>,
}
impl CallerInformation {
pub const fn new(
kind: CallerKind,
timestamp: Timestamp,
active_computation_guard: Option<ActiveComputationGuard>,
) -> Self {
Self { kind, timestamp, active_computation_guard }
}
#[must_use]
pub fn clone_active_computation_guard(
&self,
) -> Option<ActiveComputationGuard> {
self.active_computation_guard.clone()
}
#[must_use]
pub const fn active_computation_guard(
&self,
) -> Option<&ActiveComputationGuard> {
self.active_computation_guard.as_ref()
}
pub const fn get_query_caller(&self) -> Option<&QueryCaller> {
match &self.kind {
CallerKind::RepairFirewall
| CallerKind::BackwardProjectionPropagation
| CallerKind::Tracing
| CallerKind::User => None,
CallerKind::Query(q) => Some(q),
}
}
pub const fn require_value(&self) -> bool {
match &self.kind {
CallerKind::RepairFirewall
| CallerKind::BackwardProjectionPropagation
| CallerKind::Tracing => false,
CallerKind::User => true,
CallerKind::Query(q) => {
matches!(q.reason, CallerReason::RequireValue { .. })
}
}
}
pub const fn timestamp(&self) -> Timestamp { self.timestamp }
pub const fn kind(&self) -> &CallerKind { &self.kind }
}
#[derive(Debug, Clone)]
pub enum CallerKind {
User,
Query(QueryCaller),
Tracing,
BackwardProjectionPropagation,
RepairFirewall,
}