func()

in component/azstorage/block_blob.go [1251:1356]


func (bb *BlockBlob) TruncateFile(name string, size int64) error {
	// log.Trace("BlockBlob::TruncateFile : name=%s, size=%d", name, size)
	attr, err := bb.GetAttr(name)
	if err != nil {
		log.Err("BlockBlob::TruncateFile : Failed to get attributes of file %s [%s]", name, err.Error())
		if err == syscall.ENOENT {
			return err
		}
	}
	if size == 0 || attr.Size == 0 {
		// If we are resizing to a value > 1GB then we need to upload multiple blocks to resize
		if size > 1*common.GbToBytes {
			blkSize := int64(16 * common.MbToBytes)
			blobName := filepath.Join(bb.Config.prefixPath, name)
			blobClient := bb.Container.NewBlockBlobClient(blobName)

			blkList := make([]string, 0)
			id := common.GetBlockID(common.BlockIDLength)

			for i := 0; size > 0; i++ {
				if i == 0 || size < blkSize {
					// Only first and last block we upload and rest all we replicate with the first block itself
					if size < blkSize {
						blkSize = size
						id = common.GetBlockID(common.BlockIDLength)
					}
					data := make([]byte, blkSize)

					_, err = blobClient.StageBlock(context.Background(),
						id,
						streaming.NopCloser(bytes.NewReader(data)),
						&blockblob.StageBlockOptions{
							CPKInfo: bb.blobCPKOpt,
						})
					if err != nil {
						log.Err("BlockBlob::TruncateFile : Failed to stage block for %s [%s]", name, err.Error())
						return err
					}
				}
				blkList = append(blkList, id)
				size -= blkSize
			}

			err = bb.CommitBlocks(blobName, blkList, nil)
			if err != nil {
				log.Err("BlockBlob::TruncateFile : Failed to commit blocks for %s [%s]", name, err.Error())
				return err
			}
		} else {
			err := bb.WriteFromBuffer(name, nil, make([]byte, size))
			if err != nil {
				log.Err("BlockBlob::TruncateFile : Failed to set the %s to 0 bytes [%s]", name, err.Error())
			}
		}
		return err
	}

	//If new size is less than 256MB
	if size < blockblob.MaxUploadBlobBytes {
		data, err := bb.HandleSmallFile(name, size, attr.Size)
		if err != nil {
			log.Err("BlockBlob::TruncateFile : Failed to read small file %s", name, err.Error())
			return err
		}
		err = bb.WriteFromBuffer(name, nil, data)
		if err != nil {
			log.Err("BlockBlob::TruncateFile : Failed to write from buffer file %s", name, err.Error())
			return err
		}
	} else {
		bol, err := bb.GetFileBlockOffsets(name)
		if err != nil {
			log.Err("BlockBlob::TruncateFile : Failed to get block list of file %s [%s]", name, err.Error())
			return err
		}
		if bol.SmallFile() {
			data, err := bb.HandleSmallFile(name, size, attr.Size)
			if err != nil {
				log.Err("BlockBlob::TruncateFile : Failed to read small file %s", name, err.Error())
				return err
			}
			err = bb.WriteFromBuffer(name, nil, data)
			if err != nil {
				log.Err("BlockBlob::TruncateFile : Failed to write from buffer file %s", name, err.Error())
				return err
			}
		} else {
			if size < attr.Size {
				bol = bb.removeBlocks(bol, size, name)
			} else if size > attr.Size {
				_, err = bb.createNewBlocks(bol, bol.BlockList[len(bol.BlockList)-1].EndIndex, size-attr.Size)
				if err != nil {
					log.Err("BlockBlob::TruncateFile : Failed to create new blocks for file %s", name, err.Error())
					return err
				}
			}
			err = bb.StageAndCommit(name, bol)
			if err != nil {
				log.Err("BlockBlob::TruncateFile : Failed to stage and commit file %s", name, err.Error())
				return err
			}
		}
	}

	return nil
}