fn read_chunks(
        &self,
        blob_offset: u64,
        blob_size: usize,
        chunks: &[BlobIoChunk],
    ) -> Result<Vec<Vec<u8>>> {
        // Read requested data from the backend by altogether.
        let mut c_buf = alloc_buf(blob_size);
        let nr_read = self
            .reader()
            .read(c_buf.as_mut_slice(), blob_offset)
            .map_err(|e| eio!(e))?;
        if nr_read != blob_size {
            return Err(eio!(format!(
                "request for {} bytes but got {} bytes",
                blob_size, nr_read
            )));
        }

        let mut last = blob_offset;
        let mut buffers: Vec<Vec<u8>> = Vec::with_capacity(chunks.len());
        for chunk in chunks {
            // Ensure BlobIoChunk is valid and continuous.
            let offset = chunk.compress_offset();
            let size = chunk.compress_size();
            let d_size = chunk.uncompress_size() as usize;
            if offset != last
                || offset - blob_offset > usize::MAX as u64
                || offset.checked_add(size as u64).is_none()
                || ((!self.is_stargz() && d_size as u64 > RAFS_MAX_CHUNK_SIZE)
                    || (self.is_stargz() && d_size > 4 << 20))
            {
                return Err(eio!(format!("chunks to read_chunks() is invalid, offset {} last {} blob_offset {} d_size {}",
                                        offset, last, blob_offset, d_size)));
            }

            let offset_merged = (offset - blob_offset) as usize;
            let end_merged = offset_merged + size as usize;
            let buf = &c_buf[offset_merged..end_merged];
            let mut buffer = alloc_buf(d_size);

            self.process_raw_chunk(chunk, buf, None, &mut buffer, chunk.is_compressed(), false)?;
            buffers.push(buffer);
            last = offset + size as u64;
        }

        Ok(buffers)
    }
/// Read multiple chunks from the blob cache in batch mode.
///
/// This is an interface to optimize chunk data fetch performance by merging multiple continuous
/// chunks into one backend request. Callers must ensure that chunks in `chunks` covers a
/// continuous range, and the range exactly matches [`blob_offset`..`blob_offset` + `blob_size`].
/// Function `read_chunks()` returns one buffer containing decompressed chunk data for each
/// entry in the `chunks` array in corresponding order.
///
/// This method returns success only if all requested data are successfully fetched.
Read multiple chunks from the blob cache in batch mode.
This is an interface to optimize chunk data fetch performance by merging multiple continuous
chunks into one backend request.

This method returns success only if all requested data are successfully fetched.
Read multiple chunks from the blob cache in batch mode . This is an interface to optimize chunk data fetch performance by merging multiple continuous chunks into one backend request . This method returns success only if all requested data are successfully fetched .
fn read_chunks(
        &self,
        blob_offset: u64,
        blob_size: usize,
        chunks: &[BlobIoChunk],
    ) -> Result<Vec<Vec<u8>>> {
        // Read requested data from the backend by altogether.
        let mut c_buf = alloc_buf(blob_size);
        let nr_read = self
            .reader()
            .read(c_buf.as_mut_slice(), blob_offset)
            .map_err(|e| eio!(e))?;
        if nr_read != blob_size {
            return Err(eio!(format!(
                "request for {} bytes but got {} bytes",
                blob_size, nr_read
            )));
        }
        let mut last = blob_offset;
        let mut buffers: Vec<Vec<u8>> = Vec::with_capacity(chunks.len());
        for chunk in chunks {
            // Ensure BlobIoChunk is valid and continuous.
            let offset = chunk.compress_offset();
            let size = chunk.compress_size();
            let d_size = chunk.uncompress_size() as usize;
            if offset != last
                || offset - blob_offset > usize::MAX as u64
                || offset.checked_add(size as u64).is_none()
                || ((!self.is_stargz() && d_size as u64 > RAFS_MAX_CHUNK_SIZE)
                    || (self.is_stargz() && d_size > 4 << 20))
            {
                return Err(eio!(format!("chunks to read_chunks() is invalid, offset {} last {} blob_offset {} d_size {}",
                                        offset, last, blob_offset, d_size)));
            }
            let offset_merged = (offset - blob_offset) as usize;
            let end_merged = offset_merged + size as usize;
            let buf = &c_buf[offset_merged..end_merged];
            let mut buffer = alloc_buf(d_size);
            self.process_raw_chunk(chunk, buf, None, &mut buffer, chunk.is_compressed(), false)?;
            buffers.push(buffer);
            last = offset + size as u64;
        }
        Ok(buffers)
    }
fn read_chunks ( & self , blob_offset : u64 , blob_size : usize , chunks : & [ BlobIoChunk ] , ) -> Result < Vec < Vec < u8 > > > { // Read requested data from the backend by altogether. let mut c_buf = alloc_buf ( blob_size ) ; let nr_read = self . reader ( ) . read ( c_buf . as_mut_slice ( ) , blob_offset ) . map_err ( | e | eio ! ( e ) ) ? ; if nr_read != blob_size { return Err ( eio ! ( format ( " " blob_size nr_read ) ) ) ; } let mut last = blob_offset ; let mut buffers : Vec < Vec < u8 > > = Vec :: with_capacity ( chunks . len ( ) ) ; for chunk in chunks { // Ensure BlobIoChunk is valid and continuous. let offset = chunk . compress_offset ( ) ; let size = chunk . compress_size ( ) ; let d_size = chunk . uncompress_size ( ) as usize ; if offset != last || offset - blob_offset > usize :: MAX as u64 || offset . checked_add ( size as u64 ) . is_none ( ) || ( ( ! self . is_stargz ( ) && d_size as u64 > RAFS_MAX_CHUNK_SIZE ) || ( self . is_stargz ( ) && d_size > 4 << 20 ) ) { return Err ( eio ! ( format ( " " offset last blob_offset d_size ) ) ) ; } let offset_merged = ( offset - blob_offset ) as usize ; let end_merged = offset_merged + size as usize ; let buf = & c_buf [ offset_merged .. end_merged ] ; let mut buffer = alloc_buf ( d_size ) ; self . process_raw_chunk ( chunk , buf , None , & mut buffer , chunk . is_compressed ( ) , false ) ? ; buffers . push ( buffer ) ; last = offset + size as u64 ; } Ok ( buffers ) }
Read multiple chunks from the blob cache in batch mode.
Read multiple chunks from the blob cache in batch mode .
&self
blob_offset
u64
blob_size
usize
chunks
&[BlobIoChunk]
&self
blob_offset
u64
blob_size
usize
chunks
&[BlobIoChunk]