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 }