honeycomb_core/attributes/
collections.rs1use num_traits::ToPrimitive;
7#[cfg(feature = "par-internals")]
8use rayon::prelude::*;
9
10use crate::attributes::{
11 AttributeBind, AttributeError, AttributeStorage, AttributeUpdate, UnknownAttributeStorage,
12};
13use crate::cmap::DartIdType;
14use crate::stm::{StmClosureResult, TVar, Transaction, TransactionClosureResult, abort};
15
16#[derive(Debug)]
28pub struct AttrSparseVec<T: AttributeBind + AttributeUpdate> {
29 data: Vec<TVar<Option<T>>>,
31}
32
33unsafe impl<A: AttributeBind + AttributeUpdate> Send for AttrSparseVec<A> {}
34unsafe impl<A: AttributeBind + AttributeUpdate> Sync for AttrSparseVec<A> {}
35
36impl<A: AttributeBind + AttributeUpdate> UnknownAttributeStorage for AttrSparseVec<A> {
37 #[cfg(not(feature = "par-internals"))]
38 fn new(length: usize) -> Self
39 where
40 Self: Sized,
41 {
42 Self {
43 data: (0..length).map(|_| TVar::new(None)).collect(),
44 }
45 }
46
47 #[cfg(feature = "par-internals")]
48 fn new(length: usize) -> Self
49 where
50 Self: Sized,
51 {
52 Self {
53 data: (0..length)
54 .into_par_iter()
55 .map(|_| TVar::new(None))
56 .collect(),
57 }
58 }
59
60 #[cfg(not(feature = "par-internals"))]
61 fn extend(&mut self, length: usize) {
62 self.data.extend((0..length).map(|_| TVar::new(None)));
63 }
64
65 #[cfg(feature = "par-internals")]
66 fn extend(&mut self, length: usize) {
67 self.data
68 .par_extend((0..length).into_par_iter().map(|_| TVar::new(None)));
69 }
70
71 fn clear_slot(&self, t: &mut Transaction, id: DartIdType) -> StmClosureResult<()> {
72 self.remove(t, A::IdentifierType::from(id))?;
73 Ok(())
74 }
75
76 fn n_attributes(&self) -> usize {
77 self.data
78 .iter()
79 .filter(|v| v.read_atomic().is_some())
80 .count()
81 }
82
83 fn merge(
84 &self,
85 t: &mut Transaction,
86 out: DartIdType,
87 lhs_inp: DartIdType,
88 rhs_inp: DartIdType,
89 ) -> TransactionClosureResult<(), AttributeError> {
90 let new_v = match (
91 self.data[lhs_inp as usize].read(t)?,
92 self.data[rhs_inp as usize].read(t)?,
93 ) {
94 (Some(v1), Some(v2)) => AttributeUpdate::merge(v1, v2),
95 (Some(v), None) | (None, Some(v)) => AttributeUpdate::merge_incomplete(v),
96 (None, None) => AttributeUpdate::merge_from_none(),
97 };
98 match new_v {
99 Ok(v) => {
100 self.data[rhs_inp as usize].write(t, None)?;
101 self.data[lhs_inp as usize].write(t, None)?;
102 self.data[out as usize].write(t, Some(v))?;
103 Ok(())
104 }
105 Err(e) => abort(e),
106 }
107 }
108
109 fn split(
110 &self,
111 t: &mut Transaction,
112 lhs_out: DartIdType,
113 rhs_out: DartIdType,
114 inp: DartIdType,
115 ) -> TransactionClosureResult<(), AttributeError> {
116 let res = if let Some(val) = self.data[inp as usize].read(t)? {
117 AttributeUpdate::split(val)
118 } else {
119 AttributeUpdate::split_from_none()
120 };
121 match res {
122 Ok((lhs_val, rhs_val)) => {
123 self.data[inp as usize].write(t, None)?;
124 self.data[lhs_out as usize].write(t, Some(lhs_val))?;
125 self.data[rhs_out as usize].write(t, Some(rhs_val))?;
126 Ok(())
127 }
128 Err(e) => abort(e),
129 }
130 }
131}
132
133impl<A: AttributeBind + AttributeUpdate> AttributeStorage<A> for AttrSparseVec<A> {
134 fn write(
135 &self,
136 t: &mut Transaction,
137 id: <A as AttributeBind>::IdentifierType,
138 val: A,
139 ) -> StmClosureResult<Option<A>> {
140 self.data[id.to_usize().unwrap()].replace(t, Some(val))
141 }
142
143 fn read(
144 &self,
145 t: &mut Transaction,
146 id: <A as AttributeBind>::IdentifierType,
147 ) -> StmClosureResult<Option<A>> {
148 self.data[id.to_usize().unwrap()].read(t)
149 }
150
151 fn remove(
152 &self,
153 t: &mut Transaction,
154 id: <A as AttributeBind>::IdentifierType,
155 ) -> StmClosureResult<Option<A>> {
156 self.data[id.to_usize().unwrap()].replace(t, None)
157 }
158}