-
Notifications
You must be signed in to change notification settings - Fork 9
[#1177] Create new class AtomDBFactory #1220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
dfbf5eb
d297947
653c4bd
9e390d6
622d81c
f415feb
edd7624
0eaaa34
2a210e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,11 +16,38 @@ using namespace atoms; | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| namespace atomdb { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| enum class AtomDBType { RedisMongoDB, MorkDB, InMemoryDB, RemoteAtomDB, AdapterDB }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| class AtomDB : public HandleDecoder { | ||||||||||||||||||||||
| public: | ||||||||||||||||||||||
| AtomDB() = default; | ||||||||||||||||||||||
| virtual ~AtomDB() = default; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static AtomDBType string_to_type(const string& type) { | ||||||||||||||||||||||
| if (type == "redismongodb") return AtomDBType::RedisMongoDB; | ||||||||||||||||||||||
| if (type == "morkdb") return AtomDBType::MorkDB; | ||||||||||||||||||||||
| if (type == "inmemorydb") return AtomDBType::InMemoryDB; | ||||||||||||||||||||||
| if (type == "remotedb") return AtomDBType::RemoteAtomDB; | ||||||||||||||||||||||
| if (type == "adapterdb") return AtomDBType::AdapterDB; | ||||||||||||||||||||||
| RAISE_ERROR("Unsupported atomdb.type: " + type); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static string type_to_string(AtomDBType type) { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make sure this method is not causing a compilation warning because of the lack of a return statement. |
||||||||||||||||||||||
| switch (type) { | ||||||||||||||||||||||
| case AtomDBType::RedisMongoDB: | ||||||||||||||||||||||
| return "redismongodb"; | ||||||||||||||||||||||
| case AtomDBType::MorkDB: | ||||||||||||||||||||||
| return "morkdb"; | ||||||||||||||||||||||
| case AtomDBType::InMemoryDB: | ||||||||||||||||||||||
| return "inmemorydb"; | ||||||||||||||||||||||
| case AtomDBType::RemoteAtomDB: | ||||||||||||||||||||||
| return "remotedb"; | ||||||||||||||||||||||
| case AtomDBType::AdapterDB: | ||||||||||||||||||||||
| return "adapterdb"; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| RAISE_ERROR("Unsupported AtomDBType"); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+45
to
+49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| virtual bool allow_nested_indexing() = 0; | ||||||||||||||||||||||
| virtual bool composite_type_enabled() const = 0; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| #include "AtomDBFactory.h" | ||
|
|
||
| #include "AdapterDB.h" | ||
| #include "InMemoryDB.h" | ||
| #include "MorkDB.h" | ||
| #include "RedisMongoDB.h" | ||
| #include "RemoteAtomDB.h" | ||
| #include "Utils.h" | ||
|
|
||
| using namespace atomdb; | ||
| using namespace commons; | ||
|
|
||
| // -------------------------------------------------------------------------------- | ||
| // Public methods | ||
|
|
||
| shared_ptr<AtomDB> AtomDBFactory::create(const JsonConfig& config, const string& context) { | ||
| auto atomdb_type = config.at_path("type").get_or<string>(""); | ||
|
|
||
| AtomDBType type = AtomDB::string_to_type(atomdb_type); | ||
|
|
||
| shared_ptr<AtomDB> atomdb; | ||
|
|
||
| if (type == AtomDBType::RedisMongoDB || type == AtomDBType::MorkDB || | ||
| type == AtomDBType::InMemoryDB) { | ||
| atomdb = create_basic_atomdb(config, context); | ||
| } else if (type == AtomDBType::RemoteAtomDB || type == AtomDBType::AdapterDB) { | ||
| atomdb = create_composite_atomdb(config, context); | ||
| } else { | ||
| RAISE_ERROR("AtomDBFactory: unsupported AtomDB type: " + atomdb_type); | ||
| } | ||
|
|
||
| return wrap_if_protected(atomdb); | ||
| } | ||
|
|
||
| // -------------------------------------------------------------------------------- | ||
| // Private methods | ||
|
|
||
| shared_ptr<AtomDB> AtomDBFactory::create_basic_atomdb(const JsonConfig& config, const string& context) { | ||
| auto atomdb_type = config.at_path("type").get_or<string>(""); | ||
|
|
||
| AtomDBType type = AtomDB::string_to_type(atomdb_type); | ||
|
|
||
| shared_ptr<AtomDB> atomdb; | ||
|
|
||
| if (type == AtomDBType::RedisMongoDB) { | ||
| // make_shared cannot access RedisMongoDB's private ctor; friend can via new. | ||
| atomdb = shared_ptr<RedisMongoDB>(new RedisMongoDB(context, false, config)); | ||
|
andre-senna marked this conversation as resolved.
|
||
| } else if (type == AtomDBType::MorkDB) { | ||
| atomdb = make_shared<MorkDB>(context, config); | ||
| } else if (type == AtomDBType::InMemoryDB) { | ||
| atomdb = make_shared<InMemoryDB>(context.empty() ? "inmemorydb_" : context); | ||
| } else { | ||
| RAISE_ERROR("AtomDBFactory: '" + atomdb_type + "' is not a basic AtomDB type"); | ||
| } | ||
|
|
||
| return atomdb; | ||
| } | ||
|
|
||
| shared_ptr<AtomDB> AtomDBFactory::create_composite_atomdb(const JsonConfig& config, | ||
| const string& context) { | ||
| auto atomdb_type = config.at_path("type").get_or<string>(""); | ||
|
|
||
| AtomDBType type = AtomDB::string_to_type(atomdb_type); | ||
|
|
||
| shared_ptr<AtomDB> atomdb; | ||
|
|
||
| if (type == AtomDBType::RemoteAtomDB) { | ||
| auto remote_peers_config = config.at_path("remote_peers").get_or<JsonConfig>(JsonConfig()); | ||
|
|
||
| map<string, shared_ptr<RemoteAtomDBPeer>> remote_peers; | ||
|
|
||
| for (auto& entry : remote_peers_config) { | ||
| auto peer_config = JsonConfig(entry); | ||
| string uid = peer_config.at_path("uid").get_or<string>(""); | ||
| if (uid.empty()) { | ||
| RAISE_ERROR("AtomDBFactory: remote peer is missing a non-empty uid"); | ||
| } | ||
|
|
||
| string peer_context = peer_config.at_path("context").get_or<string>(""); | ||
| if (peer_context.empty()) { | ||
| peer_context = "remotedb_" + uid; | ||
| } | ||
|
|
||
| shared_ptr<AtomDB> local_persistence = nullptr; | ||
| auto local_persistence_config = | ||
| peer_config.at_path("local_persistence").get_or<JsonConfig>(JsonConfig()); | ||
| if (!local_persistence_config.empty()) { | ||
| string local_context = | ||
| local_persistence_config.at_path("context").get_or<string>(peer_context); | ||
| if (local_context.empty()) { | ||
| local_context = peer_context; | ||
| } | ||
| local_persistence = create_basic_atomdb(local_persistence_config, local_context); | ||
| } | ||
| remote_peers[uid] = make_shared<RemoteAtomDBPeer>( | ||
| create_basic_atomdb(peer_config, peer_context), local_persistence, uid); | ||
| } | ||
|
|
||
| return make_shared<RemoteAtomDB>(remote_peers); | ||
| } | ||
|
|
||
| if (type == AtomDBType::AdapterDB) { | ||
| // The backend AtomDB in AdapterDB could be RemoteAtomDB ? | ||
| auto atomdb_backend_config = | ||
| config.at_path("adapterdb.atomdb_backend").get_or<JsonConfig>(JsonConfig()); | ||
| auto basic_atomdb = create_basic_atomdb(atomdb_backend_config, context); | ||
| return make_shared<AdapterDB>(config, basic_atomdb); | ||
| } | ||
|
|
||
| return atomdb; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is correct but unnatural. Just return |
||
| } | ||
|
|
||
| shared_ptr<AtomDB> AtomDBFactory::wrap_if_protected(shared_ptr<AtomDB> atomdb) { | ||
| // AtomDBFactory::wrap_if_protected() is not implemented yet. | ||
| return atomdb; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #pragma once | ||
|
|
||
| #include <memory> | ||
| #include <string> | ||
|
|
||
| #include "AtomDB.h" | ||
| #include "JsonConfig.h" | ||
|
|
||
| using namespace std; | ||
| using namespace commons; | ||
|
|
||
| namespace atomdb { | ||
|
|
||
| /** | ||
| * @brief Factory that builds AtomDB instances from a JsonConfig. | ||
| * | ||
| * This is the preferred way to obtain an AtomDB. Callers should not construct | ||
| * RedisMongoDB, MorkDB, InMemoryDB, RemoteAtomDB, or AdapterDB directly; instead | ||
| * pass a config whose "type" field selects the concrete implementation. | ||
| * | ||
| * Two kinds of AtomDB are supported: | ||
| * - Basic: RedisMongoDB, MorkDB, InMemoryDB — constructed from their own config. | ||
| * - Composite: RemoteAtomDB and AdapterDB — built by composing one or more basic | ||
| * AtomDBs (remote peers for RemoteAtomDB; a wrapped AtomDB for AdapterDB). | ||
| * | ||
| */ | ||
| class AtomDBFactory { | ||
| public: | ||
| /** | ||
| * @brief Creates a AtomDB and wraps it with ProtectedAtomDB when is applyable. | ||
| */ | ||
| static shared_ptr<AtomDB> create(const JsonConfig& config, const string& context = ""); | ||
|
|
||
| private: | ||
| // Supported types: redismongodb, morkdb, inmemorydb. | ||
| static shared_ptr<AtomDB> create_basic_atomdb(const JsonConfig& config, const string& context = ""); | ||
|
|
||
| // Supported types: remotedb, adapterdb. | ||
| static shared_ptr<AtomDB> create_composite_atomdb(const JsonConfig& config, | ||
| const string& context = ""); | ||
|
|
||
| /** | ||
| * @brief Wraps an AtomDB with ProtectedAtomDB when protected and not already wrapped. | ||
| */ | ||
| static shared_ptr<AtomDB> wrap_if_protected(shared_ptr<AtomDB> atomdb); | ||
| }; | ||
|
|
||
| } // namespace atomdb |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,6 @@ enum MONGODB_FIELD { ID = 0, NAME, TARGETS, NAMED_TYPE, size }; | |
|
|
||
| class RedisMongoDB : public AtomDB { | ||
| public: | ||
| RedisMongoDB(const string& context, bool skip_redis, const JsonConfig& config); | ||
| ~RedisMongoDB(); | ||
|
|
||
| bool allow_nested_indexing() override; | ||
|
|
@@ -146,6 +145,11 @@ class RedisMongoDB : public AtomDB { | |
| map<string, vector<string>>& composite_type_entries_map); | ||
|
|
||
| private: | ||
| friend class AtomDBFactory; | ||
| friend class MorkDB; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does MorkDB need to be a friend class?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because of this code snippet This causes a compilation error if it is not a friend class
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding MorkDB as a friend is the wrong fix. Make RedisMongo constructor |
||
|
|
||
| RedisMongoDB(const string& context, bool skip_redis, const JsonConfig& config); | ||
|
|
||
| string context; | ||
| bool skip_redis_; | ||
| bool composite_type_enabled_; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure this method is not causing a compilation warning because of the lack of a return statement.