(&self, _: &[ChildRef])
| 80 | V: Serialize + Sync + ParcodeVisitor, |
| 81 | { |
| 82 | fn execute(&self, _: &[ChildRef]) -> Result<Vec<u8>> { |
| 83 | let count = self.items.len(); |
| 84 | if count == 0 { |
| 85 | return Ok(Vec::new()); |
| 86 | } |
| 87 | |
| 88 | // Temporary buffers for SOA components |
| 89 | let mut data_blob = Vec::new(); |
| 90 | let mut offsets = Vec::with_capacity(count * 4); |
| 91 | let mut hashes = Vec::with_capacity(count * 8); |
| 92 | |
| 93 | let mut cursor = std::io::Cursor::new(&mut data_blob); |
| 94 | |
| 95 | for (k, v) in &self.items { |
| 96 | // 1. Compute and store hash (for fast lookup) |
| 97 | hashes.extend_from_slice(&hash_key(k).to_le_bytes()); |
| 98 | |
| 99 | // 2. Record current offset in data blob (for random access) |
| 100 | let pos = u32::try_from(cursor.position()) |
| 101 | .map_err(|_| ParcodeError::Serialization("Data blob exceeds 4GB".into()))?; |
| 102 | offsets.extend_from_slice(&pos.to_le_bytes()); |
| 103 | |
| 104 | // 3. Serialize (K, V) tuple to data blob |
| 105 | // Both key and value are stored to enable collision resolution |
| 106 | // We serialize K using standard bincode, and V using serialize_shallow |
| 107 | // to respect chunkable fields. |
| 108 | bincode::serde::encode_into_std_write(k, &mut cursor, bincode::config::standard()) |
| 109 | .map_err(|e| ParcodeError::Serialization(e.to_string()))?; |
| 110 | |
| 111 | v.serialize_shallow(&mut cursor)?; |
| 112 | } |
| 113 | |
| 114 | // 4. Assemble final buffer with proper alignment |
| 115 | // Header: Count (4 bytes) |
| 116 | // Alignment target for Hashes is 8 bytes |
| 117 | // Current size: 4. Padding needed: 4 |
| 118 | |
| 119 | let hashes_size = count * 8; |
| 120 | let offsets_size = count * 4; |
| 121 | let total_size = 8 + hashes_size + offsets_size + data_blob.len(); |
| 122 | |
| 123 | let mut final_buf = Vec::with_capacity(total_size); |
| 124 | |
| 125 | // Write Count (u32 LE) |
| 126 | final_buf.extend_from_slice( |
| 127 | &u32::try_from(count) |
| 128 | .map_err(|_| ParcodeError::Serialization("Shard count exceeds u32".into()))? |
| 129 | .to_le_bytes(), |
| 130 | ); |
| 131 | |
| 132 | // Write Padding (4 bytes of zeros for 8-byte alignment) |
| 133 | final_buf.extend_from_slice(&[0u8; 4]); |
| 134 | |
| 135 | // Write Hashes (Aligned at offset 8) |
| 136 | final_buf.extend_from_slice(&hashes); |
| 137 | |
| 138 | // Write Offsets |
| 139 | final_buf.extend_from_slice(&offsets); |
nothing calls this directly
no test coverage detected