reed_solomon_16/engine/
shards.rs1use std::ops::{Bound, Index, IndexMut, RangeBounds};
2
3pub(crate) struct Shards {
7 shard_count: usize,
8 shard_bytes: usize,
9
10 data: Vec<u8>,
12}
13
14impl Shards {
15 pub(crate) fn as_ref_mut(&mut self) -> ShardsRefMut {
16 ShardsRefMut::new(self.shard_count, self.shard_bytes, self.data.as_mut())
17 }
18
19 pub(crate) fn new() -> Self {
20 Self {
21 shard_count: 0,
22 shard_bytes: 0,
23 data: Vec::new(),
24 }
25 }
26
27 pub(crate) fn resize(&mut self, shard_count: usize, shard_bytes: usize) {
28 assert!(shard_bytes > 0 && shard_bytes & 63 == 0);
29
30 self.shard_count = shard_count;
31 self.shard_bytes = shard_bytes;
32
33 self.data.resize(shard_count * shard_bytes, 0);
34 }
35}
36
37impl Index<usize> for Shards {
41 type Output = [u8];
42 fn index(&self, index: usize) -> &Self::Output {
43 &self.data[index * self.shard_bytes..(index + 1) * self.shard_bytes]
44 }
45}
46
47impl IndexMut<usize> for Shards {
51 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
52 &mut self.data[index * self.shard_bytes..(index + 1) * self.shard_bytes]
53 }
54}
55
56pub struct ShardsRefMut<'a> {
61 shard_count: usize,
62 shard_bytes: usize,
63
64 data: &'a mut [u8],
66}
67
68impl<'a> ShardsRefMut<'a> {
69 pub fn dist2_mut(&mut self, mut pos: usize, mut dist: usize) -> (&mut [u8], &mut [u8]) {
79 pos *= self.shard_bytes;
80 dist *= self.shard_bytes;
81
82 let (a, b) = self.data[pos..].split_at_mut(dist);
83 (&mut a[..self.shard_bytes], &mut b[..self.shard_bytes])
84 }
85
86 pub fn dist4_mut(
98 &mut self,
99 mut pos: usize,
100 mut dist: usize,
101 ) -> (&mut [u8], &mut [u8], &mut [u8], &mut [u8]) {
102 pos *= self.shard_bytes;
103 dist *= self.shard_bytes;
104
105 let (ab, cd) = self.data[pos..].split_at_mut(dist * 2);
106 let (a, b) = ab.split_at_mut(dist);
107 let (c, d) = cd.split_at_mut(dist);
108
109 (
110 &mut a[..self.shard_bytes],
111 &mut b[..self.shard_bytes],
112 &mut c[..self.shard_bytes],
113 &mut d[..self.shard_bytes],
114 )
115 }
116
117 pub fn is_empty(&self) -> bool {
119 self.shard_count == 0
120 }
121
122 pub fn len(&self) -> usize {
124 self.shard_count
125 }
126
127 pub fn new(shard_count: usize, shard_bytes: usize, data: &'a mut [u8]) -> Self {
133 Self {
134 shard_count,
135 shard_bytes,
136 data: &mut data[..shard_count * shard_bytes],
137 }
138 }
139
140 pub fn split_at_mut(&mut self, mid: usize) -> (ShardsRefMut, ShardsRefMut) {
143 let (a, b) = self.data.split_at_mut(mid * self.shard_bytes);
144 (
145 ShardsRefMut::new(mid, self.shard_bytes, a),
146 ShardsRefMut::new(self.shard_count - mid, self.shard_bytes, b),
147 )
148 }
149
150 pub fn zero<R: RangeBounds<usize>>(&mut self, range: R) {
152 let start = match range.start_bound() {
153 Bound::Included(start) => start * self.shard_bytes,
154 Bound::Excluded(start) => (start + 1) * self.shard_bytes,
155 Bound::Unbounded => 0,
156 };
157
158 let end = match range.end_bound() {
159 Bound::Included(end) => (end + 1) * self.shard_bytes,
160 Bound::Excluded(end) => end * self.shard_bytes,
161 Bound::Unbounded => self.shard_count * self.shard_bytes,
162 };
163
164 self.data[start..end].fill(0);
165 }
166}
167
168impl<'a> Index<usize> for ShardsRefMut<'a> {
172 type Output = [u8];
173 fn index(&self, index: usize) -> &Self::Output {
174 &self.data[index * self.shard_bytes..(index + 1) * self.shard_bytes]
175 }
176}
177
178impl<'a> IndexMut<usize> for ShardsRefMut<'a> {
182 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
183 &mut self.data[index * self.shard_bytes..(index + 1) * self.shard_bytes]
184 }
185}
186
187impl<'a> ShardsRefMut<'a> {
191 pub(crate) fn copy_within(&mut self, mut src: usize, mut dest: usize, mut count: usize) {
192 src *= self.shard_bytes;
193 dest *= self.shard_bytes;
194 count *= self.shard_bytes;
195
196 self.data.copy_within(src..src + count, dest);
197 }
198
199 pub(crate) fn flat2_mut(
204 &mut self,
205 mut x: usize,
206 mut y: usize,
207 mut count: usize,
208 ) -> (&mut [u8], &mut [u8]) {
209 x *= self.shard_bytes;
210 y *= self.shard_bytes;
211 count *= self.shard_bytes;
212
213 if x < y {
214 let (head, tail) = self.data.split_at_mut(y);
215 (&mut head[x..x + count], &mut tail[..count])
216 } else {
217 let (head, tail) = self.data.split_at_mut(x);
218 (&mut tail[..count], &mut head[y..y + count])
219 }
220 }
221}