github.com/Microsoft/azure-vhd-utils@v0.0.0-20230613175315-7c30a3748a1b/vhdcore/block/dynamicDiskBlockFactory.go (about)

     1  package block
     2  
     3  import (
     4  	"github.com/Microsoft/azure-vhd-utils/vhdcore"
     5  	"github.com/Microsoft/azure-vhd-utils/vhdcore/block/bitmap"
     6  	"github.com/Microsoft/azure-vhd-utils/vhdcore/common"
     7  )
     8  
     9  // DynamicDiskBlockFactory is a type which is used for following purposes
    10  // To create a Block instance representing a dynamic disk block
    11  // To get the number of blocks in the dynamic disk
    12  // To get the block size of the block in dynamic disk
    13  // To get a Sector instance representing sector of dynamic disk's block
    14  // To get the logical footer range of fixed disk generated from the dynamic disk
    15  //
    16  type DynamicDiskBlockFactory struct {
    17  	params             *FactoryParams
    18  	bitmapFactory      *bitmap.Factory
    19  	sectorFactory      *SectorFactory
    20  	blockDataReader    DataReader
    21  	cachedDynamicBlock *Block
    22  }
    23  
    24  // NewDynamicDiskFactory creates a DynamicDiskBlockFactory instance which can be used to create a
    25  // Block objects representing dynamic disk block of a size specified in header BlockSize field
    26  // parameter params contains header, footer, BAT of dynamic disk and reader to read the disk.
    27  //
    28  func NewDynamicDiskFactory(params *FactoryParams) *DynamicDiskBlockFactory {
    29  	blockFactory := &DynamicDiskBlockFactory{params: params}
    30  
    31  	blockFactory.bitmapFactory = bitmap.NewFactory(blockFactory.params.VhdReader,
    32  		blockFactory.params.BlockAllocationTable)
    33  
    34  	blockFactory.sectorFactory = NewSectorFactory(blockFactory.params.VhdReader,
    35  		blockFactory.params.BlockAllocationTable.HasData,
    36  		blockFactory.params.BlockAllocationTable.GetBlockDataAddress)
    37  
    38  	blockFactory.blockDataReader = NewDynamicDiskBlockReader(blockFactory.params.VhdReader,
    39  		blockFactory.params.BlockAllocationTable,
    40  		blockFactory.params.VhdHeader.BlockSize)
    41  	return blockFactory
    42  }
    43  
    44  // GetBlockCount returns the number of blocks in the dynamic disk.
    45  //
    46  func (f *DynamicDiskBlockFactory) GetBlockCount() int64 {
    47  	return int64(f.params.BlockAllocationTable.BATEntriesCount)
    48  }
    49  
    50  // GetBlockSize returns the size of the 'data section' of block in bytes in the dynamic disk.
    51  //
    52  func (f *DynamicDiskBlockFactory) GetBlockSize() int64 {
    53  	return int64(f.params.VhdHeader.BlockSize)
    54  }
    55  
    56  // GetFooterRange returns the logical range of the footer when converting this dynamic vhd to fixed
    57  // logical range of footer is the absolute start and end byte offset of the footer.
    58  //
    59  func (f *DynamicDiskBlockFactory) GetFooterRange() *common.IndexRange {
    60  	return common.NewIndexRangeFromLength(f.GetBlockCount()*f.GetBlockSize(), vhdcore.VhdFooterSize)
    61  }
    62  
    63  // Create returns an instance of Block which represents a dynamic disk block, the parameter blockIndex
    64  // identifies the block. This function return error if the block cannot be created due to any read error.
    65  //
    66  func (f *DynamicDiskBlockFactory) Create(blockIndex uint32) (*Block, error) {
    67  	if f.cachedDynamicBlock == nil || f.cachedDynamicBlock.BlockIndex != blockIndex {
    68  		logicalRange := common.NewIndexRangeFromLength(int64(blockIndex)*f.GetBlockSize(), f.GetBlockSize())
    69  		f.cachedDynamicBlock = &Block{
    70  			BlockIndex:      blockIndex,
    71  			LogicalRange:    logicalRange,
    72  			VhdUniqueID:     f.params.VhdFooter.UniqueID,
    73  			BlockDataReader: f.blockDataReader,
    74  		}
    75  
    76  		if f.params.BlockAllocationTable.HasData(blockIndex) {
    77  			var err error
    78  			f.cachedDynamicBlock.BitMap, err = f.bitmapFactory.Create(blockIndex)
    79  			if err != nil {
    80  				return nil, err
    81  			}
    82  
    83  			f.cachedDynamicBlock.IsEmpty = false
    84  		} else {
    85  			f.cachedDynamicBlock.BitMap = nil
    86  			f.cachedDynamicBlock.IsEmpty = true
    87  		}
    88  	}
    89  
    90  	return f.cachedDynamicBlock, nil
    91  }
    92  
    93  // GetSector returns an instance of Sector in a dynamic disk, parameter block object identifying the block
    94  // containing the sector, the parameter sectorIndex identifies the sector in the block. This function return
    95  // error if the sector cannot be created due to any read error or if the requested sector index is invalid.
    96  //
    97  func (f *DynamicDiskBlockFactory) GetSector(block *Block, sectorIndex uint32) (*Sector, error) {
    98  	blockIndex := block.BlockIndex
    99  	if block.IsEmpty {
   100  		return f.sectorFactory.CreateEmptySector(blockIndex, sectorIndex), nil
   101  	}
   102  
   103  	return f.sectorFactory.Create(block, sectorIndex)
   104  }
   105  
   106  // GetBitmapFactory returns an instance of BitmapFactory that can be used to create the bitmap of a block
   107  // by reading block from dynamic disk.
   108  //
   109  func (f *DynamicDiskBlockFactory) GetBitmapFactory() *bitmap.Factory {
   110  	return f.bitmapFactory
   111  }