sim_lib_mutation/managed/
handles.rs1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3pub enum TraceContractVersion {
4 V1,
6}
7#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
9pub struct ManagedId(u64);
10
11impl ManagedId {
12 pub const fn allocation_ordinal(self) -> u64 {
14 self.0
15 }
16}
17
18#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
20pub struct RootId(u64);
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
24pub struct ManagedHandle {
25 id: ManagedId,
26}
27
28impl ManagedHandle {
29 pub const fn id(self) -> ManagedId {
31 self.id
32 }
33
34 pub const fn downgrade(self) -> WeakHandle {
36 WeakHandle { id: self.id }
37 }
38}
39
40#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
43pub struct RootedHandle {
44 root: RootId,
45 handle: ManagedHandle,
46}
47
48impl RootedHandle {
49 pub const fn root_id(self) -> RootId {
51 self.root
52 }
53
54 pub const fn handle(self) -> ManagedHandle {
56 self.handle
57 }
58}
59
60#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
62pub struct WeakHandle {
63 id: ManagedId,
64}
65
66impl WeakHandle {
67 pub const fn id(self) -> ManagedId {
69 self.id
70 }
71}
72
73#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
78pub struct EdgeId(pub u32);
79
80impl EdgeId {
81 pub const fn allocation_ordinal(self) -> u32 {
83 self.0
84 }
85}
86
87#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
89pub enum EdgeKind {
90 Strong,
92 Weak,
94 Ephemeron,
96}
97
98#[derive(Clone, Copy, Debug, Eq, PartialEq)]
100pub struct EdgeLimits {
101 total: usize,
102 strong: usize,
103 weak: usize,
104 ephemeron: usize,
105}
106
107impl EdgeLimits {
108 pub const DEFAULT: Self = Self::new(65_536, 65_536, 65_536, 65_536);
111
112 pub const fn new(total: usize, strong: usize, weak: usize, ephemeron: usize) -> Self {
114 Self {
115 total,
116 strong,
117 weak,
118 ephemeron,
119 }
120 }
121
122 pub const fn total(self) -> usize {
124 self.total
125 }
126
127 pub const fn for_kind(self, kind: EdgeKind) -> usize {
129 match kind {
130 EdgeKind::Strong => self.strong,
131 EdgeKind::Weak => self.weak,
132 EdgeKind::Ephemeron => self.ephemeron,
133 }
134 }
135}
136
137impl Default for EdgeLimits {
138 fn default() -> Self {
139 Self::DEFAULT
140 }
141}
142
143#[derive(Clone, Copy, Debug, Eq, PartialEq)]
145pub enum EdgeSnapshot {
146 Strong {
148 edge: EdgeId,
150 target: ManagedId,
152 },
153 Weak {
155 edge: EdgeId,
157 target: ManagedId,
159 },
160 Ephemeron {
162 edge: EdgeId,
164 key: ManagedId,
166 value: ManagedId,
168 },
169}
170
171impl EdgeSnapshot {
172 pub const fn id(self) -> EdgeId {
174 match self {
175 Self::Strong { edge, .. } | Self::Weak { edge, .. } | Self::Ephemeron { edge, .. } => {
176 edge
177 }
178 }
179 }
180}
181
182#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
184pub struct TypedEdgeId {
185 id: EdgeId,
186 kind: EdgeKind,
187}
188
189impl TypedEdgeId {
190 pub const fn id(self) -> EdgeId {
192 self.id
193 }
194
195 pub const fn kind(self) -> EdgeKind {
197 self.kind
198 }
199}
200
201#[derive(Clone, Copy, Debug, Eq, PartialEq)]
203pub enum EdgeAllocationError {
204 IdentityExhausted,
206 CapacityExceeded {
208 kind: EdgeKind,
210 cap: usize,
212 },
213}
214
215impl fmt::Display for EdgeAllocationError {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 match self {
218 Self::IdentityExhausted => f.write_str("managed edge identity space exhausted"),
219 Self::CapacityExceeded { kind, cap } => {
220 write!(f, "managed {kind:?} edge cap {cap} reached")
221 }
222 }
223 }
224}
225
226impl Error for EdgeAllocationError {}
227
228#[derive(Clone, Debug, Eq, PartialEq)]
235pub struct EdgeAllocator {
236 next: Option<u32>,
237}
238
239impl EdgeAllocator {
240 pub const fn new() -> Self {
242 Self { next: Some(0) }
243 }
244
245 pub fn allocate(&mut self, kind: EdgeKind) -> Result<TypedEdgeId, EdgeAllocationError> {
247 let ordinal = self.next.ok_or(EdgeAllocationError::IdentityExhausted)?;
248 self.next = ordinal.checked_add(1);
249 Ok(TypedEdgeId {
250 id: EdgeId(ordinal),
251 kind,
252 })
253 }
254
255 #[cfg(test)]
256 pub(crate) const fn starting_at(next: u32) -> Self {
257 Self { next: Some(next) }
258 }
259}
260
261impl Default for EdgeAllocator {
262 fn default() -> Self {
263 Self::new()
264 }
265}