nodedb_columnar/mutation/
write.rs1use nodedb_types::surrogate::Surrogate;
6use nodedb_types::value::Value;
7
8use crate::error::ColumnarError;
9use crate::pk_index::{RowLocation, encode_pk};
10use crate::wal_record::{ColumnarWalRecord, encode_row_for_wal};
11
12use super::engine::{MutationEngine, MutationResult};
13
14impl MutationEngine {
15 pub fn insert(&mut self, values: &[Value]) -> Result<MutationResult, ColumnarError> {
31 let pk_bytes = self.extract_pk_bytes(values)?;
32 let mut wal_records = Vec::with_capacity(2);
33
34 let bitemporal = self.schema.is_bitemporal();
42
43 if !bitemporal && let Some(prior) = self.pk_index.get(&pk_bytes).copied() {
47 let bitmap = self.delete_bitmaps.entry(prior.segment_id).or_default();
48 bitmap.mark_deleted(prior.row_index);
49 wal_records.push(ColumnarWalRecord::DeleteRows {
50 collection: self.collection.clone(),
51 segment_id: prior.segment_id,
52 row_indices: vec![prior.row_index],
53 });
54 }
55
56 let row_data = encode_row_for_wal(values)?;
57 wal_records.push(ColumnarWalRecord::InsertRow {
58 collection: self.collection.clone(),
59 row_data,
60 });
61
62 self.memtable.append_row(values)?;
63 let location = RowLocation {
64 segment_id: self.memtable_segment_id,
65 row_index: self.memtable_row_counter,
66 };
67 self.pk_index.upsert(pk_bytes, location);
68 self.memtable_surrogates.push(None);
69 self.memtable_row_counter += 1;
70
71 Ok(MutationResult { wal_records })
72 }
73
74 pub fn insert_with_surrogate(
80 &mut self,
81 values: &[Value],
82 surrogate: Surrogate,
83 ) -> Result<MutationResult, ColumnarError> {
84 let pk_bytes = self.extract_pk_bytes(values)?;
85 let mut wal_records = Vec::with_capacity(2);
86
87 let bitemporal = self.schema.is_bitemporal();
88 if !bitemporal && let Some(prior) = self.pk_index.get(&pk_bytes).copied() {
89 let bitmap = self.delete_bitmaps.entry(prior.segment_id).or_default();
90 bitmap.mark_deleted(prior.row_index);
91 wal_records.push(ColumnarWalRecord::DeleteRows {
92 collection: self.collection.clone(),
93 segment_id: prior.segment_id,
94 row_indices: vec![prior.row_index],
95 });
96 }
97
98 let row_data = encode_row_for_wal(values)?;
99 wal_records.push(ColumnarWalRecord::InsertRow {
100 collection: self.collection.clone(),
101 row_data,
102 });
103
104 self.memtable.append_row(values)?;
105 let location = RowLocation {
106 segment_id: self.memtable_segment_id,
107 row_index: self.memtable_row_counter,
108 };
109 self.pk_index.upsert(pk_bytes, location);
110 self.memtable_surrogates.push(Some(surrogate));
111 self.memtable_row_counter += 1;
112
113 Ok(MutationResult { wal_records })
114 }
115
116 pub fn insert_if_absent(&mut self, values: &[Value]) -> Result<MutationResult, ColumnarError> {
123 let pk_bytes = self.extract_pk_bytes(values)?;
124 if self.pk_index.contains(&pk_bytes) {
125 return Ok(MutationResult {
126 wal_records: Vec::new(),
127 });
128 }
129
130 let row_data = encode_row_for_wal(values)?;
131 let wal = ColumnarWalRecord::InsertRow {
132 collection: self.collection.clone(),
133 row_data,
134 };
135 self.memtable.append_row(values)?;
136 let location = RowLocation {
137 segment_id: self.memtable_segment_id,
138 row_index: self.memtable_row_counter,
139 };
140 self.pk_index.upsert(pk_bytes, location);
141 self.memtable_surrogates.push(None);
142 self.memtable_row_counter += 1;
143
144 Ok(MutationResult {
145 wal_records: vec![wal],
146 })
147 }
148
149 pub fn lookup_memtable_row_by_pk(&self, pk_bytes: &[u8]) -> Option<Vec<Value>> {
158 let loc = self.pk_index.get(pk_bytes).copied()?;
159 if loc.segment_id != self.memtable_segment_id {
160 return None;
161 }
162 self.memtable.get_row(loc.row_index as usize)
163 }
164
165 pub fn delete(&mut self, pk_value: &Value) -> Result<MutationResult, ColumnarError> {
170 let pk_bytes = encode_pk(pk_value);
171
172 let location = self
173 .pk_index
174 .get(&pk_bytes)
175 .copied()
176 .ok_or(ColumnarError::PrimaryKeyNotFound)?;
177
178 let wal = ColumnarWalRecord::DeleteRows {
180 collection: self.collection.clone(),
181 segment_id: location.segment_id,
182 row_indices: vec![location.row_index],
183 };
184
185 let bitmap = self.delete_bitmaps.entry(location.segment_id).or_default();
187 bitmap.mark_deleted(location.row_index);
188
189 self.pk_index.remove(&pk_bytes);
191
192 Ok(MutationResult {
193 wal_records: vec![wal],
194 })
195 }
196
197 pub fn update(
207 &mut self,
208 old_pk: &Value,
209 new_values: &[Value],
210 ) -> Result<MutationResult, ColumnarError> {
211 let delete_result = self.delete(old_pk)?;
213
214 let insert_result = self.insert(new_values)?;
216
217 let mut wal_records = delete_result.wal_records;
219 wal_records.extend(insert_result.wal_records);
220
221 Ok(MutationResult { wal_records })
222 }
223}