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  }