1use crate::{
2 catalogs, config, conn, database, retry,
3 runtime::{self, heap, slot},
4};
5use dope_core::driver::storage;
6use heap::layout::Layout;
7use std::{cell, marker, mem, pin};
8
9pub struct State<'d, I: catalogs::Catalog> {
11 retry: retry::raw::Configured<'d>,
12 slot: cell::UnsafeCell<slot::Local<I>>,
13 phase: runtime::raw::Span,
14 _retire: heap::raw::Retained,
15 proof: marker::PhantomData<(cell::Cell<&'d I>, marker::PhantomPinned)>,
16 value_bytes: i32,
17 statement_sql_bytes: i32,
18 database: cell::UnsafeCell<Option<(database::Target<'d>, heap::raw::Local)>>,
20}
21
22pub(super) struct Settings {
23 pub(super) config: config::Config,
24 pub(super) value_bytes: i32,
25 pub(super) statement_sql_bytes: i32,
26}
27
28impl<'d, I: catalogs::Catalog> State<'d, I> {
29 pub(in crate::runtime) fn new(
30 context: &mut storage::Context<'_, 'd>,
31 settings: Settings,
32 sqlite: Layout,
33 database: database::Target<'d>,
34 stmts: usize,
35 aside: crate::memory::Lookaside,
36 ) -> Result<Self, runtime::Error> {
37 let Settings {
38 config,
39 value_bytes: values,
40 statement_sql_bytes: sql,
41 } = settings;
42 let (memory, sqlite, collect, stmts, storage, phase) = runtime::raw::Memory::new(
43 sqlite,
44 config.result_bytes(),
45 stmts,
46 aside.bytes(),
47 conn::raw::Vacant::<'_, 'd, I>::LAYOUT,
48 )?;
49 let retry = retry::raw::Configured::new(config, || {
50 context
51 .timer()
52 .try_alarm()
53 .map_err(runtime::Error::TimerCapacity)
54 })?;
55 let (slot, heap, retained) =
56 slot::Local::new(memory, sqlite, collect, stmts, storage, aside)?;
57 Ok(Self {
58 retry,
59 slot: cell::UnsafeCell::new(slot),
60 phase,
61 _retire: retained,
62 proof: marker::PhantomData,
63 value_bytes: values,
64 statement_sql_bytes: sql,
65 database: cell::UnsafeCell::new(Some((database, heap))),
66 })
67 }
68
69 pub fn config(self: pin::Pin<&Self>) -> &config::Config {
70 self.get_ref().retry.config()
71 }
72
73 pub(crate) const fn sql_bytes(&self) -> i32 {
74 self.statement_sql_bytes
75 }
76
77 pub(crate) const fn value_bytes(&self) -> i32 {
78 self.value_bytes
79 }
80
81 pub(crate) fn try_lease<'local>(
82 self: pin::Pin<&'local Self>,
83 report: &'local mut crate::open::Completion,
84 ) -> Result<
85 (
86 database::Target<'d>,
87 slot::Vacant<'local, 'd, I>,
88 conn::raw::Vacant<'local, 'd, I>,
89 ),
90 crate::open::Error,
91 >
92 where
93 'd: 'local,
94 {
95 let report = report.admit()?;
96 let local = self.get_ref();
97 let (database, heap) = unsafe { &mut *local.database.get() }
99 .take()
100 .ok_or(crate::open::Error::AlreadyStarted)?;
101 let retry = unsafe { local.retry.loan() };
104 let slot = unsafe { &mut *local.slot.get() };
107 let lease = slot.lease(heap, retry, report)?;
108 let phase = unsafe { conn::raw::Vacant::new(&local.phase) };
111 Ok((database, lease, phase))
112 }
113}
114
115const _: () = {
116 let fields = mem::size_of::<retry::raw::Configured<'_>>()
117 + mem::size_of::<cell::UnsafeCell<slot::Local<catalogs::Empty>>>()
118 + mem::size_of::<runtime::raw::Span>()
119 + mem::size_of::<heap::raw::Retained>()
120 + mem::size_of::<marker::PhantomData<(cell::Cell<&catalogs::Empty>, marker::PhantomPinned)>>(
121 )
122 + 2 * mem::size_of::<i32>()
123 + mem::size_of::<cell::UnsafeCell<Option<(database::Target<'_>, heap::raw::Local)>>>();
124 let align = mem::align_of::<State<'_, catalogs::Empty>>();
125 assert!(mem::size_of::<State<'_, catalogs::Empty>>() == fields.next_multiple_of(align));
126};