2017-02-04 16:01:15 +08:00
|
|
|
#pragma once
|
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
#include <atomic>
|
2017-12-19 19:40:30 +08:00
|
|
|
#include <memory>
|
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
#include "gflags/gflags.h"
|
|
|
|
#include "glog/logging.h"
|
LabelProperty index.
Summary:
Add return values.
After merge.
Inital working version. Still missing comments.
Update documentation.
Add checking for previous vlist and value equality.
After merge.
Remove functor, add boolean ffunction.
Build index.
More functionality. Start implementing tests.
Add tests.
Reviewers: matej.gradicek, mislav.bradac, mferencevic, buda, florijan
Reviewed By: mislav.bradac, buda, florijan
Subscribers: lion, florijan, teon.banek, buda, pullbot
Differential Revision: https://phabricator.memgraph.io/D355
2017-05-16 20:47:03 +08:00
|
|
|
|
2018-01-10 19:18:03 +08:00
|
|
|
#include "database/counters.hpp"
|
2018-01-12 22:17:04 +08:00
|
|
|
#include "database/storage.hpp"
|
|
|
|
#include "database/storage_gc.hpp"
|
2017-11-13 16:50:49 +08:00
|
|
|
#include "durability/wal.hpp"
|
2018-01-15 21:03:07 +08:00
|
|
|
#include "io/network/endpoint.hpp"
|
2017-11-23 23:36:54 +08:00
|
|
|
#include "storage/concurrent_id_mapper.hpp"
|
2018-01-16 17:09:15 +08:00
|
|
|
#include "storage/types.hpp"
|
2017-02-18 18:54:37 +08:00
|
|
|
#include "transactions/engine.hpp"
|
2017-04-10 21:44:36 +08:00
|
|
|
#include "utils/scheduler.hpp"
|
2017-02-04 16:01:15 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
namespace database {
|
|
|
|
|
|
|
|
/// Database configuration. Initialized from flags, but modifiable.
|
|
|
|
struct Config {
|
|
|
|
Config();
|
|
|
|
// Durability flags.
|
|
|
|
bool durability_enabled;
|
|
|
|
std::string durability_directory;
|
|
|
|
bool db_recover_on_startup;
|
|
|
|
int snapshot_cycle_sec;
|
|
|
|
int snapshot_max_retained;
|
|
|
|
int snapshot_on_exit;
|
|
|
|
|
|
|
|
// Misc flags.
|
|
|
|
int gc_cycle_sec;
|
|
|
|
int query_execution_time_sec;
|
|
|
|
|
|
|
|
// Distributed master/worker flags.
|
|
|
|
int worker_id;
|
2018-01-15 21:03:07 +08:00
|
|
|
io::network::Endpoint master_endpoint;
|
|
|
|
io::network::Endpoint worker_endpoint;
|
2018-01-12 22:17:04 +08:00
|
|
|
};
|
|
|
|
|
2017-02-04 16:01:15 +08:00
|
|
|
/**
|
2018-01-12 22:17:04 +08:00
|
|
|
* An abstract base class for a SingleNode/Master/Worker graph db.
|
2017-10-30 17:43:25 +08:00
|
|
|
*
|
|
|
|
* Always be sure that GraphDb object is destructed before main exits, i. e.
|
|
|
|
* GraphDb object shouldn't be part of global/static variable, except if its
|
|
|
|
* destructor is explicitly called before main exits. Consider code:
|
|
|
|
*
|
2018-01-12 22:17:04 +08:00
|
|
|
* GraphDb db; // KeyIndex is created as a part of database::Storage
|
2017-10-30 17:43:25 +08:00
|
|
|
* int main() {
|
|
|
|
* GraphDbAccessor dba(db);
|
|
|
|
* auto v = dba.InsertVertex();
|
|
|
|
* v.add_label(dba.Label(
|
|
|
|
* "Start")); // New SkipList is created in KeyIndex for LabelIndex.
|
|
|
|
* // That SkipList creates SkipListGc which
|
|
|
|
* // initialises static Executor object.
|
|
|
|
* return 0;
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* After main exits: 1. Executor is destructed, 2. KeyIndex is destructed.
|
|
|
|
* Destructor of KeyIndex calls delete on created SkipLists which destroy
|
|
|
|
* SkipListGc that tries to use Excutioner object that doesn't exist anymore.
|
|
|
|
* -> CRASH
|
2017-02-04 16:01:15 +08:00
|
|
|
*/
|
2017-06-21 17:29:13 +08:00
|
|
|
class GraphDb {
|
2017-02-18 18:54:37 +08:00
|
|
|
public:
|
2018-01-19 21:49:58 +08:00
|
|
|
GraphDb() {}
|
|
|
|
virtual ~GraphDb() {}
|
|
|
|
|
|
|
|
virtual Storage &storage() = 0;
|
|
|
|
virtual durability::WriteAheadLog &wal() = 0;
|
|
|
|
virtual tx::Engine &tx_engine() = 0;
|
|
|
|
virtual storage::ConcurrentIdMapper<storage::Label> &label_mapper() = 0;
|
|
|
|
virtual storage::ConcurrentIdMapper<storage::EdgeType>
|
|
|
|
&edge_type_mapper() = 0;
|
|
|
|
virtual storage::ConcurrentIdMapper<storage::Property> &property_mapper() = 0;
|
|
|
|
virtual database::Counters &counters() = 0;
|
|
|
|
virtual void CollectGarbage() = 0;
|
|
|
|
virtual int WorkerId() const = 0;
|
|
|
|
|
|
|
|
GraphDb(const GraphDb &) = delete;
|
|
|
|
GraphDb(GraphDb &&) = delete;
|
|
|
|
GraphDb &operator=(const GraphDb &) = delete;
|
|
|
|
GraphDb &operator=(GraphDb &&) = delete;
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace impl {
|
|
|
|
// Private GraphDb implementations all inherit `PrivateBase`.
|
|
|
|
// Public GraphDb implementations all inherit `PublicBase`.
|
|
|
|
class PrivateBase;
|
|
|
|
|
|
|
|
// Base class for all GraphDb implementations exposes to the client programmer.
|
|
|
|
// Encapsulates an instance of a private implementation of GraphDb and performs
|
|
|
|
// initialization and cleanup.
|
|
|
|
class PublicBase : public GraphDb {
|
|
|
|
public:
|
|
|
|
Storage &storage() override;
|
|
|
|
durability::WriteAheadLog &wal() override;
|
|
|
|
tx::Engine &tx_engine() override;
|
|
|
|
storage::ConcurrentIdMapper<storage::Label> &label_mapper() override;
|
|
|
|
storage::ConcurrentIdMapper<storage::EdgeType> &edge_type_mapper() override;
|
|
|
|
storage::ConcurrentIdMapper<storage::Property> &property_mapper() override;
|
|
|
|
database::Counters &counters() override;
|
|
|
|
void CollectGarbage() override;
|
|
|
|
int WorkerId() const override;
|
2017-10-30 17:43:25 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
protected:
|
2018-01-19 21:49:58 +08:00
|
|
|
explicit PublicBase(std::unique_ptr<PrivateBase> impl);
|
|
|
|
~PublicBase();
|
2017-12-20 19:48:19 +08:00
|
|
|
|
2018-01-19 21:49:58 +08:00
|
|
|
std::unique_ptr<PrivateBase> impl_;
|
2017-10-30 17:43:25 +08:00
|
|
|
|
|
|
|
private:
|
2018-01-12 22:17:04 +08:00
|
|
|
std::unique_ptr<Scheduler> snapshot_creator_;
|
2017-11-13 16:50:49 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
void MakeSnapshot();
|
|
|
|
};
|
2018-01-19 21:49:58 +08:00
|
|
|
} // namespace impl
|
2017-04-10 21:44:36 +08:00
|
|
|
|
2018-01-19 21:49:58 +08:00
|
|
|
class MasterBase : public impl::PublicBase {
|
2018-01-12 22:17:04 +08:00
|
|
|
public:
|
2018-01-19 21:49:58 +08:00
|
|
|
explicit MasterBase(std::unique_ptr<impl::PrivateBase> impl);
|
2018-01-12 22:17:04 +08:00
|
|
|
bool is_accepting_transactions() const { return is_accepting_transactions_; }
|
2017-08-11 15:48:13 +08:00
|
|
|
|
2018-01-19 21:49:58 +08:00
|
|
|
~MasterBase();
|
2017-05-17 16:08:57 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
private:
|
|
|
|
/** When this is false, no new transactions should be created. */
|
|
|
|
std::atomic<bool> is_accepting_transactions_{true};
|
2017-08-17 15:19:58 +08:00
|
|
|
Scheduler transaction_killer_;
|
2018-01-12 22:17:04 +08:00
|
|
|
};
|
2017-09-13 23:09:04 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
class SingleNode : public MasterBase {
|
|
|
|
public:
|
|
|
|
explicit SingleNode(Config config = Config());
|
|
|
|
};
|
2017-12-19 19:40:30 +08:00
|
|
|
|
2018-01-12 22:17:04 +08:00
|
|
|
class Master : public MasterBase {
|
|
|
|
public:
|
|
|
|
explicit Master(Config config = Config());
|
|
|
|
};
|
2017-12-19 19:40:30 +08:00
|
|
|
|
2018-01-19 21:49:58 +08:00
|
|
|
class Worker : public impl::PublicBase {
|
2018-01-12 22:17:04 +08:00
|
|
|
public:
|
|
|
|
explicit Worker(Config config = Config());
|
|
|
|
void WaitForShutdown();
|
2017-02-04 16:01:15 +08:00
|
|
|
};
|
2018-01-12 22:17:04 +08:00
|
|
|
} // namespace database
|