pub fn generate_coding_shreds(
        slot: Slot,
        fec_rate: f32,
        data_shred_batch: &[Shred],
        version: u16,
        max_coding_shreds: bool,
    ) -> Vec<Shred> {
        assert!(!data_shred_batch.is_empty());
        if fec_rate != 0.0 {
            let num_data = data_shred_batch.len();
            // always generate at least 1 coding shred even if the fec_rate doesn't allow it
            let shred_count = if max_coding_shreds {
                MAX_DATA_SHREDS_PER_FEC_BLOCK as usize
            } else {
                num_data
            };
            let num_coding = Self::calculate_num_coding_shreds(shred_count as f32, fec_rate);
            if num_coding > num_data {
                trace!(
                    "Generated more codes ({}) than data shreds ({})",
                    num_coding,
                    num_data
                );
            }
            let session =
                Session::new(num_data, num_coding).expect("Failed to create erasure session");
            let start_index = data_shred_batch[0].common_header.index;

            // All information after coding shred field in a data shred is encoded
            let valid_data_len = PACKET_DATA_SIZE - SIZE_OF_DATA_SHRED_IGNORED_TAIL;
            let data_ptrs: Vec<_> = data_shred_batch
                .iter()
                .map(|data| &data.payload[..valid_data_len])
                .collect();

            // Create empty coding shreds, with correctly populated headers
            let mut coding_shreds = Vec::with_capacity(num_coding);
            (0..num_coding).for_each(|i| {
                let (header, coding_header) = Self::new_coding_shred_header(
                    slot,
                    start_index + i as u32,
                    start_index,
                    num_data,
                    num_coding,
                    i,
                    version,
                );
                let shred =
                    Shred::new_empty_from_header(header, DataShredHeader::default(), coding_header);
                coding_shreds.push(shred.payload);
            });

            // Grab pointers for the coding blocks
            let coding_block_offset = SIZE_OF_COMMON_SHRED_HEADER + SIZE_OF_CODING_SHRED_HEADER;
            let mut coding_ptrs: Vec<_> = coding_shreds
                .iter_mut()
                .map(|buffer| &mut buffer[coding_block_offset..])
                .collect();

            // Create coding blocks
            session
                .encode(&data_ptrs, coding_ptrs.as_mut_slice())
                .expect("Failed in erasure encode");

            // append to the shred list
            coding_shreds
                .into_iter()
                .enumerate()
                .map(|(i, payload)| {
                    let (common_header, coding_header) = Self::new_coding_shred_header(
                        slot,
                        start_index + i as u32,
                        start_index,
                        num_data,
                        num_coding,
                        i,
                        version,
                    );
                    Shred {
                        common_header,
                        data_header: DataShredHeader::default(),
                        coding_header,
                        payload,
                    }
                })
                .collect()
        } else {
            vec![]
        }
    }
/// Generates coding shreds for the data shreds in the current FEC set
Generates coding shreds for the data shreds in the current FEC set
Generates coding shreds for the data shreds in the current FEC set
pub fn generate_coding_shreds(
        slot: Slot,
        fec_rate: f32,
        data_shred_batch: &[Shred],
        version: u16,
        max_coding_shreds: bool,
    ) -> Vec<Shred> {
        assert!(!data_shred_batch.is_empty());
        if fec_rate != 0.0 {
            let num_data = data_shred_batch.len();
            // always generate at least 1 coding shred even if the fec_rate doesn't allow it
            let shred_count = if max_coding_shreds {
                MAX_DATA_SHREDS_PER_FEC_BLOCK as usize
            } else {
                num_data
            };
            let num_coding = Self::calculate_num_coding_shreds(shred_count as f32, fec_rate);
            if num_coding > num_data {
                trace!(
                    "Generated more codes ({}) than data shreds ({})",
                    num_coding,
                    num_data
                );
            }
            let session =
                Session::new(num_data, num_coding).expect("Failed to create erasure session");
            let start_index = data_shred_batch[0].common_header.index;
            // All information after coding shred field in a data shred is encoded
            let valid_data_len = PACKET_DATA_SIZE - SIZE_OF_DATA_SHRED_IGNORED_TAIL;
            let data_ptrs: Vec<_> = data_shred_batch
                .iter()
                .map(|data| &data.payload[..valid_data_len])
                .collect();
            // Create empty coding shreds, with correctly populated headers
            let mut coding_shreds = Vec::with_capacity(num_coding);
            (0..num_coding).for_each(|i| {
                let (header, coding_header) = Self::new_coding_shred_header(
                    slot,
                    start_index + i as u32,
                    start_index,
                    num_data,
                    num_coding,
                    i,
                    version,
                );
                let shred =
                    Shred::new_empty_from_header(header, DataShredHeader::default(), coding_header);
                coding_shreds.push(shred.payload);
            });
            // Grab pointers for the coding blocks
            let coding_block_offset = SIZE_OF_COMMON_SHRED_HEADER + SIZE_OF_CODING_SHRED_HEADER;
            let mut coding_ptrs: Vec<_> = coding_shreds
                .iter_mut()
                .map(|buffer| &mut buffer[coding_block_offset..])
                .collect();
            // Create coding blocks
            session
                .encode(&data_ptrs, coding_ptrs.as_mut_slice())
                .expect("Failed in erasure encode");
            // append to the shred list
            coding_shreds
                .into_iter()
                .enumerate()
                .map(|(i, payload)| {
                    let (common_header, coding_header) = Self::new_coding_shred_header(
                        slot,
                        start_index + i as u32,
                        start_index,
                        num_data,
                        num_coding,
                        i,
                        version,
                    );
                    Shred {
                        common_header,
                        data_header: DataShredHeader::default(),
                        coding_header,
                        payload,
                    }
                })
                .collect()
        } else {
            vec![]
        }
    }
