Partition a flat coord list by Hilbert tile and fan delete requests to owning shards. `coords` — each element is `(hilbert_prefix, zerompk-encoded single-coord bytes)`. `prefix_bits` — routing granularity (1–16). `wal_lsn` — WAL sequence number allocated by the Control Plane. Atomicity is per-shard only (same contract as `coord_put`).
(
params: &ArrayWriteCoordParams,
array_id_msgpack: Vec<u8>,
prefix_bits: u8,
wal_lsn: u64,
coords: &[(u64, Vec<u8>)],
dispatch: &Arc<dyn ShardRpcDispatch>,
circuit_breaker
| 125 | /// |
| 126 | /// Atomicity is per-shard only (same contract as `coord_put`). |
| 127 | pub async fn coord_delete( |
| 128 | params: &ArrayWriteCoordParams, |
| 129 | array_id_msgpack: Vec<u8>, |
| 130 | prefix_bits: u8, |
| 131 | wal_lsn: u64, |
| 132 | coords: &[(u64, Vec<u8>)], |
| 133 | dispatch: &Arc<dyn ShardRpcDispatch>, |
| 134 | circuit_breaker: &Arc<CircuitBreaker>, |
| 135 | ) -> Result<Vec<ArrayShardDeleteResp>> { |
| 136 | if coords.is_empty() { |
| 137 | return Ok(Vec::new()); |
| 138 | } |
| 139 | |
| 140 | let buckets = partition_delete_coords(coords, prefix_bits)?; |
| 141 | |
| 142 | let fo_params = FanOutPartitionedParams { |
| 143 | timeout_ms: params.timeout_ms, |
| 144 | source_node: params.source_node, |
| 145 | }; |
| 146 | |
| 147 | let encoded: Result<Vec<(u32, Vec<u8>)>> = buckets |
| 148 | .into_iter() |
| 149 | .map(|b| { |
| 150 | let req = ArrayShardDeleteReq { |
| 151 | array_id_msgpack: array_id_msgpack.clone(), |
| 152 | coords_msgpack: b.coords_msgpack, |
| 153 | wal_lsn, |
| 154 | representative_hilbert_prefix: b.representative_hilbert_prefix, |
| 155 | prefix_bits, |
| 156 | }; |
| 157 | zerompk::to_msgpack_vec(&req) |
| 158 | .map(|bytes| (b.vshard_id, bytes)) |
| 159 | .map_err(|e| ClusterError::Codec { |
| 160 | detail: format!("ArrayShardDeleteReq serialise (shard {}): {e}", b.vshard_id), |
| 161 | }) |
| 162 | }) |
| 163 | .collect(); |
| 164 | |
| 165 | let raw = fan_out_partitioned( |
| 166 | &fo_params, |
| 167 | super::super::opcodes::ARRAY_SHARD_DELETE_REQ, |
| 168 | &encoded?, |
| 169 | dispatch, |
| 170 | circuit_breaker, |
| 171 | ) |
| 172 | .await?; |
| 173 | |
| 174 | decode_resps::<ArrayShardDeleteResp>(&raw) |
| 175 | } |
no test coverage detected