func NewLargeObject(c *swift.Connection, path string, concurrency int, partSize int64, expireAfter int64, logger cpiLogger.Logger) (*largeObject, error) {
	pathParts := strings.SplitN(path, "/", 2)
	objectName := "upload"
	if len(pathParts) > 1 {
		objectName = pathParts[1]
	}
	// #nosec G401
	lo := largeObject{
		c:          c,
		container:  pathParts[0],
		objectName: objectName,
		timestamp:  fmt.Sprintf("%d", time.Now().UnixNano()),
		expire:     fmt.Sprintf("%d", expireAfter),

		bufsz: max64(minPartSize, partSize),

		ch:         make(chan *part),
		md5OfParts: md5.New(),
		md5:        md5.New(),

		bp: newBufferPool(minPartSize),

		logger: logger,
	}

	for i := 0; i < max(concurrency, 1); i++ {
		go lo.worker()
	}

	// Create segment container if it doesn't already exist
	err := c.ContainerCreate(lo.container, nil)
	if err != nil {
		return nil, err
	}

	return &lo, nil
}
func NewLargeObject(c *swift.Connection, path string, concurrency int, partSize int64, expireAfter int64, logger cpiLogger.Logger) (*largeObject, error) {
	pathParts := strings.SplitN(path, "/", 2)
	objectName := "upload"
	if len(pathParts) > 1 {
		objectName = pathParts[1]
	}
	// #nosec G401
	lo := largeObject{
		c:          c,
		container:  pathParts[0],
		objectName: objectName,
		timestamp:  fmt.Sprintf("%d", time.Now().UnixNano()),
		expire:     fmt.Sprintf("%d", expireAfter),

		bufsz: max64(minPartSize, partSize),

		ch:         make(chan *part),
		md5OfParts: md5.New(),
		md5:        md5.New(),

		bp: newBufferPool(minPartSize),

		logger: logger,
	}

	for i := 0; i < max(concurrency, 1); i++ {
		go lo.worker()
	}

	// Create segment container if it doesn't already exist
	err := c.ContainerCreate(lo.container, nil)
	if err != nil {
		return nil, err
	}

	return &lo, nil
}
// NewLargeObject provides a io.writer to upload data as a segmented upload
//
// It will upload all the segments into a second container named <container>.
// These segments will have names like large_file/1290206778.25/00000000,
// large_file/1290206778.25/00000001, etc.
//
// The main benefit for using a separate container is that the main container listings
// will not be polluted with all the segment names. The reason for using the segment
// name format of <name>/<timestamp>/<segment> is so that an upload of a new
// file with the same name won’t overwrite the contents of the first until the last
// moment when the manifest file is updated.
//
// swift will manage these segment files for you, deleting old segments on deletes
// and overwrites, etc. You can override this behavior with the --leave-segments
// option if desired; this is useful if you want to have multiple versions of
// the same large object available.