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
parent
87ba8262ab
commit
ddcafc661e
|
@ -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++
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue