github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/renter/erasure.go (about)

     1  package renter
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/klauspost/reedsolomon"
     7  
     8  	"github.com/NebulousLabs/Sia/modules"
     9  )
    10  
    11  // rsCode is a Reed-Solomon encoder/decoder. It implements the
    12  // modules.ErasureCoder interface.
    13  type rsCode struct {
    14  	enc reedsolomon.Encoder
    15  
    16  	numPieces  int
    17  	dataPieces int
    18  }
    19  
    20  // NumPieces returns the number of pieces returned by Encode.
    21  func (rs *rsCode) NumPieces() int { return rs.numPieces }
    22  
    23  // MinPieces return the minimum number of pieces that must be present to
    24  // recover the original data.
    25  func (rs *rsCode) MinPieces() int { return rs.dataPieces }
    26  
    27  // Encode splits data into equal-length pieces, some containing the original
    28  // data and some containing parity data.
    29  func (rs *rsCode) Encode(data []byte) ([][]byte, error) {
    30  	pieces, err := rs.enc.Split(data)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	// err should not be possible if Encode is called on the result of Split,
    35  	// but no harm in checking anyway.
    36  	err = rs.enc.Encode(pieces)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	return pieces, nil
    41  }
    42  
    43  // Recover recovers the original data from pieces (including parity) and
    44  // writes it to w. pieces should be identical to the slice returned by
    45  // Encode (length and order must be preserved), but with missing elements
    46  // set to nil.
    47  func (rs *rsCode) Recover(pieces [][]byte, n uint64, w io.Writer) error {
    48  	err := rs.enc.Reconstruct(pieces)
    49  	if err != nil {
    50  		return err
    51  	}
    52  	// TODO: implement this manually
    53  	return rs.enc.Join(w, pieces, int(n))
    54  }
    55  
    56  // NewRSCode creates a new Reed-Solomon encoder/decoder using the supplied
    57  // parameters.
    58  func NewRSCode(nData, nParity int) (modules.ErasureCoder, error) {
    59  	enc, err := reedsolomon.New(nData, nParity)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	return &rsCode{
    64  		enc:        enc,
    65  		numPieces:  nData + nParity,
    66  		dataPieces: nData,
    67  	}, nil
    68  }