Airat Arifullin
3de256d05e
* Introduce `parentSplitID`, `parentSplitParentID` fields for `ECHeader`; * Fix ECHeader's constructor; * Fix `Split` and `Reconstruct`; * Add unit-tests. Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package erasurecode
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
|
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
|
)
|
|
|
|
// Split splits fully formed object into multiple chunks.
|
|
func (c *Constructor) Split(obj *objectSDK.Object, key *ecdsa.PrivateKey) ([]*objectSDK.Object, error) {
|
|
c.clear()
|
|
|
|
header, err := obj.CutPayload().Marshal()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
headerShards, err := c.encodeRaw(header)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payloadShards, err := c.encodeRaw(obj.Payload())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
parts := make([]*objectSDK.Object, len(payloadShards))
|
|
parent, _ := obj.ID()
|
|
for i := range parts {
|
|
chunk := objectSDK.New()
|
|
copyRequiredFields(chunk, obj)
|
|
chunk.SetPayload(payloadShards[i])
|
|
chunk.SetPayloadSize(uint64(len(payloadShards[i])))
|
|
|
|
var parentSplitParentID *oid.ID
|
|
if obj.HasParent() {
|
|
splitParentID, ok := obj.Parent().ID()
|
|
if ok {
|
|
parentSplitParentID = &splitParentID
|
|
}
|
|
}
|
|
|
|
ec := objectSDK.NewECHeader(parent, obj.SplitID(), parentSplitParentID, uint32(i), uint32(len(payloadShards)), headerShards[i], uint32(len(header)))
|
|
chunk.SetECHeader(ec)
|
|
if err := setIDWithSignature(chunk, key); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
parts[i] = chunk
|
|
}
|
|
return parts, nil
|
|
}
|
|
|
|
func setIDWithSignature(obj *objectSDK.Object, key *ecdsa.PrivateKey) error {
|
|
objectSDK.CalculateAndSetPayloadChecksum(obj)
|
|
|
|
if err := objectSDK.CalculateAndSetID(obj); err != nil {
|
|
return err
|
|
}
|
|
|
|
if key == nil {
|
|
return nil
|
|
}
|
|
|
|
return objectSDK.CalculateAndSetSignature(*key, obj)
|
|
}
|
|
|
|
func (c *Constructor) encodeRaw(data []byte) ([][]byte, error) {
|
|
shards, err := c.enc.Split(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := c.enc.Encode(shards); err != nil {
|
|
return nil, err
|
|
}
|
|
return shards, nil
|
|
}
|