Serialize the block to bytes. Layout: ```text [doc_count: u16 LE] [packed_doc_id_deltas: len u32 LE + bytes] [packed_term_freqs: len u32 LE + bytes] [fieldnorms: doc_count bytes] [position_data: for each doc, count u16 LE + packed positions] ```
(&self)
| 113 | /// [position_data: for each doc, count u16 LE + packed positions] |
| 114 | /// ``` |
| 115 | pub fn to_bytes(&self) -> Vec<u8> { |
| 116 | let mut buf = Vec::new(); |
| 117 | |
| 118 | // Doc count. |
| 119 | buf.extend_from_slice(&(self.doc_ids.len() as u16).to_le_bytes()); |
| 120 | |
| 121 | // Delta-encoded, bitpacked surrogate IDs (raw u32 on disk). |
| 122 | let raw_ids: Vec<u32> = self.doc_ids.iter().map(|s| s.0).collect(); |
| 123 | let deltas = delta::encode(&raw_ids); |
| 124 | let packed_ids = bitpack::pack(&deltas); |
| 125 | buf.extend_from_slice(&(packed_ids.len() as u32).to_le_bytes()); |
| 126 | buf.extend_from_slice(&packed_ids); |
| 127 | |
| 128 | // Bitpacked term frequencies. |
| 129 | let packed_freqs = bitpack::pack(&self.term_freqs); |
| 130 | buf.extend_from_slice(&(packed_freqs.len() as u32).to_le_bytes()); |
| 131 | buf.extend_from_slice(&packed_freqs); |
| 132 | |
| 133 | // Fieldnorms (raw bytes, 1 per doc). |
| 134 | buf.extend_from_slice(&self.fieldnorms); |
| 135 | |
| 136 | // Position data: for each doc, [count: u16 LE][packed positions]. |
| 137 | for positions in &self.positions { |
| 138 | buf.extend_from_slice(&(positions.len() as u16).to_le_bytes()); |
| 139 | if !positions.is_empty() { |
| 140 | let packed_pos = bitpack::pack(positions); |
| 141 | buf.extend_from_slice(&(packed_pos.len() as u16).to_le_bytes()); |
| 142 | buf.extend_from_slice(&packed_pos); |
| 143 | } else { |
| 144 | buf.extend_from_slice(&0u16.to_le_bytes()); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | buf |
| 149 | } |
| 150 | |
| 151 | /// Deserialize a block from bytes. Returns `None` if malformed. |
| 152 | pub fn from_bytes(buf: &[u8]) -> Option<Self> { |