Allow reconstructing into pre-allocated memory. (#66)

This changes the interface of Reconstruct and ReconstructData to accept
slices of zero length but sufficient capacity for shards to reconstruct,
and reslices them instead of allocating new memory.
master
David Reiss 2017-09-20 12:08:25 -07:00 committed by Klaus Post
parent 87ba8262ab
commit ddcafc661e
2 changed files with 38 additions and 10 deletions

View File

@ -40,7 +40,9 @@ type Encoder interface {
// 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.
// You indicate that a shard is missing by setting it to nil or zero-length.
// If a shard is zero-length but has sufficient capacity, that memory will
// be used, otherwise a new []byte will be allocated.
//
// If there are too few shards to reconstruct the missing
// ones, ErrTooFewShards will be returned.
@ -55,7 +57,9 @@ type Encoder interface {
// data shards that don't have data.
//
// The length of the array must be equal to Shards.
// You indicate that a shard is missing by setting it to nil.
// You indicate that a shard is missing by setting it to nil or zero-length.
// If a shard is zero-length but has sufficient capacity, that memory will
// be used, otherwise a new []byte will be allocated.
//
// If there are too few shards to reconstruct the missing
// ones, ErrTooFewShards will be returned.
@ -547,7 +551,9 @@ func shardSize(shards [][]byte) int {
// ones that don't have data.
//
// The length of the array must be equal to Shards.
// You indicate that a shard is missing by setting it to nil.
// You indicate that a shard is missing by setting it to nil or zero-length.
// If a shard is zero-length but has sufficient capacity, that memory will
// be used, otherwise a new []byte will be allocated.
//
// If there are too few shards to reconstruct the missing
// ones, ErrTooFewShards will be returned.
@ -564,7 +570,9 @@ func (r reedSolomon) Reconstruct(shards [][]byte) error {
// data shards that don't have data.
//
// The length of the array must be equal to Shards.
// You indicate that a shard is missing by setting it to nil.
// You indicate that a shard is missing by setting it to nil or zero-length.
// If a shard is zero-length but has sufficient capacity, that memory will
// be used, otherwise a new []byte will be allocated.
//
// If there are too few shards to reconstruct the missing
// ones, ErrTooFewShards will be returned.
@ -682,7 +690,11 @@ func (r reedSolomon) reconstruct(shards [][]byte, dataOnly bool) error {
for iShard := 0; iShard < r.DataShards; iShard++ {
if len(shards[iShard]) == 0 {
shards[iShard] = make([]byte, shardSize)
if cap(shards[iShard]) >= shardSize {
shards[iShard] = shards[iShard][0:shardSize]
} else {
shards[iShard] = make([]byte, shardSize)
}
outputs[outputCount] = shards[iShard]
matrixRows[outputCount] = dataDecodeMatrix[iShard]
outputCount++
@ -704,7 +716,11 @@ func (r reedSolomon) reconstruct(shards [][]byte, dataOnly bool) error {
outputCount = 0
for iShard := r.DataShards; iShard < r.Shards; iShard++ {
if len(shards[iShard]) == 0 {
shards[iShard] = make([]byte, shardSize)
if cap(shards[iShard]) >= shardSize {
shards[iShard] = shards[iShard][0:shardSize]
} else {
shards[iShard] = make([]byte, shardSize)
}
outputs[outputCount] = shards[iShard]
matrixRows[outputCount] = r.parity[iShard-r.DataShards]
outputCount++

View File

@ -313,10 +313,12 @@ func testReconstruct(t *testing.T, o ...Option) {
t.Fatal(err)
}
// Reconstruct with 10 shards present
// Reconstruct with 10 shards present. Use pre-allocated memory for one of them.
shards[0] = nil
shards[7] = nil
shards[11] = nil
shard11 := shards[11]
shards[11] = shard11[:0]
fillRandom(shard11)
err = r.Reconstruct(shards)
if err != nil {
@ -331,6 +333,10 @@ func testReconstruct(t *testing.T, o ...Option) {
t.Fatal("Verification failed")
}
if &shard11[0] != &shards[11][0] {
t.Errorf("Shard was not reconstructed into pre-allocated memory")
}
// Reconstruct with 9 shards present (should fail)
shards[0] = nil
shards[4] = nil
@ -386,10 +392,12 @@ func testReconstructData(t *testing.T, o ...Option) {
t.Fatal(err)
}
// Reconstruct with 10 shards present
// Reconstruct with 10 shards present. Use pre-allocated memory for one of them.
shards[0] = nil
shards[2] = nil
shards[4] = nil
shard4 := shards[4]
shards[4] = shard4[:0]
fillRandom(shard4)
err = r.ReconstructData(shards)
if err != nil {
@ -405,6 +413,10 @@ func testReconstructData(t *testing.T, o ...Option) {
t.Fatal("Verification failed")
}
if &shard4[0] != &shards[4][0] {
t.Errorf("Shard was not reconstructed into pre-allocated memory")
}
// Reconstruct with 6 data and 4 parity shards
shards[0] = nil
shards[2] = nil