git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/object/erasurecode/split.go (about) 1 package erasurecode 2 3 import ( 4 "crypto/ecdsa" 5 6 objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" 7 oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" 8 ) 9 10 // Split splits fully formed object into multiple chunks. 11 func (c *Constructor) Split(obj *objectSDK.Object, key *ecdsa.PrivateKey) ([]*objectSDK.Object, error) { 12 c.clear() 13 14 header, err := obj.CutPayload().Marshal() 15 if err != nil { 16 return nil, err 17 } 18 19 headerShards, err := c.encodeRaw(header) 20 if err != nil { 21 return nil, err 22 } 23 payloadShards, err := c.encodeRaw(obj.Payload()) 24 if err != nil { 25 return nil, err 26 } 27 28 parts := make([]*objectSDK.Object, len(payloadShards)) 29 parent, _ := obj.ID() 30 for i := range parts { 31 chunk := objectSDK.New() 32 copyRequiredFields(chunk, obj) 33 chunk.SetPayload(payloadShards[i]) 34 chunk.SetPayloadSize(uint64(len(payloadShards[i]))) 35 36 var parentSplitParentID *oid.ID 37 if obj.HasParent() { 38 splitParentID, ok := obj.Parent().ID() 39 if ok { 40 parentSplitParentID = &splitParentID 41 } 42 } 43 44 ecParentInfo := objectSDK.ECParentInfo{ 45 ID: parent, 46 SplitID: obj.SplitID(), 47 SplitParentID: parentSplitParentID, 48 Attributes: obj.Attributes(), 49 } 50 51 ec := objectSDK.NewECHeader(ecParentInfo, uint32(i), uint32(len(payloadShards)), headerShards[i], uint32(len(header))) 52 chunk.SetECHeader(ec) 53 if err := setIDWithSignature(chunk, key); err != nil { 54 return nil, err 55 } 56 57 parts[i] = chunk 58 } 59 return parts, nil 60 } 61 62 func setIDWithSignature(obj *objectSDK.Object, key *ecdsa.PrivateKey) error { 63 objectSDK.CalculateAndSetPayloadChecksum(obj) 64 65 if err := objectSDK.CalculateAndSetID(obj); err != nil { 66 return err 67 } 68 69 if key == nil { 70 return nil 71 } 72 73 return objectSDK.CalculateAndSetSignature(*key, obj) 74 } 75 76 func (c *Constructor) encodeRaw(data []byte) ([][]byte, error) { 77 shards, err := c.enc.Split(data) 78 if err != nil { 79 return nil, err 80 } 81 if err := c.enc.Encode(shards); err != nil { 82 return nil, err 83 } 84 return shards, nil 85 }