/// Dump blob file and generate chunks
Dump blob file and generate chunks
Dump blob file and generate chunks
fn dump_blob(&mut self) -> Result<(Sha256, usize, usize)> {
        // Sort readahead list by file size for better prefetch
        let mut readahead_files = self
            .readahead_files
            .values()
            .filter_map(|index| index.as_ref())
            .collect::<Vec<&u64>>();
        readahead_files.sort_by_key(|index| self.nodes[**index as usize - 1].inode.i_size);
        let blob_index = self.blob_table.entries.len() as u32;
        let mut blob_readahead_size = 0usize;
        let mut blob_size = 0usize;
        let mut compress_offset = 0u64;
        let mut decompress_offset = 0u64;
        let mut blob_hash = Sha256::new();
        match self.source_type {
            SourceType::Directory => {
                // Dump readahead nodes
                for index in &readahead_files {
                    let node = self.nodes.get_mut(**index as usize - 1).unwrap();
                    debug!("[{}]\treadahead {}", node.overlay, node);
                    if node.overlay == Overlay::UpperAddition
                        || node.overlay == Overlay::UpperModification
                    {
                        blob_readahead_size += node.dump_blob(
                            &mut self.f_blob,
                            &mut blob_hash,
                            &mut compress_offset,
                            &mut decompress_offset,
                            &mut self.chunk_cache,
                            self.compressor,
                            self.digester,
                            blob_index,
                        )?;
                    }
                }
                blob_size += blob_readahead_size;
                // Dump other nodes
                for node in &mut self.nodes {
                    if self.readahead_files.get(&node.rootfs()).is_some() {
                        continue;
                    }
                    // Ignore lower layer node when dump blob
                    debug!("[{}]\t{}", node.overlay, node);
                    if !node.is_dir()
                        && (node.overlay == Overlay::UpperAddition
                            || node.overlay == Overlay::UpperModification)
                    {
                        blob_size += node.dump_blob(
                            &mut self.f_blob,
                            &mut blob_hash,
                            &mut compress_offset,
                            &mut decompress_offset,
                            &mut self.chunk_cache,
                            self.compressor,
                            self.digester,
                            blob_index,
                        )?;
                    }
                }
            }
            SourceType::StargzIndex => {
                // Set blob index and inode digest for upper nodes
                for node in &mut self.nodes {
                    if node.overlay.lower_layer() {
                        continue;
                    }
                    let mut inode_hasher = RafsDigest::hasher(digest::Algorithm::Sha256);
                    for chunk in node.chunks.iter_mut() {
                        (*chunk).blob_index = blob_index;
                        inode_hasher.digest_update(chunk.block_id.as_ref());
                    }
                    if node.is_symlink() {
                        node.inode.i_digest = RafsDigest::from_buf(
                            node.symlink.as_ref().unwrap().as_bytes(),
                            digest::Algorithm::Sha256,
                        );
                    } else {
                        node.inode.i_digest = inode_hasher.digest_finalize();
                    }
                }
            }
        }
        Ok((blob_hash, blob_size, blob_readahead_size))
    }
fn dump_blob ( & mut self ) -> Result < ( Sha256 , usize , usize ) > { // Sort readahead list by file size for better prefetch let mut readahead_files = self . readahead_files . values ( ) . filter_map ( | index | index . as_ref ( ) ) . collect :: < Vec < & u64 > > ( ) ; readahead_files . sort_by_key ( | index | self . nodes [ * * index as usize - 1 ] . inode . i_size ) ; let blob_index = self . blob_table . entries . len ( ) as u32 ; let mut blob_readahead_size = 0usize ; let mut blob_size = 0usize ; let mut compress_offset = 0u64 ; let mut decompress_offset = 0u64 ; let mut blob_hash = Sha256 :: new ( ) ; match self . source_type { SourceType :: Directory => { // Dump readahead nodes for index in & readahead_files { let node = self . nodes . get_mut ( * * index as usize - 1 ) . unwrap ( ) ; debug ! ( " \t " node overlay node ) ; if node . overlay == Overlay :: UpperAddition || node . overlay == Overlay :: UpperModification { blob_readahead_size += node . dump_blob ( & mut self . f_blob , & mut blob_hash , & mut compress_offset , & mut decompress_offset , & mut self . chunk_cache , self . compressor , self . digester , blob_index , ) ? ; } } blob_size += blob_readahead_size ; // Dump other nodes for node in & mut self . nodes { if self . readahead_files . get ( & node . rootfs ( ) ) . is_some ( ) { continue ; } // Ignore lower layer node when dump blob debug ! ( " \t " node overlay node ) ; if ! node . is_dir ( ) && ( node . overlay == Overlay :: UpperAddition || node . overlay == Overlay :: UpperModification ) { blob_size += node . dump_blob ( & mut self . f_blob , & mut blob_hash , & mut compress_offset , & mut decompress_offset , & mut self . chunk_cache , self . compressor , self . digester , blob_index , ) ? ; } } } SourceType :: StargzIndex => { // Set blob index and inode digest for upper nodes for node in & mut self . nodes { if node . overlay . lower_layer ( ) { continue ; } let mut inode_hasher = RafsDigest :: hasher ( digest :: Algorithm :: Sha256 ) ; for chunk in node . chunks . iter_mut ( ) { ( * chunk ) . blob_index = blob_index ; inode_hasher . digest_update ( chunk . block_id . as_ref ( ) ) ; } if node . is_symlink ( ) { node . inode . i_digest = RafsDigest :: from_buf ( node . symlink . as_ref ( ) . unwrap ( ) . as_bytes ( ) , digest :: Algorithm :: Sha256 , ) ; } else { node . inode . i_digest = inode_hasher . digest_finalize ( ) ; } } } } Ok ( ( blob_hash , blob_size , blob_readahead_size ) ) }
Dump blob file and generate chunks
Dump blob file and generate chunks
&mut self