From 372cbbab7bddc57d5b9530859a71f69cc241963e Mon Sep 17 00:00:00 2001 From: Brian Bockelman Date: Fri, 29 Nov 2024 19:50:42 -0600 Subject: [PATCH] Small file upload optimization If the entire object is uploaded during a single `Write` call, then skip the multipart upload and just do a single non-buffered upload. --- src/S3Commands.cc | 2 +- src/S3Commands.hh | 2 +- src/S3File.cc | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/S3Commands.cc b/src/S3Commands.cc index a6d9db9..a8b0848 100644 --- a/src/S3Commands.cc +++ b/src/S3Commands.cc @@ -476,7 +476,7 @@ bool AmazonRequest::SendS3Request(const std::string_view payload, AmazonS3Upload::~AmazonS3Upload() {} -bool AmazonS3Upload::SendRequest(const std::string &payload) { +bool AmazonS3Upload::SendRequest(const std::string_view &payload) { httpVerb = "PUT"; return SendS3Request(payload, payload.size(), true); } diff --git a/src/S3Commands.hh b/src/S3Commands.hh index d8519d8..3e72d2e 100644 --- a/src/S3Commands.hh +++ b/src/S3Commands.hh @@ -158,7 +158,7 @@ class AmazonS3Upload final : public AmazonRequest { virtual ~AmazonS3Upload(); - bool SendRequest(const std::string &payload); + bool SendRequest(const std::string_view &payload); protected: std::string path; diff --git a/src/S3File.cc b/src/S3File.cc index 9bcf27c..c45d96c 100644 --- a/src/S3File.cc +++ b/src/S3File.cc @@ -224,6 +224,25 @@ ssize_t S3File::Write(const void *buffer, off_t offset, size_t size) { } std::lock_guard lk(*write_mutex); + // Small object optimization -- if this is the full object, upload + // it immediately. + if (!m_write_offset && m_object_size == size) { + AmazonS3Upload upload(m_ai, m_object, m_log); + m_write_lk.reset(); + if (!upload.SendRequest( + std::string_view(static_cast(buffer), size))) { + m_log.Log(LogMask::Warning, "Write", + "Failed to create small object"); + return -EIO; + } else { + m_write_offset += size; + m_log.Log(LogMask::Debug, "Write", + "Creation of small object succeeded", + std::to_string(size).c_str()); + return size; + } + } + if (offset != m_write_offset) { m_log.Emsg( "Write",