Encode one axis of a `DimDict` into a byte vector.
(dict: &DimDict, out: &mut Vec<u8>)
| 85 | |
| 86 | /// Encode one axis of a `DimDict` into a byte vector. |
| 87 | pub fn encode_coord_axis(dict: &DimDict, out: &mut Vec<u8>) -> ArrayResult<()> { |
| 88 | // Dict entries: tag + count + values. Per-axis homogeneous-Int64 dicts |
| 89 | // are batch-encoded with fastlanes; mixed/string dicts fall back to |
| 90 | // per-value zerompk msgpack. |
| 91 | if let Some(ints) = try_encode_int64_dict(&dict.values) { |
| 92 | out.push(DICT_TAG_INT64_FASTLANES); |
| 93 | out.extend_from_slice(&(ints.len() as u32).to_le_bytes()); |
| 94 | let encoded = nodedb_codec::fastlanes::encode(&ints); |
| 95 | out.extend_from_slice(&(encoded.len() as u32).to_le_bytes()); |
| 96 | out.extend_from_slice(&encoded); |
| 97 | } else { |
| 98 | out.push(DICT_TAG_MSGPACK); |
| 99 | let dict_count = dict.values.len() as u32; |
| 100 | out.extend_from_slice(&dict_count.to_le_bytes()); |
| 101 | for cv in &dict.values { |
| 102 | let bytes = zerompk::to_msgpack_vec(cv).map_err(|e| ArrayError::SegmentCorruption { |
| 103 | detail: format!("coord dict encode: {e}"), |
| 104 | })?; |
| 105 | let len = bytes.len() as u32; |
| 106 | out.extend_from_slice(&len.to_le_bytes()); |
| 107 | out.extend_from_slice(&bytes); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Index stream: count + zigzag-varint deltas. |
| 112 | let idx_count = dict.indices.len() as u32; |
| 113 | out.extend_from_slice(&idx_count.to_le_bytes()); |
| 114 | let mut prev: i64 = 0; |
| 115 | for &idx in &dict.indices { |
| 116 | let cur = idx as i64; |
| 117 | let delta = cur - prev; |
| 118 | write_varint(out, zigzag_encode(delta)); |
| 119 | prev = cur; |
| 120 | } |
| 121 | Ok(()) |
| 122 | } |
| 123 | |
| 124 | /// Decode one axis from `data[pos..]`, advancing `pos` past consumed bytes. |
| 125 | pub fn decode_coord_axis(data: &[u8], pos: &mut usize) -> ArrayResult<DimDict> { |
no test coverage detected