Decodes a single block of data The `f` function accepts a slice of the decoded data, it may be called multiple times
(row: &[u8], options: SortOptions, mut f: impl FnMut(&[u8]))
| 219 | /// Decodes a single block of data |
| 220 | /// The `f` function accepts a slice of the decoded data, it may be called multiple times |
| 221 | pub fn decode_blocks(row: &[u8], options: SortOptions, mut f: impl FnMut(&[u8])) -> usize { |
| 222 | let (non_empty_sentinel, continuation) = match options.descending { |
| 223 | true => (!NON_EMPTY_SENTINEL, !BLOCK_CONTINUATION), |
| 224 | false => (NON_EMPTY_SENTINEL, BLOCK_CONTINUATION), |
| 225 | }; |
| 226 | |
| 227 | if row[0] != non_empty_sentinel { |
| 228 | // Empty or null string |
| 229 | return 1; |
| 230 | } |
| 231 | |
| 232 | // Extracts the block length from the sentinel |
| 233 | let block_len = |sentinel: u8| match options.descending { |
| 234 | true => !sentinel as usize, |
| 235 | false => sentinel as usize, |
| 236 | }; |
| 237 | |
| 238 | let mut idx = 1; |
| 239 | for _ in 0..MINI_BLOCK_COUNT { |
| 240 | let sentinel = row[idx + MINI_BLOCK_SIZE]; |
| 241 | if sentinel != continuation { |
| 242 | f(&row[idx..idx + block_len(sentinel)]); |
| 243 | return idx + MINI_BLOCK_SIZE + 1; |
| 244 | } |
| 245 | f(&row[idx..idx + MINI_BLOCK_SIZE]); |
| 246 | idx += MINI_BLOCK_SIZE + 1; |
| 247 | } |
| 248 | |
| 249 | loop { |
| 250 | let sentinel = row[idx + BLOCK_SIZE]; |
| 251 | if sentinel != continuation { |
| 252 | f(&row[idx..idx + block_len(sentinel)]); |
| 253 | return idx + BLOCK_SIZE + 1; |
| 254 | } |
| 255 | f(&row[idx..idx + BLOCK_SIZE]); |
| 256 | idx += BLOCK_SIZE + 1; |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | /// Returns the number of bytes of encoded data |
| 261 | fn decoded_len(row: &[u8], options: SortOptions) -> usize { |
no outgoing calls
no test coverage detected