MCPcopy
hub / github.com/minio/minio-go / ComposeObject

Method ComposeObject

api-compose-object.go:417–572  ·  view source on GitHub ↗

ComposeObject - creates an object using server-side copying of existing objects. It takes a list of source objects (with optional offsets) and concatenates them into a new object using only server-side copying operations. Optionally takes progress reader hook for applications to look at current prog

(ctx context.Context, dst CopyDestOptions, srcs ...CopySrcOptions)

Source from the content-addressed store, hash-verified

415// operations. Optionally takes progress reader hook for applications to
416// look at current progress.
417func (c *Client) ComposeObject(ctx context.Context, dst CopyDestOptions, srcs ...CopySrcOptions) (UploadInfo, error) {
418 if len(srcs) < 1 || len(srcs) > maxPartsCount {
419 return UploadInfo{}, errInvalidArgument("There must be as least one and up to 10000 source objects.")
420 }
421
422 for _, src := range srcs {
423 if err := src.validate(); err != nil {
424 return UploadInfo{}, err
425 }
426 }
427
428 if err := dst.validate(); err != nil {
429 return UploadInfo{}, err
430 }
431
432 srcObjectInfos := make([]ObjectInfo, len(srcs))
433 srcObjectSizes := make([]int64, len(srcs))
434 var totalSize, totalParts int64
435 var err error
436 for i, src := range srcs {
437 opts := StatObjectOptions{ServerSideEncryption: encrypt.SSE(src.Encryption), VersionID: src.VersionID}
438 srcObjectInfos[i], err = c.StatObject(context.Background(), src.Bucket, src.Object, opts)
439 if err != nil {
440 return UploadInfo{}, err
441 }
442
443 srcCopySize := srcObjectInfos[i].Size
444 // Check if a segment is specified, and if so, is the
445 // segment within object bounds?
446 if src.MatchRange {
447 // Since range is specified,
448 // 0 <= src.start <= src.end
449 // so only invalid case to check is:
450 if src.End >= srcCopySize || src.Start < 0 {
451 return UploadInfo{}, errInvalidArgument(
452 fmt.Sprintf("CopySrcOptions %d has invalid segment-to-copy [%d, %d] (size is %d)",
453 i, src.Start, src.End, srcCopySize))
454 }
455 srcCopySize = src.End - src.Start + 1
456 }
457
458 // Only the last source may be less than `absMinPartSize`
459 if srcCopySize < absMinPartSize && i < len(srcs)-1 {
460 return UploadInfo{}, errInvalidArgument(
461 fmt.Sprintf("CopySrcOptions %d is too small (%d) and it is not the last part", i, srcCopySize))
462 }
463
464 // Is data to copy too large?
465 totalSize += srcCopySize
466 if totalSize > maxObjectSize {
467 return UploadInfo{}, errInvalidArgument(fmt.Sprintf("Cannot compose an object of size %d (> 5GiB * 10000)", totalSize))
468 }
469
470 // record source size
471 srcObjectSizes[i] = srcCopySize
472
473 // calculate parts needed for current source
474 totalParts += partsRequired(srcCopySize, int64(dst.PartSize))

Callers 5

mainFunction · 0.80

Calls 13

StatObjectMethod · 0.95
CopyObjectMethod · 0.95
newUploadIDMethod · 0.95
uploadPartCopyMethod · 0.95
SSEFunction · 0.92
errInvalidArgumentFunction · 0.85
partsRequiredFunction · 0.85
calculateEvenSplitsFunction · 0.85
MarshalMethod · 0.65
TypeMethod · 0.65
validateMethod · 0.45

Tested by

no test coverage detected