Skip to main content

icydb_core/db/query/
read_intent.rs

1//! Module: query::read_intent
2//! Responsibility: hardcoded read-intent caps for public semantic terminals.
3//! Does not own: planner proof, executor routing, or public policy builders.
4//! Boundary: one internal authority for 0.198 engine-owned read-intent limits.
5
6use crate::db::query::admission::{
7    DEFAULT_BOUNDED_READ_MAX_ROWS, DEFAULT_BOUNDED_READ_RESPONSE_BYTES,
8};
9
10pub(in crate::db::query) const PUBLIC_PAGE_DEFAULT_ROWS: u32 = DEFAULT_BOUNDED_READ_MAX_ROWS;
11pub(in crate::db::query) const PUBLIC_PAGE_MAX_ROWS: u32 = DEFAULT_BOUNDED_READ_MAX_ROWS;
12pub(in crate::db::query) const PUBLIC_PAGE_MAX_RESPONSE_BYTES: u32 =
13    DEFAULT_BOUNDED_READ_RESPONSE_BYTES;
14
15pub(in crate::db::query) const COMPLETE_SMALL_MAX_ROWS: u32 = DEFAULT_BOUNDED_READ_MAX_ROWS;
16pub(in crate::db::query) const COMPLETE_SMALL_LOOKAHEAD_ROWS: u32 = 1;
17pub(in crate::db::query) const COMPLETE_SMALL_EXECUTION_LIMIT: u32 =
18    COMPLETE_SMALL_MAX_ROWS + COMPLETE_SMALL_LOOKAHEAD_ROWS;
19pub(in crate::db::query) const ADMIN_BATCH_ROWS: u32 = DEFAULT_BOUNDED_READ_MAX_ROWS;
20
21/// Request-owned public page shape.
22///
23/// The requested limit is a caller preference, not a custom policy. IcyDB
24/// clamps it to the engine-owned public page cap before admission/execution.
25#[derive(Clone, Debug, Default, Eq, PartialEq)]
26pub struct PageRequest {
27    limit: Option<u32>,
28    cursor: Option<String>,
29}
30
31impl PageRequest {
32    /// Build a first-page request using the default public page size.
33    #[must_use]
34    pub const fn new() -> Self {
35        Self {
36            limit: None,
37            cursor: None,
38        }
39    }
40
41    /// Build a first-page request with one requested page size.
42    #[must_use]
43    pub const fn first(limit: u32) -> Self {
44        Self {
45            limit: Some(limit),
46            cursor: None,
47        }
48    }
49
50    /// Build a continuation request with one requested page size and cursor.
51    #[must_use]
52    pub fn next(limit: u32, cursor: impl Into<String>) -> Self {
53        Self {
54            limit: Some(limit),
55            cursor: Some(cursor.into()),
56        }
57    }
58
59    /// Return this request with a requested page size.
60    #[must_use]
61    pub const fn with_limit(mut self, limit: u32) -> Self {
62        self.limit = Some(limit);
63        self
64    }
65
66    /// Return this request with an opaque continuation cursor.
67    #[must_use]
68    pub fn with_cursor(mut self, cursor: impl Into<String>) -> Self {
69        self.cursor = Some(cursor.into());
70        self
71    }
72
73    /// Return the caller-requested page size, if supplied.
74    #[must_use]
75    pub const fn limit(&self) -> Option<u32> {
76        self.limit
77    }
78
79    /// Return the opaque continuation cursor, if supplied.
80    #[must_use]
81    pub fn cursor(&self) -> Option<&str> {
82        self.cursor.as_deref()
83    }
84
85    pub(in crate::db::query) const fn effective_limit(&self) -> u32 {
86        match self.limit {
87            Some(0) => 1,
88            Some(limit) if limit > PUBLIC_PAGE_MAX_ROWS => PUBLIC_PAGE_MAX_ROWS,
89            Some(limit) => limit,
90            None => PUBLIC_PAGE_DEFAULT_ROWS,
91        }
92    }
93
94    pub(in crate::db::query) fn into_cursor(self) -> Option<String> {
95        self.cursor
96    }
97}
98
99/// Request-owned trusted/admin batch continuation shape.
100///
101/// The batch size is engine-owned. Callers may only supply an opaque cursor
102/// for continuation, and the terminal remains gated to trusted read lanes.
103#[derive(Clone, Debug, Default, Eq, PartialEq)]
104pub struct AdminBatchRequest {
105    cursor: Option<String>,
106}
107
108impl AdminBatchRequest {
109    /// Build a first-batch request.
110    #[must_use]
111    pub const fn new() -> Self {
112        Self { cursor: None }
113    }
114
115    /// Build a continuation request with an opaque cursor.
116    #[must_use]
117    pub fn next(cursor: impl Into<String>) -> Self {
118        Self {
119            cursor: Some(cursor.into()),
120        }
121    }
122
123    /// Return this request with an opaque continuation cursor.
124    #[must_use]
125    pub fn with_cursor(mut self, cursor: impl Into<String>) -> Self {
126        self.cursor = Some(cursor.into());
127        self
128    }
129
130    /// Return the opaque continuation cursor, if supplied.
131    #[must_use]
132    pub fn cursor(&self) -> Option<&str> {
133        self.cursor.as_deref()
134    }
135
136    pub(in crate::db::query) fn into_cursor(self) -> Option<String> {
137        self.cursor
138    }
139}