spongefish_circuit/
allocator.rs1use alloc::{sync::Arc, vec::Vec};
4
5use spin::RwLock;
6use spongefish::Unit;
7
8#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, Unit)]
11pub struct FieldVar(pub usize);
12
13impl core::fmt::Debug for FieldVar {
14 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
15 write!(f, "v({})", self.0)
16 }
17}
18
19#[derive(Clone)]
24pub struct VarAllocator<T> {
25 state: Arc<RwLock<AllocatorState<T>>>,
26}
27
28struct AllocatorState<T> {
29 vars_count: usize,
30 public_values: Vec<(FieldVar, T)>,
31}
32
33impl<T: Clone + Unit> Default for VarAllocator<T> {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38
39impl<T: Clone + Unit> VarAllocator<T> {
40 #[must_use]
41 pub fn new() -> Self {
42 let zero_var = FieldVar::ZERO;
43 Self {
44 state: Arc::new(RwLock::new(AllocatorState {
45 vars_count: 1,
46 public_values: Vec::from([(zero_var, T::ZERO)]),
47 })),
48 }
49 }
50
51 #[must_use]
52 pub fn new_field_var(&self) -> FieldVar {
53 let mut state = self.state.write();
54 let var = FieldVar(state.vars_count);
55 state.vars_count += 1;
56 var
57 }
58
59 #[must_use]
60 pub fn allocate_vars<const N: usize>(&self) -> [FieldVar; N] {
61 let mut buf = [FieldVar::default(); N];
62 for x in &mut buf {
63 *x = self.new_field_var();
64 }
65 buf
66 }
67
68 #[must_use]
69 pub fn allocate_vars_vec(&self, count: usize) -> Vec<FieldVar> {
70 (0..count).map(|_| self.new_field_var()).collect()
71 }
72
73 pub fn allocate_public<const N: usize>(&self, public_values: &[T; N]) -> [FieldVar; N] {
74 let vars = self.allocate_vars();
75 self.set_public_vars(vars, public_values);
76 vars
77 }
78
79 pub fn allocate_public_vec(&self, public_values: &[T]) -> Vec<FieldVar> {
80 let vars = self.allocate_vars_vec(public_values.len());
81 self.set_public_vars(vars.clone(), public_values);
82 vars
83 }
84
85 #[must_use]
86 pub fn vars_count(&self) -> usize {
87 self.state.read().vars_count
88 }
89
90 pub fn set_public_var(&self, val: FieldVar, var: T) {
91 self.state.write().public_values.push((val, var));
92 }
93
94 pub fn set_public_vars<Val, Var>(
95 &self,
96 vars: impl IntoIterator<Item = Var>,
97 vals: impl IntoIterator<Item = Val>,
98 ) where
99 Var: core::borrow::Borrow<FieldVar>,
100 Val: core::borrow::Borrow<T>,
101 {
102 self.state.write().public_values.extend(
103 vars.into_iter()
104 .zip(vals)
105 .map(|(var, val)| (*var.borrow(), val.borrow().clone())),
106 );
107 }
108
109 #[must_use]
110 pub fn public_vars(&self) -> Vec<(FieldVar, T)> {
111 self.state.read().public_values.clone()
112 }
113}