Retrieves item at `index` using RLE arithmetic. This calculates which shard holds the item, loads ONLY that shard, and returns the specific item.
(&self, index: usize)
| 1105 | /// This calculates which shard holds the item, loads ONLY that shard, |
| 1106 | /// and returns the specific item. |
| 1107 | pub fn get<T: ParcodeItem>(&self, index: usize) -> Result<T> { |
| 1108 | let payload = self.read_raw()?; |
| 1109 | if payload.len() < 8 { |
| 1110 | return Err(ParcodeError::Format("Not a valid container".into())); |
| 1111 | } |
| 1112 | |
| 1113 | let runs_data = payload.get(8..).unwrap_or(&[]); |
| 1114 | let shard_runs: Vec<ShardRun> = |
| 1115 | bincode::serde::decode_from_slice(runs_data, bincode::config::standard()) |
| 1116 | .map(|(obj, _)| obj) |
| 1117 | .map_err(|e| ParcodeError::Serialization(e.to_string()))?; |
| 1118 | |
| 1119 | let (target_shard_idx, index_in_shard) = self.resolve_rle_index(index, &shard_runs)?; |
| 1120 | |
| 1121 | let shard_node = self.get_child_by_index(target_shard_idx)?; |
| 1122 | |
| 1123 | let payload = shard_node.read_raw()?; |
| 1124 | let mut cursor = std::io::Cursor::new(payload.as_ref()); |
| 1125 | let children = shard_node.children()?; |
| 1126 | let mut child_iter = children.into_iter(); |
| 1127 | |
| 1128 | let shard_data: Vec<T> = T::read_slice_from_shard(&mut cursor, &mut child_iter)?; |
| 1129 | |
| 1130 | shard_data |
| 1131 | .into_iter() |
| 1132 | .nth(index_in_shard) |
| 1133 | .ok_or(ParcodeError::Internal("Shard index mismatch".into())) |
| 1134 | } |
| 1135 | |
| 1136 | /// Creates a streaming iterator over the collection. |
| 1137 | /// Memory usage is constant (size of one shard) regardless of total size. |
no test coverage detected