@@ -258,12 +258,23 @@ class S3ReadableFile : public CloudStorageReadableFileImpl {
258258 S3ReadableFile (const std::shared_ptr<AwsS3ClientWrapper>& s3client,
259259 const std::shared_ptr<Logger>& info_log,
260260 const std::string& bucket, const std::string& fname,
261- uint64_t size)
261+ uint64_t size, std::string content_hash )
262262 : CloudStorageReadableFileImpl(info_log, bucket, fname, size),
263- s3client_ (s3client) {}
263+ s3client_ (s3client),
264+ content_hash_(std::move(content_hash)) {}
264265
265266 virtual const char * Type () const { return " s3" ; }
266267
268+ virtual size_t GetUniqueId (char * id, size_t max_size) const override {
269+ if (content_hash_.empty ()) {
270+ return 0 ;
271+ }
272+
273+ max_size = std::min (content_hash_.size (), max_size);
274+ memcpy (id, content_hash_.c_str (), max_size);
275+ return max_size;
276+ }
277+
267278 // random access, read data from specified offset in file
268279 Status DoCloudRead (uint64_t offset, size_t n, char * scratch,
269280 uint64_t * bytes_read) const override {
@@ -328,6 +339,7 @@ class S3ReadableFile : public CloudStorageReadableFileImpl {
328339
329340 private:
330341 std::shared_ptr<AwsS3ClientWrapper> s3client_;
342+ std::string content_hash_;
331343}; // End class S3ReadableFile
332344
333345/* ******************* Writablefile ******************/
@@ -371,9 +383,10 @@ class S3StorageProvider : public CloudStorageProviderImpl {
371383 uint64_t * time) override ;
372384
373385 // Get the metadata of the object in cloud storage
374- Status GetCloudObjectMetadata (
375- const std::string& bucket_name, const std::string& object_path,
376- std::unordered_map<std::string, std::string>* metadata) override ;
386+ Status GetCloudObjectMetadata (const std::string& bucket_name,
387+ const std::string& object_path,
388+ CloudObjectInformation* info) override ;
389+
377390 Status PutCloudObjectMetadata (
378391 const std::string& bucket_name, const std::string& object_path,
379392 const std::unordered_map<std::string, std::string>& metadata) override ;
@@ -383,6 +396,7 @@ class S3StorageProvider : public CloudStorageProviderImpl {
383396 const std::string& object_path_dest) override ;
384397 Status DoNewCloudReadableFile (
385398 const std::string& bucket, const std::string& fname, uint64_t fsize,
399+ const std::string& content_hash,
386400 std::unique_ptr<CloudStorageReadableFile>* result,
387401 const EnvOptions& options) override ;
388402 Status NewCloudWritableFile (const std::string& local_path,
@@ -403,11 +417,13 @@ class S3StorageProvider : public CloudStorageProviderImpl {
403417 uint64_t file_size) override ;
404418
405419 private:
406- // If metadata, size or modtime is non-nullptr, returns requested data
420+ // If metadata, size modtime or etag is non-nullptr, returns requested data
407421 Status HeadObject (
408422 const std::string& bucket, const std::string& path,
409423 std::unordered_map<std::string, std::string>* metadata = nullptr ,
410- uint64_t * size = nullptr , uint64_t * modtime = nullptr );
424+ uint64_t * size = nullptr , uint64_t * modtime = nullptr ,
425+ std::string* etag = nullptr );
426+
411427 // The S3 client
412428 std::shared_ptr<AwsS3ClientWrapper> s3client_;
413429};
@@ -646,10 +662,12 @@ Status S3StorageProvider::GetCloudObjectModificationTime(
646662 return HeadObject (bucket_name, object_path, nullptr , nullptr , time);
647663}
648664
649- Status S3StorageProvider::GetCloudObjectMetadata (
650- const std::string& bucket_name, const std::string& object_path,
651- std::unordered_map<std::string, std::string>* metadata) {
652- return HeadObject (bucket_name, object_path, metadata, nullptr , nullptr );
665+ Status S3StorageProvider::GetCloudObjectMetadata (const std::string& bucket_name,
666+ const std::string& object_path,
667+ CloudObjectInformation* info) {
668+ assert (info != nullptr );
669+ return HeadObject (bucket_name, object_path, &info->metadata , &info->size ,
670+ &info->modification_time , &info->content_hash );
653671}
654672
655673Status S3StorageProvider::PutCloudObjectMetadata (
@@ -680,10 +698,11 @@ Status S3StorageProvider::PutCloudObjectMetadata(
680698
681699Status S3StorageProvider::DoNewCloudReadableFile (
682700 const std::string& bucket, const std::string& fname, uint64_t fsize,
701+ const std::string& content_hash,
683702 std::unique_ptr<CloudStorageReadableFile>* result,
684703 const EnvOptions& /* options*/ ) {
685- result->reset (
686- new S3ReadableFile (s3client_, env_-> info_log_ , bucket, fname, fsize));
704+ result->reset (new S3ReadableFile (s3client_, env_-> info_log_ , bucket, fname,
705+ fsize, content_hash ));
687706 return Status::OK ();
688707}
689708
@@ -700,7 +719,7 @@ Status S3StorageProvider::NewCloudWritableFile(
700719Status S3StorageProvider::HeadObject (
701720 const std::string& bucket_name, const std::string& object_path,
702721 std::unordered_map<std::string, std::string>* metadata, uint64_t * size,
703- uint64_t * modtime) {
722+ uint64_t * modtime, std::string* etag ) {
704723 Aws::S3::Model::HeadObjectRequest request;
705724 request.SetBucket (ToAwsString (bucket_name));
706725 request.SetKey (ToAwsString (object_path));
@@ -727,6 +746,9 @@ Status S3StorageProvider::HeadObject(
727746 if (modtime != nullptr ) {
728747 *modtime = res.GetLastModified ().Millis ();
729748 }
749+ if (etag != nullptr ) {
750+ *etag = std::string (res.GetETag ().data (), res.GetETag ().length ());
751+ }
730752 return Status::OK ();
731753}
732754
0 commit comments