ferrum_interfaces/vnext/execution/
allocation.rs1use super::{
2 invalid_plan, quantize_storage_bytes, AllocationKind, AllocationLifetime, BufferRequest,
3 BufferUsage, Deserialize, DynamicStorageContract, ElementType, ResourceId, Serialize,
4 VNextError,
5};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub struct ResourceAllocation {
9 pub(super) resource_id: ResourceId,
10 pub(super) per_instance_bytes: u64,
11 pub(super) instance_stride_bytes: u64,
12 pub(super) instance_count: u32,
13 pub(super) size_bytes: u64,
14 pub(super) alignment_bytes: u64,
15 pub(super) usage: BufferUsage,
16 pub(super) element_type: ElementType,
17 pub(super) lifetime: AllocationLifetime,
18 pub(super) kind: AllocationKind,
19 pub(super) storage: DynamicStorageContract,
20}
21
22impl ResourceAllocation {
23 pub(super) fn new(
24 resource_id: ResourceId,
25 per_instance_bytes: u64,
26 alignment_bytes: u64,
27 usage: BufferUsage,
28 element_type: ElementType,
29 kind: AllocationKind,
30 storage: DynamicStorageContract,
31 ) -> Result<Self, VNextError> {
32 if per_instance_bytes == 0 || alignment_bytes == 0 || !alignment_bytes.is_power_of_two() {
33 return Err(invalid_plan(format!(
34 "resource `{resource_id}` has invalid size or alignment"
35 )));
36 }
37 let instance_stride_bytes =
38 quantize_storage_bytes(per_instance_bytes, alignment_bytes, storage.profile())?;
39 Ok(Self {
40 resource_id,
41 per_instance_bytes,
42 instance_stride_bytes,
43 instance_count: 1,
44 size_bytes: instance_stride_bytes,
45 alignment_bytes,
46 usage,
47 element_type,
48 lifetime: AllocationLifetime::Plan,
49 kind,
50 storage,
51 })
52 }
53
54 pub fn resource_id(&self) -> &ResourceId {
55 &self.resource_id
56 }
57
58 pub const fn size_bytes(&self) -> u64 {
59 self.size_bytes
60 }
61
62 pub const fn per_instance_bytes(&self) -> u64 {
63 self.per_instance_bytes
64 }
65
66 pub const fn instance_stride_bytes(&self) -> u64 {
67 self.instance_stride_bytes
68 }
69
70 pub const fn instance_count(&self) -> u32 {
71 self.instance_count
72 }
73
74 pub fn scoped_offset_bytes(
75 &self,
76 base_offset_bytes: u64,
77 _active_sequence_slot: u32,
78 ) -> Result<u64, VNextError> {
79 if base_offset_bytes >= self.per_instance_bytes {
80 return Err(invalid_plan(format!(
81 "resource `{}` base offset is outside its per-instance span",
82 self.resource_id
83 )));
84 }
85 Ok(base_offset_bytes)
86 }
87
88 pub const fn alignment_bytes(&self) -> u64 {
89 self.alignment_bytes
90 }
91
92 pub const fn usage(&self) -> BufferUsage {
93 self.usage
94 }
95
96 pub const fn element_type(&self) -> ElementType {
97 self.element_type
98 }
99
100 pub const fn lifetime(&self) -> AllocationLifetime {
101 self.lifetime
102 }
103
104 pub fn kind(&self) -> &AllocationKind {
105 &self.kind
106 }
107
108 pub fn storage(&self) -> &DynamicStorageContract {
109 &self.storage
110 }
111
112 pub fn buffer_request(&self) -> Result<BufferRequest, VNextError> {
113 BufferRequest::new(
114 self.resource_id.clone(),
115 self.size_bytes,
116 self.alignment_bytes,
117 self.usage,
118 self.element_type,
119 )
120 }
121}