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

Function unpack

nodedb-fts/src/codec/bitpack.rs:77–116  ·  view source on GitHub ↗

Unpack values from a bitpacked buffer. Returns the unpacked `Vec `. Uses the scalar path. For SIMD-accelerated unpacking, use `super::simd_unpack`.

(buf: &[u8])

Source from the content-addressed store, hash-verified

75/// Returns the unpacked `Vec<u32>`. Uses the scalar path.
76/// For SIMD-accelerated unpacking, use `super::simd_unpack`.
77pub fn unpack(buf: &[u8]) -> Vec<u32> {
78 if buf.len() < 3 {
79 return Vec::new();
80 }
81
82 let num_values = u16::from_le_bytes([buf[0], buf[1]]) as usize;
83 let bit_width = buf[2];
84
85 if num_values == 0 || bit_width == 0 {
86 return vec![0; num_values];
87 }
88
89 let mask = if bit_width >= 32 {
90 u32::MAX
91 } else {
92 (1u32 << bit_width) - 1
93 };
94
95 let data = &buf[3..];
96 let mut values = Vec::with_capacity(num_values);
97 let mut bit_pos = 0u64;
98
99 for _ in 0..num_values {
100 let byte_idx = (bit_pos / 8) as usize;
101 let bit_offset = (bit_pos % 8) as u32;
102
103 // Read up to 8 bytes starting at byte_idx (handles spanning).
104 let mut wide_bytes = [0u8; 8];
105 let avail = data.len().saturating_sub(byte_idx).min(8);
106 wide_bytes[..avail].copy_from_slice(&data[byte_idx..byte_idx + avail]);
107 let wide = u64::from_le_bytes(wide_bytes);
108
109 let val = ((wide >> bit_offset) as u32) & mask;
110 values.push(val);
111
112 bit_pos += bit_width as u64;
113 }
114
115 values
116}
117
118#[cfg(test)]
119mod tests {

Callers 2

roundtrip_basicFunction · 0.70
from_bytesMethod · 0.50

Calls 2

lenMethod · 0.45
pushMethod · 0.45

Tested by 1

roundtrip_basicFunction · 0.56