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

Function compact_segment

nodedb-columnar/src/compaction/segment.rs:44–121  ·  view source on GitHub ↗

Compact a single segment by removing deleted rows. Reads the segment, skips rows marked in the delete bitmap, and writes a new segment with only live rows. Returns `None` segment if all rows were deleted. When `kek` is `Some`, the output segment is wrapped in an AES-256-GCM SEGC envelope. The input segment must be plaintext (the caller is responsible for decrypting before passing to this functio

(
    segment_data: &[u8],
    deletes: &DeleteBitmap,
    schema: &ColumnarSchema,
    profile_tag: u8,
    governor: Option<&Arc<MemoryGovernor>>,
    kek: Option<&nodedb_wal::crypto::WalEncryptionK

Source from the content-addressed store, hash-verified

42/// tracked against the `Columnar` engine budget. Pass `None` in embedded
43/// (Lite) deployments where no governor is configured.
44pub fn compact_segment(
45 segment_data: &[u8],
46 deletes: &DeleteBitmap,
47 schema: &ColumnarSchema,
48 profile_tag: u8,
49 governor: Option<&Arc<MemoryGovernor>>,
50 kek: Option<&nodedb_wal::crypto::WalEncryptionKey>,
51) -> Result<CompactionResult, ColumnarError> {
52 let reader = SegmentReader::open(segment_data)?;
53 let total_rows = reader.row_count() as usize;
54 let deleted = deletes.deleted_count() as usize;
55 let live = total_rows.saturating_sub(deleted);
56
57 if live == 0 {
58 return Ok(CompactionResult {
59 segment: None,
60 live_rows: 0,
61 removed_rows: total_rows,
62 });
63 }
64
65 // Read all columns without delete masking — we'll filter manually.
66 let col_count = reader.column_count();
67 // Reserve budget for the decoded-column pointer vec (each entry is a fat pointer).
68 let _cols_guard = governor
69 .map(|g| {
70 g.reserve(
71 EngineId::Columnar,
72 col_count * std::mem::size_of::<usize>() * 3,
73 )
74 })
75 .transpose()?;
76 let mut decoded_cols = Vec::with_capacity(col_count);
77 for i in 0..col_count {
78 decoded_cols.push(reader.read_column(i)?);
79 }
80
81 // Build a new memtable with only live rows.
82 let mut memtable = ColumnarMemtable::new(schema);
83 let col_len = schema.columns.len();
84 let _row_guard = governor
85 .map(|g| {
86 g.reserve(
87 EngineId::Columnar,
88 col_len * std::mem::size_of::<usize>() * 3,
89 )
90 })
91 .transpose()?;
92 let mut row_values = Vec::with_capacity(col_len);
93
94 for row_idx in 0..total_rows {
95 if deletes.is_deleted(row_idx as u32) {
96 continue;
97 }
98
99 row_values.clear();
100 for (col_idx, decoded) in decoded_cols.iter().enumerate() {
101 let col = &schema.columns[col_idx];

Callers 4

compact_all_deletedFunction · 0.85
compact_no_deletesFunction · 0.85

Calls 15

extract_row_valueFunction · 0.85
deleted_countMethod · 0.80
append_rowMethod · 0.80
openFunction · 0.50
row_countMethod · 0.45
column_countMethod · 0.45
reserveMethod · 0.45
pushMethod · 0.45
read_columnMethod · 0.45
lenMethod · 0.45
is_deletedMethod · 0.45
clearMethod · 0.45

Tested by 4

compact_all_deletedFunction · 0.68
compact_no_deletesFunction · 0.68