pub fn generate_coding_shreds ( slot : Slot , fec_rate : f32 , data_shred_batch : & [ Shred ] , version : u16 , max_coding_shreds : bool , ) -> Vec < Shred > { assert ! ( data_shred_batch is_empty ( ) ) ; if fec_rate != 0.0 { let num_data = data_shred_batch . len ( ) ; // always generate at least 1 coding shred even if the fec_rate doesn't allow it let shred_count = if max_coding_shreds { MAX_DATA_SHREDS_PER_FEC_BLOCK as usize } else { num_data } ; let num_coding = Self :: calculate_num_coding_shreds ( shred_count as f32 , fec_rate ) ; if num_coding > num_data { trace ! ( " " num_coding num_data ) ; } let session = Session :: new ( num_data , num_coding ) . expect ( " " ) ; let start_index = data_shred_batch [ 0 ] . common_header . index ; // All information after coding shred field in a data shred is encoded let valid_data_len = PACKET_DATA_SIZE - SIZE_OF_DATA_SHRED_IGNORED_TAIL ; let data_ptrs : Vec < _ > = data_shred_batch . iter ( ) . map ( | data | & data . payload [ .. valid_data_len ] ) . collect ( ) ; // Create empty coding shreds, with correctly populated headers let mut coding_shreds = Vec :: with_capacity ( num_coding ) ; ( 0 .. num_coding ) . for_each ( | i | { let ( header , coding_header ) = Self :: new_coding_shred_header ( slot , start_index + i as u32 , start_index , num_data , num_coding , i , version , ) ; let shred = Shred :: new_empty_from_header ( header , DataShredHeader :: default ( ) , coding_header ) ; coding_shreds . push ( shred . payload ) ; } ) ; // Grab pointers for the coding blocks let coding_block_offset = SIZE_OF_COMMON_SHRED_HEADER + SIZE_OF_CODING_SHRED_HEADER ; let mut coding_ptrs : Vec < _ > = coding_shreds . iter_mut ( ) . map ( | buffer | & mut buffer [ coding_block_offset .. ] ) . collect ( ) ; // Create coding blocks session . encode ( & data_ptrs , coding_ptrs . as_mut_slice ( ) ) . expect ( " " ) ; // append to the shred list coding_shreds . into_iter ( ) . enumerate ( ) . map ( | ( i , payload ) | { let ( common_header , coding_header ) = Self :: new_coding_shred_header ( slot , start_index + i as u32 , start_index , num_data , num_coding , i , version , ) ; Shred { common_header , data_header : DataShredHeader :: default ( ) , coding_header , payload , } } ) . collect ( ) } else { vec ! [ ] } }
Generates coding shreds for the data shreds in the current FEC set
Generates coding shreds for the data shreds in the current FEC set
slot
Slot
fec_rate
f32
data_shred_batch
&[Shred]
version
u16
max_coding_shreds
bool
slot
Slot
fec_rate
f32
data_shred_batch
&[Shred]
version
u16
max_coding_shreds
bool