Skip to content

Commit 221622d

Browse files
committed
fix object_size_hint buffer reservation
1 parent e8bf59a commit 221622d

1 file changed

Lines changed: 16 additions & 10 deletions

File tree

source/s3_auto_ranged_get.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -173,18 +173,19 @@ static enum aws_s3_auto_ranged_get_request_type s_s3_get_request_type_for_discov
173173
: AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_HEAD_OBJECT;
174174
}
175175

176+
/* If the object_size_hint indicates that it fits in a single part, try to get the file directly.
177+
* This avoids a HEAD request and sizes the buffer reservation to the hint rather than full part_size.
178+
* If the hint is wrong and the object is larger, the request will be cancelled and retried with ranged gets. */
179+
if (auto_ranged_get->object_size_hint_available && auto_ranged_get->object_size_hint > 0 &&
180+
auto_ranged_get->object_size_hint <= meta_request->part_size) {
181+
return AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_GET_OBJECT_WITH_PART_NUMBER_1;
182+
}
183+
176184
/* If we don't need checksum validation, then discover the size of the object while trying to get the first part. */
177185
if (!meta_request->checksum_config.validate_response_checksum) {
178186
return AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_GET_OBJECT_WITH_RANGE;
179187
}
180188

181-
/* If the object_size_hint indicates that it is a small one part file, then try to get the file directly
182-
* TODO: Bypass memory limiter so that we don't overallocate memory for small files
183-
*/
184-
if (auto_ranged_get->object_size_hint_available && auto_ranged_get->object_size_hint <= meta_request->part_size) {
185-
return AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_GET_OBJECT_WITH_PART_NUMBER_1;
186-
}
187-
188189
/* Otherwise, do a headObject so that we can validate checksum if the file was uploaded as a single part */
189190
return AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_HEAD_OBJECT;
190191
}
@@ -265,10 +266,15 @@ static bool s_s3_auto_ranged_get_update(
265266
1 /*part_number*/,
266267
AWS_S3_REQUEST_FLAG_RECORD_RESPONSE_HEADERS |
267268
AWS_S3_REQUEST_FLAG_ALLOCATE_BUFFER_FROM_POOL);
268-
/* Note: our current default logic is to do part 1, discover size and then abort if payload its
269-
* too huge We optimistically reserve part size for it */
269+
/* Reserve only as much buffer as the hint suggests, capped at part_size.
270+
* If the hint is absent or zero, fall back to the full part_size reservation.
271+
* The cancellation path in s_s3_meta_request_headers_block_done handles the
272+
* case where the actual object is larger than reserved (retries with range gets). */
270273
request->part_range_start = 0;
271-
request->part_range_end = meta_request->part_size - 1;
274+
request->part_range_end =
275+
(auto_ranged_get->object_size_hint_available && auto_ranged_get->object_size_hint > 0)
276+
? aws_min_u64(auto_ranged_get->object_size_hint, meta_request->part_size) - 1
277+
: meta_request->part_size - 1;
272278
++auto_ranged_get->synced_data.num_parts_requested;
273279

274280
break;

0 commit comments

Comments
 (0)