-
Notifications
You must be signed in to change notification settings - Fork 647
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add API to compose objects through server-side copying (#715)
The new ComposeObject API provides a way to create objects by concatenating existing objects. It takes a list of source objects along with optional start-end range specifications, and concatenates them into a new object. The API supports: * Create an object from upto 10000 existing objects. * Create objects upto 5TiB in size, from source objects of any size. * Support copy-conditions on each source object separately. * Support SSE-C (i.e. Server-Side-Encryption with Customer provided key) for both encryption of destination object, and decryption of source objects. * Support for setting/replacing custom metadata in the destination object. This API has been used to refactor the CopyObject API - that API now supports source objects of any size, SSE-C for source and destination, and settings custom metadata.
- Loading branch information
1 parent
2263a34
commit 129fe89
Showing
9 changed files
with
1,173 additions
and
115 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2017 Minio, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package minio | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
const ( | ||
gb1 = 1024 * 1024 * 1024 | ||
gb5 = 5 * gb1 | ||
gb5p1 = gb5 + 1 | ||
gb10p1 = 2*gb5 + 1 | ||
gb10p2 = 2*gb5 + 2 | ||
) | ||
|
||
func TestPartsRequired(t *testing.T) { | ||
testCases := []struct { | ||
size, ref int64 | ||
}{ | ||
{0, 0}, | ||
{1, 1}, | ||
{gb5, 1}, | ||
{2 * gb5, 2}, | ||
{gb10p1, 3}, | ||
{gb10p2, 3}, | ||
} | ||
|
||
for i, testCase := range testCases { | ||
res := partsRequired(testCase.size) | ||
if res != testCase.ref { | ||
t.Errorf("Test %d - output did not match with reference results", i+1) | ||
} | ||
} | ||
} | ||
|
||
func TestCalculateEvenSplits(t *testing.T) { | ||
|
||
testCases := []struct { | ||
// input size and source object | ||
size int64 | ||
src SourceInfo | ||
|
||
// output part-indexes | ||
starts, ends []int64 | ||
}{ | ||
{0, SourceInfo{start: -1}, nil, nil}, | ||
{1, SourceInfo{start: -1}, []int64{0}, []int64{0}}, | ||
{1, SourceInfo{start: 0}, []int64{0}, []int64{0}}, | ||
|
||
{gb1, SourceInfo{start: -1}, []int64{0}, []int64{gb1 - 1}}, | ||
{gb5, SourceInfo{start: -1}, []int64{0}, []int64{gb5 - 1}}, | ||
|
||
// 2 part splits | ||
{gb5p1, SourceInfo{start: -1}, []int64{0, gb5/2 + 1}, []int64{gb5 / 2, gb5}}, | ||
{gb5p1, SourceInfo{start: -1}, []int64{0, gb5/2 + 1}, []int64{gb5 / 2, gb5}}, | ||
|
||
// 3 part splits | ||
{gb10p1, SourceInfo{start: -1}, | ||
[]int64{0, gb10p1/3 + 1, 2*gb10p1/3 + 1}, | ||
[]int64{gb10p1 / 3, 2 * gb10p1 / 3, gb10p1 - 1}}, | ||
|
||
{gb10p2, SourceInfo{start: -1}, | ||
[]int64{0, gb10p2 / 3, 2 * gb10p2 / 3}, | ||
[]int64{gb10p2/3 - 1, 2*gb10p2/3 - 1, gb10p2 - 1}}, | ||
} | ||
|
||
for i, testCase := range testCases { | ||
resStart, resEnd := calculateEvenSplits(testCase.size, testCase.src) | ||
if !reflect.DeepEqual(testCase.starts, resStart) || !reflect.DeepEqual(testCase.ends, resEnd) { | ||
t.Errorf("Test %d - output did not match with reference results", i+1) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.