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

Method encode

nodedb-strict/src/encode.rs:77–159  ·  view source on GitHub ↗

Encode a row of values into a Binary Tuple. `values` must have exactly `schema.len()` entries. A `Value::Null` is allowed only if the corresponding column is nullable.

(&self, values: &[Value])

Source from the content-addressed store, hash-verified

75 /// `values` must have exactly `schema.len()` entries. A `Value::Null` is
76 /// allowed only if the corresponding column is nullable.
77 pub fn encode(&self, values: &[Value]) -> Result<Vec<u8>, StrictError> {
78 let n_cols = self.schema.columns.len();
79 if values.len() != n_cols {
80 return Err(StrictError::ValueCountMismatch {
81 expected: n_cols,
82 got: values.len(),
83 });
84 }
85
86 // Pre-size: header + fixed + offset_table. Variable data appended later.
87 let offset_table_size = (self.var_indices.len() + 1) * 4;
88 let base_size = self.header_size + self.fixed_section_size + offset_table_size;
89 let mut buf = vec![0u8; base_size];
90
91 // 1. Magic, format version, schema version.
92 buf[0..4].copy_from_slice(&MAGIC.to_le_bytes());
93 buf[4] = FORMAT_VERSION;
94 buf[5..9].copy_from_slice(&self.schema.version.to_le_bytes());
95
96 // 2. Null bitmap + fixed fields + type validation.
97 let bitmap_start = 9;
98 let fixed_start = self.header_size;
99
100 for (i, (col, val)) in self.schema.columns.iter().zip(values.iter()).enumerate() {
101 let is_null = matches!(val, Value::Null);
102
103 if is_null {
104 if !col.nullable {
105 return Err(StrictError::NullViolation(col.name.clone()));
106 }
107 // Set null bit: byte = i / 8, bit = i % 8.
108 buf[bitmap_start + i / 8] |= 1 << (i % 8);
109 // Fixed fields remain zeroed; no variable data emitted.
110 continue;
111 }
112
113 // Type check (with coercion).
114 if !col.column_type.accepts(val) {
115 return Err(StrictError::TypeMismatch {
116 column: col.name.clone(),
117 expected: col.column_type,
118 });
119 }
120
121 // Write fixed-size value.
122 if let Some(offset) = self.fixed_offsets[i] {
123 let dst = fixed_start + offset;
124 encode_fixed(&mut buf[dst..], &col.column_type, val);
125 }
126 // Variable-length values are handled in the offset table pass below.
127 }
128
129 // 3. Variable-length fields: build offset table + variable data.
130 let offset_table_start = self.header_size + self.fixed_section_size;
131 let mut var_data: Vec<u8> = Vec::new();
132
133 for (var_idx, &col_idx) in self.var_indices.iter().enumerate() {
134 // Write current offset.

Callers 15

encode_rowsFunction · 0.45
encode_bitemporalMethod · 0.45
encode_basic_rowFunction · 0.45
encode_with_nullsFunction · 0.45
encode_null_violationFunction · 0.45
encode_type_mismatchFunction · 0.45
encode_timestampFunction · 0.45
encode_timestamptzFunction · 0.45

Calls 6

encode_fixedFunction · 0.85
encode_variableFunction · 0.85
acceptsMethod · 0.80
lenMethod · 0.45
iterMethod · 0.45
cloneMethod · 0.45

Tested by 15

encode_basic_rowFunction · 0.36
encode_with_nullsFunction · 0.36
encode_null_violationFunction · 0.36
encode_type_mismatchFunction · 0.36
encode_timestampFunction · 0.36
encode_timestamptzFunction · 0.36
encode_json_nullFunction · 0.36
encode_vectorFunction · 0.36