1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
//! A distinct source-worker ledger using the existing ownership accountant.
//! It never attaches to an exact-provider registry or borrows its 1-GiB budget.
use super::{
BudgetObservation, BudgetUnavailable, PreparedSharedPhysicalOwnership, ProviderAllocationOwner,
ProviderBudget, Reservation,
};
use std::ops::Deref;
/// Compiled aggregate incremental memory limit for one source worker/database.
pub const PROJECTION_SOURCE_WORKING_MEMORY_BYTES: u64 = 64 * 1024 * 1024;
const SOURCE_ACCOUNTANT_BYTES: u64 = 512;
/// Source-worker accounting owner. Native worker admission must first establish
/// the single worker/database; cloning shares this exact ledger. Construction
/// charges its bounded accountant allocation before admitting any data.
#[derive(Clone)]
pub struct ProjectionSourceWorkingBudgetV1(ProviderBudget);
impl Default for ProjectionSourceWorkingBudgetV1 {
fn default() -> Self {
Self::new()
}
}
impl ProjectionSourceWorkingBudgetV1 {
/// Creates a separate fixed-limit ledger, never a provider budget handle.
#[must_use]
pub fn new() -> Self {
Self(ProviderBudget::with_limit_and_owner(
PROJECTION_SOURCE_WORKING_MEMORY_BYTES,
SOURCE_ACCOUNTANT_BYTES,
))
}
/// Admits the full simultaneous capacity/overhead bound before allocation.
pub fn reserve(
&self,
bytes: u64,
) -> Result<ProjectionSourceWorkReservationV1, BudgetUnavailable> {
self.0.reserve(bytes).map(ProjectionSourceWorkReservationV1)
}
/// Conservative overlap for the fixed accountant physically retained by
/// an exact-provider graph. This grants no extra source-work capacity.
#[doc(hidden)]
pub fn provider_control_ownership_needed(
&self,
budget: &ProviderBudget,
) -> Result<u64, BudgetUnavailable> {
if self.0.0.same_owner(&budget.0) {
return Err(BudgetUnavailable);
}
{
let accounting = budget.0.lock().map_err(|_| BudgetUnavailable)?;
if accounting.refused || accounting.limit != super::EXACT_PROVIDER_BUDGET_BYTES {
return Err(BudgetUnavailable);
}
}
self.0
.0
.provider_control
.provider_ownership_needed(SOURCE_ACCOUNTANT_BYTES, budget)
}
/// Whole-plan preparation only; cancellation attaches no foreign owner.
/// The cell lives with the actual accountant Arc, not the engine handle.
#[doc(hidden)]
pub fn prepare_provider_control_ownership_from(
&self,
work: &mut Reservation,
budget: &ProviderBudget,
) -> Result<PreparedSharedPhysicalOwnership<'_>, BudgetUnavailable> {
if self.0.0.same_owner(&budget.0) {
return Err(BudgetUnavailable);
}
{
let accounting = budget.0.lock().map_err(|_| BudgetUnavailable)?;
if accounting.refused || accounting.limit != super::EXACT_PROVIDER_BUDGET_BYTES {
return Err(BudgetUnavailable);
}
}
self.0.0.provider_control.prepare_provider_ownership_from(
SOURCE_ACCOUNTANT_BYTES,
work,
budget,
)
}
/// Fixed numeric control observation; never data or publication authority.
#[doc(hidden)]
pub fn provider_control_owned_bytes(&self) -> Result<u64, BudgetUnavailable> {
self.0.0.provider_control.owned_bytes()
}
/// One move-only maintenance-worker claim for this actual source ledger.
/// Native role checks and its existing drained process lifecycle are still
/// required; this claim alone grants no database mutation authority.
#[doc(hidden)]
pub fn try_acquire_worker(
&self,
) -> Result<ProjectionSourceWorkerOwnershipV1, BudgetUnavailable> {
let mut accounting = self.0.0.lock().map_err(|_| BudgetUnavailable)?;
if accounting.refused || accounting.source_worker_claimed {
return Err(BudgetUnavailable);
}
accounting.source_worker_claimed = true;
Ok(ProjectionSourceWorkerOwnershipV1 {
budget: self.clone(),
})
}
/// Exact accounting-owner affinity, never durable identity or authority.
#[doc(hidden)]
#[must_use]
pub fn shares_owner_with(&self, other: &Self) -> bool {
self.0.0.same_owner(&other.0.0)
}
/// Historical upper bound of simultaneously admitted source memory.
/// Includes fixed control, reserved work and settled ownership; not RSS,
/// publication authority, or an additional capacity allowance.
#[doc(hidden)]
pub fn peak_admitted_bytes(&self) -> Result<u64, BudgetUnavailable> {
let accounting = self.0.0.lock().map_err(|_| BudgetUnavailable)?;
if accounting.refused {
return Err(BudgetUnavailable);
}
Ok(accounting.peak_admitted_bytes)
}
/// Bounded counters only; no paths, source keys or payload values.
pub fn observation(&self) -> Result<BudgetObservation, BudgetUnavailable> {
self.0.observation()
}
/// Permanently closes this exact working ledger after uncertain private
/// resource cleanup. Existing owners still release their physical charges;
/// no later worker or allocation can turn uncertainty into fresh capacity.
#[doc(hidden)]
pub fn refuse_future_work(&self) {
let mut accounting = self
.0
.0
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
accounting.refused = true;
}
}
/// Move-only capacity admission for source work. Its private representation
/// prevents mixing it with provider reservations or native locator ownership.
pub struct ProjectionSourceWorkReservationV1(Reservation);
impl ProjectionSourceWorkReservationV1 {
/// Borrows this actual Source reservation for a numerical census.
pub fn inspection_scope(
&mut self,
) -> Result<crate::OwnedCapacityInspectionScopeV1<'_>, BudgetUnavailable> {
self.0.inspection_scope()
}
/// Already admitted allowance; never permission to exceed this capacity.
#[must_use]
pub const fn bytes(&self) -> u64 {
self.0.bytes
}
/// Transfers a nonzero portion without acquiring new allowance.
pub fn split(&mut self, bytes: u64) -> Result<Self, BudgetUnavailable> {
self.0.split(bytes).map(Self)
}
/// Combines only unpublished allowances from this same worker ledger.
pub fn absorb(&mut self, other: Self) -> Result<(), BudgetUnavailable> {
self.0.absorb(other.0)
}
/// Settles data constructed under this prior admission. The bound must
/// already include construction and the existing census scratch. Inspection
/// confirms retained ownership; it never substitutes for prior admission.
/// Shared catalog/native inputs require their own complete owner and are
/// refused by this wholly-owned helper.
pub fn settle_owned_value<T: crate::InspectOwnedCapacityV1>(
self,
value: T,
) -> Result<ProjectionSourceWorkAllocationV1<T>, BudgetUnavailable> {
self.0
.settle_owned_value(value)
.map(ProjectionSourceWorkAllocationV1)
}
/// Settles freshly constructed semantic values containing shared typed
/// identity data. Actual allocation lifecycles retain their source charge
/// until final destruction. Existing ownership in a foreign ledger refuses;
/// no identity allocation may be omitted, reassigned or borrowed silently.
/// Construction and graph-census capacity must be admitted beforehand.
pub fn settle_shared_value<T: crate::InspectOwnedCapacityV1>(
self,
value: T,
) -> Result<ProjectionSourceWorkAllocationV1<T>, BudgetUnavailable> {
self.0
.settle_shared_value(value)
.map(ProjectionSourceWorkAllocationV1)
}
}
/// Read-only shared data whose complete conservative charge lasts until the
/// final physical reference drops. The existing allocator drops data first.
pub struct ProjectionSourceWorkAllocationV1<T>(ProviderAllocationOwner<T>);
impl<T> Clone for ProjectionSourceWorkAllocationV1<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> ProjectionSourceWorkAllocationV1<T> {
/// Accounting identity only; grants no source or publication authority.
#[must_use]
pub fn belongs_to(&self, budget: &ProjectionSourceWorkingBudgetV1) -> bool {
self.0.belongs_to(&budget.0)
}
}
impl<T> Deref for ProjectionSourceWorkAllocationV1<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// A single worker's nondurable accounting ownership. It cannot be cloned or
/// converted into a command, writer lease, source proof or publication right.
#[doc(hidden)]
pub struct ProjectionSourceWorkerOwnershipV1 {
budget: ProjectionSourceWorkingBudgetV1,
}
impl Drop for ProjectionSourceWorkerOwnershipV1 {
fn drop(&mut self) {
let mut accounting = match self.budget.0.0.lock() {
Ok(accounting) => accounting,
Err(error) => {
let mut accounting = error.into_inner();
accounting.refused = true;
accounting
}
};
if accounting.source_worker_claimed {
accounting.source_worker_claimed = false;
} else {
accounting.refused = true;
}
}
}
#[cfg(test)]
#[path = "projection_source_budget_tests.rs"]
mod tests;