gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/siafile/partialssiafile.go (about)

     1  package siafile
     2  
     3  import (
     4  	"path/filepath"
     5  
     6  	"gitlab.com/NebulousLabs/errors"
     7  	"gitlab.com/SiaPrime/SiaPrime/modules"
     8  	"gitlab.com/SiaPrime/writeaheadlog"
     9  )
    10  
    11  // CombinedChunkIndex is a helper method which translates a chunk's index to the
    12  // corresponding combined chunk index dependng on the number of combined chunks.
    13  func CombinedChunkIndex(numChunks, chunkIndex uint64, numCombinedChunks int) int {
    14  	if numCombinedChunks == 1 && chunkIndex == numChunks-1 {
    15  		return 0
    16  	}
    17  	if numCombinedChunks == 2 && chunkIndex == numChunks-2 {
    18  		return 0
    19  	}
    20  	if numCombinedChunks == 2 && chunkIndex == numChunks-1 {
    21  		return 1
    22  	}
    23  	return -1
    24  }
    25  
    26  // Merge merges two PartialsSiafiles into one, returning a map which translates
    27  // chunk indices in newFile to indices in sf.
    28  func (sf *SiaFile) Merge(newFile *SiaFile) (map[uint64]uint64, error) {
    29  	sf.mu.Lock()
    30  	defer sf.mu.Unlock()
    31  	return sf.merge(newFile)
    32  }
    33  
    34  // addCombinedChunk adds a new combined chunk to a combined Siafile. This can't
    35  // be called on a regular SiaFile.
    36  func (sf *SiaFile) addCombinedChunk() ([]writeaheadlog.Update, error) {
    37  	if sf.deleted {
    38  		return nil, errors.New("can't add combined chunk to deleted file")
    39  	}
    40  	if filepath.Ext(sf.siaFilePath) != modules.PartialsSiaFileExtension {
    41  		return nil, errors.New("can only call addCombinedChunk on combined SiaFiles")
    42  	}
    43  	// Create updates to add a chunk and return index of that new chunk.
    44  	updates, err := sf.growNumChunks(uint64(sf.numChunks) + 1)
    45  	return updates, err
    46  }
    47  
    48  // merge merges two PartialsSiafiles into one, returning a map which translates
    49  // chunk indices in newFile to indices in sf.
    50  func (sf *SiaFile) merge(newFile *SiaFile) (map[uint64]uint64, error) {
    51  	if sf.deleted {
    52  		return nil, errors.New("can't merge into deleted file")
    53  	}
    54  	if filepath.Ext(sf.siaFilePath) != modules.PartialsSiaFileExtension {
    55  		return nil, errors.New("can only call merge on PartialsSiaFile")
    56  	}
    57  	if filepath.Ext(newFile.SiaFilePath()) != modules.PartialsSiaFileExtension {
    58  		return nil, errors.New("can only merge PartialsSiafiles into a PartialsSiaFile")
    59  	}
    60  	newFile.mu.Lock()
    61  	defer newFile.mu.Unlock()
    62  	if newFile.deleted {
    63  		return nil, errors.New("can't merge deleted file")
    64  	}
    65  	var newChunks []chunk
    66  	indexMap := make(map[uint64]uint64)
    67  	ncb := sf.numChunks
    68  	err := newFile.iterateChunksReadonly(func(chunk chunk) error {
    69  		newIndex := sf.numChunks
    70  		indexMap[uint64(chunk.Index)] = uint64(newIndex)
    71  		chunk.Index = newIndex
    72  		newChunks = append(newChunks, chunk)
    73  		return nil
    74  	})
    75  	if err != nil {
    76  		sf.numChunks = ncb
    77  		return nil, err
    78  	}
    79  	return indexMap, sf.saveFile(newChunks)
    80  }