1use std::vec;
2
3use crate::{
4 codec::{self, Codec},
5 Matrix2D, Matrix3D,
6};
7use eyre::{eyre, Result};
8
9pub struct DataSquare {
12 pub square_row: Matrix3D,
13 pub square_col: Matrix3D,
14 pub width: usize,
15 pub original_width: usize,
16 pub chunk_size: usize,
17 pub row_roots: Matrix2D,
18 pub col_roots: Matrix2D,
19 pub codec: Box<dyn Codec>,
20}
21
22impl DataSquare {
23 pub fn new(original_data: Matrix2D) -> Result<Self> {
37 if original_data.is_empty() {
39 return Err(eyre!("Data must not be empty."));
40 }
41
42 let data_len = f64::from(original_data.len() as u32);
44 let width = data_len.sqrt();
45 if width * width != data_len {
46 return Err(eyre!("Number of chunks must be a square number."));
47 }
48 let width: usize = width as usize;
49
50 let chunk_size = original_data[0].len();
52 for row in original_data.iter() {
53 if row.len() != chunk_size {
54 return Err(eyre!("All chunks must be of equal size."));
55 }
56 }
57
58 let mut square_row: Matrix3D = vec![vec![]; width];
60 for i in 0..width {
61 square_row[i] = original_data[i * width..i * width + width].to_vec();
62 }
63
64 let mut square_col: Matrix3D = vec![vec![]; width];
66 for j in 0..width {
67 for i in 0..width {
68 square_col[j].push(original_data[i * width + j].to_vec());
69 }
70 }
71
72 let codec = codec::new(original_data.len())?;
73
74 Ok(Self {
75 square_row,
76 square_col,
77 width,
78 original_width: width,
79 chunk_size,
80 row_roots: vec![],
81 col_roots: vec![],
82 codec,
83 })
84 }
85
86 pub fn erasure_extend_square(&mut self) -> Result<()> {
97 self.original_width = self.width;
98 self.extend_square()?;
100
101 for i in 0..self.original_width {
102 self.erasure_extend_row(i)?;
104 self.erasure_extend_col(i)?;
106 }
107
108 Ok(())
109 }
110
111 fn extend_square(&mut self) -> Result<()> {
116 self.width *= 2;
117 let filler_chunk = vec![Default::default(); self.chunk_size];
118 let mut filler_row: Vec<Vec<u8>> = vec![];
119 for _ in 0..self.width {
120 filler_row.push(filler_chunk.clone());
121 }
122 for row in self.square_row.iter_mut() {
124 for _ in 0..self.original_width {
125 row.push(filler_chunk.clone());
126 }
127 }
128
129 for i in self.original_width..self.width {
130 self.square_row.insert(i, filler_row.clone());
131 }
132 self.square_col = vec![vec![]; self.width];
134 for (j, col) in self.square_col.iter_mut().enumerate().take(self.width) {
135 for i in 0..self.width {
136 col.push(self.square_row[i][j].to_vec());
137 }
138 }
139
140 Ok(())
141 }
142
143 fn erasure_extend_row(&mut self, row_index: usize) -> Result<()> {
154 let codec = codec::new(self.original_width)?;
157 let shares = self.square_row[row_index][0..self.original_width].to_vec();
159 let encoded_shares = codec.encode(shares)?;
160 for (i, share) in encoded_shares.iter().enumerate() {
162 self.square_row[row_index][self.original_width + i] = share.clone();
163 self.square_col[self.original_width + i][row_index] = share.clone();
164 }
165 Ok(())
166 }
167
168 fn erasure_extend_col(&mut self, col_index: usize) -> Result<()> {
179 let codec = codec::new(self.original_width)?;
182 let shares = self.square_col[col_index][0..self.original_width].to_vec();
184
185 let encoded_shares = codec.encode(shares)?;
186 for (i, share) in encoded_shares.iter().enumerate() {
188 self.square_row[self.original_width + i][col_index] = share.clone();
189 self.square_col[col_index][self.original_width + i] = share.clone();
190 }
191 Ok(())
192 }
193}
194
195pub struct ExtendedDataSquare {
197 pub data_square: DataSquare,
198}