Encode a batch of strings using FSST compression. Trains a symbol table on the input, then encodes each string as a sequence of symbol indices and escaped literals.
(strings: &[&[u8]])
| 154 | /// Trains a symbol table on the input, then encodes each string as a |
| 155 | /// sequence of symbol indices and escaped literals. |
| 156 | pub fn encode(strings: &[&[u8]]) -> Vec<u8> { |
| 157 | let table = SymbolTable::train(strings); |
| 158 | |
| 159 | // Encode each string. |
| 160 | let mut encoded_strings: Vec<Vec<u8>> = Vec::with_capacity(strings.len()); |
| 161 | for s in strings { |
| 162 | encoded_strings.push(encode_string(&table, s)); |
| 163 | } |
| 164 | |
| 165 | // Build wire format. |
| 166 | let mut out = Vec::new(); |
| 167 | |
| 168 | // Symbol table. |
| 169 | out.extend_from_slice(&(table.symbol_count() as u16).to_le_bytes()); |
| 170 | for sym in &table.symbols { |
| 171 | out.push(sym.len() as u8); |
| 172 | out.extend_from_slice(sym); |
| 173 | } |
| 174 | |
| 175 | // Encoded strings with offset table. |
| 176 | let total_encoded: usize = encoded_strings.iter().map(|s| s.len()).sum(); |
| 177 | out.extend_from_slice(&(total_encoded as u32).to_le_bytes()); |
| 178 | out.extend_from_slice(&(strings.len() as u32).to_le_bytes()); |
| 179 | |
| 180 | // Cumulative offsets. |
| 181 | let mut offset = 0u32; |
| 182 | for es in &encoded_strings { |
| 183 | offset += es.len() as u32; |
| 184 | out.extend_from_slice(&offset.to_le_bytes()); |
| 185 | } |
| 186 | |
| 187 | // Encoded data. |
| 188 | for es in &encoded_strings { |
| 189 | out.extend_from_slice(es); |
| 190 | } |
| 191 | |
| 192 | out |
| 193 | } |
| 194 | |
| 195 | /// Decode FSST-compressed data back to strings. |
| 196 | pub fn decode(data: &[u8]) -> Result<Vec<Vec<u8>>, CodecError> { |