based on https://github.com/tus/tusd/blob/master/pkg/s3store/s3store.go#L943
Last active
May 23, 2022 18:28
-
-
Save singerxt/068c5a14756dd527c3e07239856fbcfd to your computer and use it in GitHub Desktop.
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
// Maximum number of parts per upload | |
// DO NOT INCREASE IT. YOU WILL REACH GRPC MESSAGE SIZE LIMIT | |
const MAX_MULTI_UPLOAD_PARTS: u64 = 7000; | |
// 5 Tb. | |
const MAX_OBJECT_SIZE: u64 = 5 * 1024 * 1024 * 1024 * 1024; | |
// 5Gb | |
const MAX_PART_SIZE: u64 = 5 * 1024 * 1024 * 1024; | |
// 5Mb | |
const MIN_PART_SIZE: u64 = 5 * 1024 * 1024; | |
// 50Mb it's good for web client and handles maximal file size [MAX_OBJECT_SIZE] | |
const PREFERRED_PART_SIZE: u64 = 50 * 1024 * 1024; | |
type OptimalPartSize = u64; | |
fn calculate_optimal_part_size(file_size: u64) -> Result<OptimalPartSize, ()> { | |
if file_size > MAX_OBJECT_SIZE { | |
return Err(()); | |
} | |
let optimal_size = match file_size { | |
// When upload is smaller or equal MinPartSize, we upload in just one part. | |
size if size <= PREFERRED_PART_SIZE => PREFERRED_PART_SIZE, | |
// Does the upload fit in MaxMultipartParts parts or less with MinPartSize. | |
size if size <= PREFERRED_PART_SIZE * MAX_MULTI_UPLOAD_PARTS => PREFERRED_PART_SIZE, | |
// Prerequisite: Be aware, that the result of an integer division (x/y) is | |
// ALWAYS rounded DOWN, as there are no digits behind the comma. | |
// In order to find out, whether we have an exact result or a rounded down | |
// one, we can check, whether the remainder of that division is 0 (x%y == 0). | |
// | |
// So if the result of (size/MaxMultipartParts) is not a rounded down value, | |
// then we can use it as our optimalPartSize. But if this division produces a | |
// remainder, we have to round up the result by adding +1. Otherwise our | |
// upload would not fit into MaxMultipartParts number of parts with that | |
// size. We would need an additional part in order to upload everything. | |
// While in almost all cases, we could skip the check for the remainder and | |
// just add +1 to every result, but there is one case, where doing that would | |
// doom our upload. When (MaxObjectSize == MaxPartSize * MaxMultipartParts), | |
// by adding +1, we would end up with an optimalPartSize > MaxPartSize. | |
// With the current S3 API specifications. | |
size if size % MAX_MULTI_UPLOAD_PARTS == 0 => size / MAX_MULTI_UPLOAD_PARTS, | |
// Having a remainder larger than 0 means, the float result would have | |
// digits after the comma (e.g. be something like 10.9). As a result, we can | |
// only squeeze our upload into MaxMultipartParts parts, if we rounded UP | |
// this division's result. That is what is happending here. We round up by | |
// adding +1, if the prior test for (remainder == 0) did not succeed. | |
size => size / MAX_MULTI_UPLOAD_PARTS + 1, | |
}; | |
match optimal_size { | |
optimal_size if optimal_size > MAX_PART_SIZE => { | |
Err(()) | |
} | |
_ => Ok(optimal_size) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment