Skip to content

Commit a5e883e

Browse files
committed
Clarify CloudFileSystem API.
Splitting the CloudFileSystem class into a pure interface class and a separate class that contains static initialization and factory methods (CloudFileSystemEnv). This will make it possible to provide other implementations of CloudFileSystem wihtout having to wrangle with static functions and options.
1 parent 43ad10b commit a5e883e

File tree

4 files changed

+139
-104
lines changed

4 files changed

+139
-104
lines changed

cloud/cloud_file_system.cc

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
#include <unordered_map>
1212

1313
#include "cloud/aws/aws_file_system.h"
14-
#include "rocksdb/cloud/cloud_file_system_impl.h"
1514
#include "cloud/cloud_log_controller_impl.h"
16-
#include "rocksdb/cloud/cloud_storage_provider_impl.h"
1715
#include "cloud/db_cloud_impl.h"
1816
#include "cloud/filename.h"
1917
#include "env/composite_env_wrapper.h"
2018
#include "options/configurable_helper.h"
2119
#include "options/options_helper.h"
2220
#include "port/likely.h"
21+
#include "rocksdb/cloud/cloud_file_system_impl.h"
2322
#include "rocksdb/cloud/cloud_log_controller.h"
23+
#include "rocksdb/cloud/cloud_storage_provider_impl.h"
2424
#include "rocksdb/db.h"
2525
#include "rocksdb/env.h"
2626
#include "rocksdb/options.h"
@@ -417,19 +417,19 @@ Status CloudFileSystemOptions::Serialize(const ConfigOptions& config_options,
417417
reinterpret_cast<const char*>(this), value);
418418
}
419419

420-
CloudFileSystem::CloudFileSystem(const CloudFileSystemOptions& options,
421-
const std::shared_ptr<FileSystem>& base,
422-
const std::shared_ptr<Logger>& logger)
420+
CloudFileSystemEnv::CloudFileSystemEnv(const CloudFileSystemOptions& options,
421+
const std::shared_ptr<FileSystem>& base,
422+
const std::shared_ptr<Logger>& logger)
423423
: cloud_fs_options(options), base_fs_(base), info_log_(logger) {
424424
RegisterOptions(&cloud_fs_options, &cloud_fs_option_type_info);
425425
}
426426

427-
CloudFileSystem::~CloudFileSystem() {
427+
CloudFileSystemEnv::~CloudFileSystemEnv() {
428428
cloud_fs_options.cloud_log_controller.reset();
429429
cloud_fs_options.storage_provider.reset();
430430
}
431431

432-
Status CloudFileSystem::NewAwsFileSystem(
432+
Status CloudFileSystemEnv::NewAwsFileSystem(
433433
const std::shared_ptr<FileSystem>& base_fs,
434434
const std::string& src_cloud_bucket, const std::string& src_cloud_object,
435435
const std::string& src_cloud_region, const std::string& dest_cloud_bucket,
@@ -484,23 +484,23 @@ int DoRegisterCloudObjects(ObjectLibrary& library, const std::string& arg) {
484484
return count;
485485
}
486486

487-
void CloudFileSystem::RegisterCloudObjects(const std::string& arg) {
487+
void CloudFileSystemEnv::RegisterCloudObjects(const std::string& arg) {
488488
static std::once_flag do_once;
489489
std::call_once(do_once, [&]() {
490490
auto library = ObjectLibrary::Default();
491491
DoRegisterCloudObjects(*library, arg);
492492
});
493493
}
494494

495-
std::unique_ptr<Env> CloudFileSystem::NewCompositeEnvFromThis(Env* env) {
495+
std::unique_ptr<Env> CloudFileSystemEnv::NewCompositeEnvFromThis(Env* env) {
496496
// We need a shared_ptr<FileSystem> pointing to "this", to initialize the
497497
// env wrapper, but we don't want that shared_ptr to own the lifecycle for
498498
// "this". Creating a shared_ptr with a custom no-op deleter instead.
499499
std::shared_ptr<FileSystem> fs(this, [](auto* /*p*/) { /*noop*/ });
500500
return std::make_unique<CompositeEnvWrapper>(env, fs);
501501
}
502502

503-
Status CloudFileSystem::CreateFromString(
503+
Status CloudFileSystemEnv::CreateFromString(
504504
const ConfigOptions& config_options, const std::string& value,
505505
std::unique_ptr<CloudFileSystem>* result) {
506506
RegisterCloudObjects();
@@ -529,7 +529,7 @@ Status CloudFileSystem::CreateFromString(
529529
copy.invoke_prepare_options = false; // Prepare here, not there
530530
s = ObjectRegistry::NewInstance()->NewUniqueObject<FileSystem>(id, &fs);
531531
if (s.ok()) {
532-
auto* cfs = dynamic_cast<CloudFileSystem*>(fs.get());
532+
auto* cfs = dynamic_cast<CloudFileSystemEnv*>(fs.get());
533533
assert(cfs);
534534
if (!options.empty()) {
535535
s = cfs->ConfigureFromMap(copy, options);
@@ -553,7 +553,7 @@ Status CloudFileSystem::CreateFromString(
553553
return s;
554554
}
555555

556-
Status CloudFileSystem::CreateFromString(
556+
Status CloudFileSystemEnv::CreateFromString(
557557
const ConfigOptions& config_options, const std::string& value,
558558
const CloudFileSystemOptions& cloud_options,
559559
std::unique_ptr<CloudFileSystem>* result) {
@@ -583,7 +583,7 @@ Status CloudFileSystem::CreateFromString(
583583
copy.invoke_prepare_options = false; // Prepare here, not there
584584
s = ObjectRegistry::NewInstance()->NewUniqueObject<FileSystem>(id, &fs);
585585
if (s.ok()) {
586-
auto* cfs = dynamic_cast<CloudFileSystem*>(fs.get());
586+
auto* cfs = dynamic_cast<CloudFileSystemEnv*>(fs.get());
587587
assert(cfs);
588588
auto copts = cfs->GetOptions<CloudFileSystemOptions>();
589589
*copts = cloud_options;
@@ -610,18 +610,18 @@ Status CloudFileSystem::CreateFromString(
610610
}
611611

612612
#ifndef USE_AWS
613-
Status CloudFileSystem::NewAwsFileSystem(
613+
Status CloudFileSystemEnv::NewAwsFileSystem(
614614
const std::shared_ptr<FileSystem>& /*base_fs*/,
615615
const CloudFileSystemOptions& /*options*/,
616616
const std::shared_ptr<Logger>& /*logger*/, CloudFileSystem** /*cfs*/) {
617617
return Status::NotSupported("RocksDB Cloud not compiled with AWS support");
618618
}
619619
#else
620-
Status CloudFileSystem::NewAwsFileSystem(
620+
Status CloudFileSystemEnv::NewAwsFileSystem(
621621
const std::shared_ptr<FileSystem>& base_fs,
622622
const CloudFileSystemOptions& options,
623623
const std::shared_ptr<Logger>& logger, CloudFileSystem** cfs) {
624-
CloudFileSystem::RegisterCloudObjects();
624+
CloudFileSystemEnv::RegisterCloudObjects();
625625
// Dump out cloud fs options
626626
options.Dump(logger.get());
627627

@@ -640,9 +640,8 @@ Status CloudFileSystem::NewAwsFileSystem(
640640
}
641641
#endif
642642

643-
std::unique_ptr<Env> CloudFileSystem::NewCompositeEnv(
644-
Env* env,
645-
const std::shared_ptr<FileSystem>& fs) {
643+
std::unique_ptr<Env> CloudFileSystemEnv::NewCompositeEnv(
644+
Env* env, const std::shared_ptr<FileSystem>& fs) {
646645
return std::make_unique<CompositeEnvWrapper>(env, fs);
647646
}
648647

cloud/cloud_file_system_impl.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include <cinttypes>
77

8-
#include "rocksdb/cloud/cloud_file_deletion_scheduler.h"
98
#include "cloud/cloud_log_controller_impl.h"
109
#include "cloud/cloud_manifest.h"
1110
#include "cloud/cloud_scheduler.h"
@@ -18,6 +17,7 @@
1817
#include "file/writable_file_writer.h"
1918
#include "port/likely.h"
2019
#include "port/port_posix.h"
20+
#include "rocksdb/cloud/cloud_file_deletion_scheduler.h"
2121
#include "rocksdb/cloud/cloud_log_controller.h"
2222
#include "rocksdb/cloud/cloud_storage_provider.h"
2323
#include "rocksdb/db.h"
@@ -33,7 +33,7 @@ namespace ROCKSDB_NAMESPACE {
3333
CloudFileSystemImpl::CloudFileSystemImpl(
3434
const CloudFileSystemOptions& opts, const std::shared_ptr<FileSystem>& base,
3535
const std::shared_ptr<Logger>& l)
36-
: CloudFileSystem(opts, base, l), purger_is_running_(true) {
36+
: CloudFileSystemEnv(opts, base, l), purger_is_running_(true) {
3737
if (opts.cloud_file_deletion_delay) {
3838
cloud_file_deletion_scheduler_ = CloudFileDeletionScheduler::Create(
3939
CloudScheduler::Get(), *opts.cloud_file_deletion_delay);

include/rocksdb/cloud/cloud_file_system.h

Lines changed: 115 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -488,45 +488,15 @@ struct CloudManifestDelta {
488488
std::string epoch; // epoch for the new manifest file
489489
};
490490

491-
//
492-
// The Cloud file system
493-
//
494-
// NOTE: The AWS SDK must be initialized before the CloudFileSystem is
495-
// constructed, and remain active (Aws::ShutdownAPI() not called) as long as any
496-
// CloudFileSystem objects exist.
491+
/** Extension of the FileSystem API for "the Cloud" */
497492
class CloudFileSystem : public FileSystem {
498-
protected:
499-
CloudFileSystemOptions cloud_fs_options;
500-
std::shared_ptr<FileSystem> base_fs_; // The underlying file system
501-
502-
// Creates a new CompositeEnv from "env" and "this".
503-
// The returned Env must not outlive "this"
504-
std::unique_ptr<Env> NewCompositeEnvFromThis(Env* env);
505-
506-
CloudFileSystem(const CloudFileSystemOptions& options,
507-
const std::shared_ptr<FileSystem>& base,
508-
const std::shared_ptr<Logger>& logger);
509-
510493
public:
511-
mutable std::shared_ptr<Logger> info_log_; // informational messages
512-
513-
virtual ~CloudFileSystem();
514-
515-
static void RegisterCloudObjects(const std::string& mode = "");
516-
static Status CreateFromString(const ConfigOptions& config_options,
517-
const std::string& id,
518-
std::unique_ptr<CloudFileSystem>* fs);
519-
static Status CreateFromString(const ConfigOptions& config_options,
520-
const std::string& id,
521-
const CloudFileSystemOptions& cloud_options,
522-
std::unique_ptr<CloudFileSystem>* fs);
523494
static const char* kCloud() { return "cloud"; }
524495
static const char* kAws() { return "aws"; }
525-
virtual const char* Name() const { return "cloud-env"; }
496+
526497
// Returns the underlying file system
527-
const std::shared_ptr<FileSystem>& GetBaseFileSystem() const {
528-
return base_fs_;
529-
}
498+
virtual const std::shared_ptr<FileSystem>& GetBaseFileSystem() const = 0;
499+
530500
virtual IOStatus PreloadCloudManifest(const std::string& local_dbname) = 0;
531501
// This method will migrate the database that is using pure RocksDB into
532502
// RocksDB-Cloud. Call this before opening the database with RocksDB-Cloud.
@@ -550,52 +520,6 @@ class CloudFileSystem : public FileSystem {
550520
virtual IOStatus DeleteDbid(const std::string& bucket_prefix,
551521
const std::string& dbid) = 0;
552522

553-
Logger* GetLogger() const { return info_log_.get(); }
554-
const std::shared_ptr<CloudStorageProvider>& GetStorageProvider() const {
555-
return cloud_fs_options.storage_provider;
556-
}
557-
558-
const std::shared_ptr<CloudLogController>& GetLogController() const {
559-
return cloud_fs_options.cloud_log_controller;
560-
}
561-
562-
// The SrcBucketName identifies the cloud storage bucket and
563-
// GetSrcObjectPath specifies the path inside that bucket
564-
// where data files reside. The specified bucket is used in
565-
// a readonly mode by the associated DBCloud instance.
566-
const std::string& GetSrcBucketName() const {
567-
return cloud_fs_options.src_bucket.GetBucketName();
568-
}
569-
const std::string& GetSrcObjectPath() const {
570-
return cloud_fs_options.src_bucket.GetObjectPath();
571-
}
572-
bool HasSrcBucket() const { return cloud_fs_options.src_bucket.IsValid(); }
573-
574-
// The DestBucketName identifies the cloud storage bucket and
575-
// GetDestObjectPath specifies the path inside that bucket
576-
// where data files reside. The associated DBCloud instance
577-
// writes newly created files to this bucket.
578-
const std::string& GetDestBucketName() const {
579-
return cloud_fs_options.dest_bucket.GetBucketName();
580-
}
581-
const std::string& GetDestObjectPath() const {
582-
return cloud_fs_options.dest_bucket.GetObjectPath();
583-
}
584-
585-
bool HasDestBucket() const { return cloud_fs_options.dest_bucket.IsValid(); }
586-
bool SrcMatchesDest() const {
587-
if (HasSrcBucket() && HasDestBucket()) {
588-
return cloud_fs_options.src_bucket == cloud_fs_options.dest_bucket;
589-
} else {
590-
return false;
591-
}
592-
}
593-
594-
// returns the options used to create this object
595-
const CloudFileSystemOptions& GetCloudFileSystemOptions() const {
596-
return cloud_fs_options;
597-
}
598-
599523
// Deletes file from a destination bucket.
600524
virtual IOStatus DeleteCloudFileFromDest(const std::string& fname) = 0;
601525
// Copies a local file to a destination bucket.
@@ -663,6 +587,117 @@ class CloudFileSystem : public FileSystem {
663587
const std::string& dbname,
664588
const std::vector<std::string>& active_cookies) = 0;
665589

590+
// returns the options used to create this object
591+
virtual const CloudFileSystemOptions& GetCloudFileSystemOptions() const = 0;
592+
593+
// The SrcBucketName identifies the cloud storage bucket and
594+
// GetSrcObjectPath specifies the path inside that bucket
595+
// where data files reside. The specified bucket is used in
596+
// a readonly mode by the associated DBCloud instance.
597+
virtual const std::string& GetSrcBucketName() const = 0;
598+
virtual const std::string& GetSrcObjectPath() const = 0;
599+
virtual bool HasSrcBucket() const = 0;
600+
601+
// The DestBucketName identifies the cloud storage bucket and
602+
// GetDestObjectPath specifies the path inside that bucket
603+
// where data files reside. The associated DBCloud instance
604+
// writes newly created files to this bucket.
605+
virtual const std::string& GetDestBucketName() const = 0;
606+
virtual const std::string& GetDestObjectPath() const = 0;
607+
virtual bool HasDestBucket() const = 0;
608+
609+
virtual bool SrcMatchesDest() const = 0;
610+
611+
// Get the storage provider for the FileSystem.
612+
virtual const std::shared_ptr<CloudStorageProvider>& GetStorageProvider()
613+
const = 0;
614+
615+
virtual Logger* GetLogger() const = 0;
616+
};
617+
618+
//
619+
// The Cloud file system
620+
//
621+
// NOTE: The AWS SDK must be initialized before the CloudFileSystem is
622+
// constructed, and remain active (Aws::ShutdownAPI() not called) as long as any
623+
// CloudFileSystem objects exist.
624+
class CloudFileSystemEnv : public CloudFileSystem {
625+
protected:
626+
CloudFileSystemOptions cloud_fs_options;
627+
std::shared_ptr<FileSystem> base_fs_; // The underlying file system
628+
629+
// Creates a new CompositeEnv from "env" and "this".
630+
// The returned Env must not outlive "this"
631+
std::unique_ptr<Env> NewCompositeEnvFromThis(Env* env);
632+
633+
CloudFileSystemEnv(const CloudFileSystemOptions& options,
634+
const std::shared_ptr<FileSystem>& base,
635+
const std::shared_ptr<Logger>& logger);
636+
637+
public:
638+
mutable std::shared_ptr<Logger> info_log_; // informational messages
639+
640+
virtual ~CloudFileSystemEnv();
641+
642+
static void RegisterCloudObjects(const std::string& mode = "");
643+
static Status CreateFromString(const ConfigOptions& config_options,
644+
const std::string& id,
645+
std::unique_ptr<CloudFileSystem>* fs);
646+
static Status CreateFromString(const ConfigOptions& config_options,
647+
const std::string& id,
648+
const CloudFileSystemOptions& cloud_options,
649+
std::unique_ptr<CloudFileSystem>* fs);
650+
651+
const char* Name() const override { return "cloud-env"; }
652+
653+
const std::shared_ptr<FileSystem>& GetBaseFileSystem() const override {
654+
return base_fs_;
655+
}
656+
657+
Logger* GetLogger() const override { return info_log_.get(); }
658+
659+
const std::shared_ptr<CloudStorageProvider>& GetStorageProvider()
660+
const override {
661+
return cloud_fs_options.storage_provider;
662+
}
663+
664+
const std::shared_ptr<CloudLogController>& GetLogController() const {
665+
return cloud_fs_options.cloud_log_controller;
666+
}
667+
668+
const std::string& GetSrcBucketName() const override {
669+
return cloud_fs_options.src_bucket.GetBucketName();
670+
}
671+
const std::string& GetSrcObjectPath() const override {
672+
return cloud_fs_options.src_bucket.GetObjectPath();
673+
}
674+
bool HasSrcBucket() const override {
675+
return cloud_fs_options.src_bucket.IsValid();
676+
}
677+
678+
const std::string& GetDestBucketName() const override {
679+
return cloud_fs_options.dest_bucket.GetBucketName();
680+
}
681+
const std::string& GetDestObjectPath() const override {
682+
return cloud_fs_options.dest_bucket.GetObjectPath();
683+
}
684+
685+
bool HasDestBucket() const override {
686+
return cloud_fs_options.dest_bucket.IsValid();
687+
}
688+
bool SrcMatchesDest() const override {
689+
if (HasSrcBucket() && HasDestBucket()) {
690+
return cloud_fs_options.src_bucket == cloud_fs_options.dest_bucket;
691+
} else {
692+
return false;
693+
}
694+
}
695+
696+
// returns the options used to create this object
697+
const CloudFileSystemOptions& GetCloudFileSystemOptions() const override {
698+
return cloud_fs_options;
699+
}
700+
666701
// Create a new AWS file system.
667702
// src_bucket_name: bucket name suffix where db data is read from
668703
// src_object_prefix: all db objects in source bucket are prepended with this

0 commit comments

Comments
 (0)