MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / insert

Method insert

nodedb-columnar/src/mutation/write.rs:30–72  ·  view source on GitHub ↗

Insert a row with upsert-on-duplicate semantics. Returns WAL records to persist. Validates schema. If the PK already exists, the prior row is tombstoned via the segment's delete bitmap (a single positional delete) before the new row is appended to the memtable. The PK index is rebound to the new row location. This matches the ClickHouse / Iceberg "sparse PK + positional delete" model and keeps `S

(&mut self, values: &[Value])

Source from the content-addressed store, hash-verified

28 /// want `ON CONFLICT DO NOTHING` semantics should use
29 /// [`Self::insert_if_absent`].
30 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 // Bitemporal collections preserve every version of a PK: each
35 // write appends a new row with a distinct `_ts_system` stamp and
36 // the prior row stays visible to `AS OF` queries. Skipping the
37 // upsert-tombstone here keeps compaction lossless without
38 // needing a separate "version-aware" delete bitmap. The PK
39 // index is still rebound below so current-state reads see the
40 // latest version.
41 let bitemporal = self.schema.is_bitemporal();
42
43 // If a prior row exists for this PK, tombstone it in place so
44 // subsequent scans skip the stale row. The PK index is rebound
45 // below to the freshly-appended row.
46 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 /// Insert with a stable cross-engine surrogate identity.
75 ///

Callers 15

parse_range_literalFunction · 0.45
pushMethod · 0.45
push_refMethod · 0.45
try_dict_encodeMethod · 0.45
pushMethod · 0.45
push_refMethod · 0.45
updateMethod · 0.45
insert_and_pk_checkFunction · 0.45
delete_by_pkFunction · 0.45
update_rowFunction · 0.45
memtable_flush_remaps_pkFunction · 0.45

Calls 10

encode_row_for_walFunction · 0.85
extract_pk_bytesMethod · 0.80
entryMethod · 0.80
append_rowMethod · 0.80
is_bitemporalMethod · 0.45
getMethod · 0.45
mark_deletedMethod · 0.45
pushMethod · 0.45
cloneMethod · 0.45
upsertMethod · 0.45

Tested by 7

insert_and_pk_checkFunction · 0.36
delete_by_pkFunction · 0.36
update_rowFunction · 0.36
memtable_flush_remaps_pkFunction · 0.36
should_compact_thresholdFunction · 0.36