Skip to content

Commit

Permalink
Allow reconstructSome to reconstruct parity shards (#267)
Browse files Browse the repository at this point in the history
* Allow reconstructSome to reconstruct parity shards
  • Loading branch information
walldiss committed Jan 5, 2024
1 parent 674f18b commit 162f2ba
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
5 changes: 4 additions & 1 deletion leopard.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,10 @@ func (r *leopardFF16) Split(data []byte) ([][]byte, error) {
}

func (r *leopardFF16) ReconstructSome(shards [][]byte, required []bool) error {
return r.ReconstructData(shards)
if len(required) == r.totalShards {
return r.reconstruct(shards, true)
}
return r.reconstruct(shards, false)
}

func (r *leopardFF16) Reconstruct(shards [][]byte) error {
Expand Down
5 changes: 4 additions & 1 deletion leopard8.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,10 @@ func (r *leopardFF8) Split(data []byte) ([][]byte, error) {
}

func (r *leopardFF8) ReconstructSome(shards [][]byte, required []bool) error {
return r.ReconstructData(shards)
if len(required) == r.totalShards {
return r.reconstruct(shards, true)
}
return r.reconstruct(shards, false)
}

func (r *leopardFF8) Reconstruct(shards [][]byte) error {
Expand Down
19 changes: 12 additions & 7 deletions reedsolomon.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ type Encoder interface {
// calling the Verify function is likely to fail.
ReconstructData(shards [][]byte) error

// ReconstructSome will recreate only requested data shards, if possible.
// ReconstructSome will recreate only requested shards, if possible.
//
// Given a list of shards, some of which contain data, fills in the
// data shards indicated by true values in the "required" parameter.
// The length of "required" array must be equal to DataShards.
// shards indicated by true values in the "required" parameter.
// The length of the "required" array must be equal to either Shards or DataShards.
// If the length is equal to DataShards, the reconstruction of parity shards will be ignored.
//
// The length of "shards" array must be equal to Shards.
// You indicate that a shard is missing by setting it to nil or zero-length.
Expand Down Expand Up @@ -1402,13 +1403,14 @@ func (r *reedSolomon) ReconstructData(shards [][]byte) error {
return r.reconstruct(shards, true, nil)
}

// ReconstructSome will recreate only requested data shards, if possible.
// ReconstructSome will recreate only requested shards, if possible.
//
// Given a list of shards, some of which contain data, fills in the
// data shards indicated by true values in the "required" parameter.
// The length of "required" array must be equal to dataShards.
// shards indicated by true values in the "required" parameter.
// The length of the "required" array must be equal to either Shards or DataShards.
// If the length is equal to DataShards, the reconstruction of parity shards will be ignored.
//
// The length of "shards" array must be equal to shards.
// The length of "shards" array must be equal to Shards.
// 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.
Expand All @@ -1419,6 +1421,9 @@ func (r *reedSolomon) ReconstructData(shards [][]byte) error {
// As the reconstructed shard set may contain missing parity shards,
// calling the Verify function is likely to fail.
func (r *reedSolomon) ReconstructSome(shards [][]byte, required []bool) error {
if len(required) == r.totalShards {
return r.reconstruct(shards, false, required)
}
return r.reconstruct(shards, true, required)
}

Expand Down
22 changes: 20 additions & 2 deletions reedsolomon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,16 +826,34 @@ func testReconstructData(t *testing.T, o ...Option) {
t.Fatal(err)
}

// Reconstruct 3 shards with 3 data and 5 parity shards
// Reconstruct parity shards from data
shardsCopy := make([][]byte, 13)
for i := 0; i < 8; i++ {
shardsCopy[i] = shards[i]
}

shardsRequired := make([]bool, 13)
shardsRequired[10] = true

err = r.ReconstructSome(shardsCopy, shardsRequired)
if err != nil {
t.Fatal(err)
}

if !bytes.Equal(shardsCopy[10], shards[10]) {
t.Fatal("ReconstructSome did not reconstruct required shards correctly")
}

// Reconstruct 3 shards with 3 data and 5 parity shards
shardsCopy = make([][]byte, 13)
copy(shardsCopy, shards)
shardsCopy[2] = nil
shardsCopy[3] = nil
shardsCopy[4] = nil
shardsCopy[5] = nil
shardsCopy[6] = nil

shardsRequired := make([]bool, 8)
shardsRequired = make([]bool, 8)
shardsRequired[3] = true
shardsRequired[4] = true
err = r.ReconstructSome(shardsCopy, shardsRequired)
Expand Down

0 comments on commit 162f2ba

Please sign in to comment.