Documentation ¶
Overview ¶
Reed-Solomon Erasure Coding in Go
For usage and examples, see https://github.com/sbberk/golang-reedsolomon
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvShardNum = errors.New("cannot create Encoder with zero or less data/parity shards")
ErrInvShardNum will be returned by New, if you attempt to create an Encoder where either data or parity shards is zero or less, or the number of data shards is higher than 256.
var ErrShardNoData = errors.New("no shard data")
ErrShardNoData will be returned if there are no shards, or if the length of all shards is zero.
var ErrShardSize = errors.New("shard sizes does not match")
ErrShardSize is returned if shard length isn't the same for all shards.
var ErrShortData = errors.New("not enough data to fill the number of requested shards")
ErrShortData will be returned by Split(), if there isn't enough data to fill the number of shards.
var ErrTooFewShards = errors.New("too few shards given")
ErrTooFewShards is returned if too few shards where given to Encode/Verify/Reconstruct. It will also be returned from Reconstruct if there were too few shards to reconstruct the missing data.
Functions ¶
This section is empty.
Types ¶
type Encoder ¶
type Encoder interface { // Encodes parity for a set of data shards. // Input is 'shards' containing data shards followed by parity shards. // The number of shards must match the number given to New(). // Each shard is a byte array, and they must all be the same size. // The parity shards will always be overwritten and the data shards // will remain the same, so it is safe for you to read from the // data shards while this is running. Encode(shards [][]byte) error // Verify returns true if the parity shards contain correct data. // The data is the same format as Encode. No data is modified, so // you are allowed to read from data while this is running. Verify(shards [][]byte) (bool, error) // Reconstruct will recreate the missing shards if possible. // // Given a list of shards, some of which contain data, fills in the // ones that don't have data. // // The length of the array must be equal to the total number of shards. // You indicate that a shard is missing by setting it to nil. // // If there are too few shards to reconstruct the missing // ones, ErrTooFewShards will be returned. // // The reconstructed shard set is complete, but integrity is not verified. // Use the Verify function to check if data set is ok. Reconstruct(shards [][]byte) error // Split a data slice into the number of shards given to the encoder, // and create empty parity shards. // // The data will be split into equally sized shards. // If the data size isn't dividable by the number of shards, // the last shard will contain extra zeros. // // There must be at least the same number of bytes as there are data shards, // otherwise ErrShortData will be returned. // // The data will not be copied, except for the last shard, so you // should not modify the data of the input slice afterwards. Split(data []byte) ([][]byte, error) // Join the shards and write the data segment to dst. // // Only the data shards are considered. // You must supply the exact output size you want. // If there are to few shards given, ErrTooFewShards will be returned. // If the total data size is less than outSize, ErrShortData will be returned. Join(dst io.Writer, shards [][]byte, outSize int) error }
Encoder is an interface to encode Reed-Salomon parity sets for your data.
Example ¶
Simple example of how to use all functions of the Encoder. Note that all error checks have been removed to keep it short.
// Create some sample data var data = make([]byte, 250000) fillRandom(data) // Create an encoder with 17 data and 3 parity slices. enc, _ := New(17, 3) // Split the data into shards shards, _ := enc.Split(data) // Encode the parity set _ = enc.Encode(shards) // Verify the parity set ok, _ := enc.Verify(shards) if ok { fmt.Println("ok") } // Delete two shards shards[10], shards[11] = nil, nil // Reconstruct the shards _ = enc.Reconstruct(shards) // Verify the data set ok, _ = enc.Verify(shards) if ok { fmt.Println("ok") }
Output: ok ok
Example (Slicing) ¶
This demonstrates that shards can be arbitrary sliced and merged and still remain valid.
// Create some sample data var data = make([]byte, 250000) fillRandom(data) // Create 5 data slices of 50000 elements each enc, _ := New(5, 3) shards, _ := enc.Split(data) err := enc.Encode(shards) if err != nil { panic(err) } // Check that it verifies ok, err := enc.Verify(shards) if ok && err == nil { fmt.Println("encode ok") } // Split the data set of 50000 elements into two of 25000 splitA := make([][]byte, 8) splitB := make([][]byte, 8) // Merge into a 100000 element set merged := make([][]byte, 8) // Split/merge the shards for i := range shards { splitA[i] = shards[i][:25000] splitB[i] = shards[i][25000:] // Concencate it to itself merged[i] = append(make([]byte, 0, len(shards[i])*2), shards[i]...) merged[i] = append(merged[i], shards[i]...) } // Each part should still verify as ok. ok, err = enc.Verify(shards) if ok && err == nil { fmt.Println("splitA ok") } ok, err = enc.Verify(splitB) if ok && err == nil { fmt.Println("splitB ok") } ok, err = enc.Verify(merged) if ok && err == nil { fmt.Println("merge ok") }
Output: encode ok splitA ok splitB ok merge ok
Example (Xor) ¶
This demonstrates that shards can xor'ed and still remain a valid set.
The xor value must be the same for element 'n' in each shard, except if you xor with a similar sized encoded shard set.
// Create some sample data var data = make([]byte, 25000) fillRandom(data) // Create 5 data slices of 5000 elements each enc, _ := New(5, 3) shards, _ := enc.Split(data) err := enc.Encode(shards) if err != nil { panic(err) } // Check that it verifies ok, err := enc.Verify(shards) if !ok || err != nil { fmt.Println("falied initial verify", err) } // Create an xor'ed set xored := make([][]byte, 8) // We xor by the index, so you can see that the xor can change, // It should however be constant vertically through your slices. for i := range shards { xored[i] = make([]byte, len(shards[i])) for j := range xored[i] { xored[i][j] = shards[i][j] ^ byte(j&0xff) } } // Each part should still verify as ok. ok, err = enc.Verify(xored) if ok && err == nil { fmt.Println("verified ok after xor") }
Output: verified ok after xor