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