2018-01-18 03:14:13 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
2018-02-04 03:22:01 +01:00
|
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
2017-09-19 04:19:02 +02:00
|
|
|
|
|
|
|
#pragma once
|
2018-01-30 18:58:36 +01:00
|
|
|
#define HAVE_IRCD_DB_TXN_H
|
2017-09-19 04:19:02 +02:00
|
|
|
|
|
|
|
namespace ircd::db
|
|
|
|
{
|
2018-01-30 18:58:36 +01:00
|
|
|
struct txn;
|
2017-09-19 04:19:02 +02:00
|
|
|
|
2018-04-17 00:16:51 +02:00
|
|
|
bool for_each(const txn &, const std::function<bool (const delta &)> &);
|
2018-01-30 18:58:36 +01:00
|
|
|
void for_each(const txn &, const std::function<void (const delta &)> &);
|
|
|
|
std::string debug(const txn &);
|
2018-03-23 04:49:11 +01:00
|
|
|
|
2018-03-28 00:21:00 +02:00
|
|
|
using seq_closure_bool = std::function<bool (txn &, const uint64_t &)>;
|
|
|
|
using seq_closure = std::function<void (txn &, const uint64_t &)>;
|
2018-03-23 04:49:11 +01:00
|
|
|
bool for_each(database &d, const uint64_t &seq, const seq_closure_bool &);
|
|
|
|
void for_each(database &d, const uint64_t &seq, const seq_closure &);
|
2018-03-28 00:21:30 +02:00
|
|
|
void get(database &d, const uint64_t &seq, const seq_closure &);
|
2017-09-19 04:19:02 +02:00
|
|
|
}
|
|
|
|
|
2018-03-23 04:48:23 +01:00
|
|
|
struct ircd::db::txn
|
2017-09-19 04:19:02 +02:00
|
|
|
{
|
|
|
|
database *d {nullptr};
|
|
|
|
std::unique_ptr<rocksdb::WriteBatch> wb;
|
|
|
|
|
|
|
|
public:
|
|
|
|
struct opts;
|
2017-09-19 05:43:32 +02:00
|
|
|
struct checkpoint;
|
2017-09-19 04:19:02 +02:00
|
|
|
struct append;
|
|
|
|
struct handler;
|
|
|
|
|
2018-04-17 00:16:51 +02:00
|
|
|
using delta_closure = std::function<void (const delta &)>;
|
|
|
|
using delta_closure_bool = std::function<bool (const delta &)>;
|
|
|
|
using value_closure = std::function<void (const string_view &)>;
|
|
|
|
|
2017-09-19 04:19:02 +02:00
|
|
|
explicit operator const rocksdb::WriteBatch &() const;
|
|
|
|
explicit operator const database &() const;
|
|
|
|
explicit operator rocksdb::WriteBatch &();
|
|
|
|
explicit operator database &();
|
|
|
|
|
2018-04-17 00:16:51 +02:00
|
|
|
bool get(const op &, const string_view &col, const string_view &key, const value_closure &) const;
|
|
|
|
void at(const op &, const string_view &col, const string_view &key, const value_closure &) const;
|
2017-09-19 05:40:13 +02:00
|
|
|
bool has(const op &, const string_view &col, const string_view &key) const;
|
|
|
|
|
2018-04-17 00:16:51 +02:00
|
|
|
bool get(const op &, const string_view &col, const delta_closure &) const;
|
|
|
|
void at(const op &, const string_view &col, const delta_closure &) const;
|
2017-09-19 05:40:13 +02:00
|
|
|
bool has(const op &, const string_view &col) const;
|
2017-09-19 04:19:02 +02:00
|
|
|
bool has(const op &) const;
|
2017-09-19 05:40:13 +02:00
|
|
|
|
2018-09-27 00:28:36 +02:00
|
|
|
size_t bytes() const; // size of data in txn.
|
|
|
|
size_t size() const; // count of updates in txn.
|
2017-09-19 04:19:02 +02:00
|
|
|
|
|
|
|
// commit
|
|
|
|
void operator()(database &, const sopts & = {});
|
|
|
|
void operator()(const sopts & = {});
|
|
|
|
|
|
|
|
// clear
|
|
|
|
void clear();
|
|
|
|
|
2018-01-30 18:58:36 +01:00
|
|
|
txn() = default;
|
|
|
|
txn(database &);
|
|
|
|
txn(database &, const opts &);
|
2018-03-23 04:48:23 +01:00
|
|
|
txn(database &, std::unique_ptr<rocksdb::WriteBatch> &&);
|
2018-01-30 18:58:36 +01:00
|
|
|
~txn() noexcept;
|
2017-09-19 04:19:02 +02:00
|
|
|
};
|
|
|
|
|
2018-01-30 18:58:36 +01:00
|
|
|
struct ircd::db::txn::append
|
2017-09-19 04:19:02 +02:00
|
|
|
{
|
2018-01-30 18:58:36 +01:00
|
|
|
append(txn &, database &, const delta &);
|
|
|
|
append(txn &, column &, const column::delta &);
|
|
|
|
append(txn &, const cell::delta &);
|
|
|
|
append(txn &, const row::delta &);
|
|
|
|
append(txn &, const delta &);
|
|
|
|
append(txn &, const string_view &key, const json::iov &);
|
2018-03-25 06:36:19 +02:00
|
|
|
template<class... T> append(txn &, const string_view &key, const json::tuple<T...> &, const op & = op::SET);
|
|
|
|
template<class... T> append(txn &, const string_view &key, const json::tuple<T...> &, std::array<column, sizeof...(T)> &, const op & = op::SET);
|
2017-09-19 04:19:02 +02:00
|
|
|
};
|
|
|
|
|
2018-01-30 18:58:36 +01:00
|
|
|
struct ircd::db::txn::checkpoint
|
2017-09-19 04:19:02 +02:00
|
|
|
{
|
2018-01-30 18:58:36 +01:00
|
|
|
txn &t;
|
2017-09-19 05:43:32 +02:00
|
|
|
|
2018-01-30 18:58:36 +01:00
|
|
|
checkpoint(txn &);
|
2017-09-19 05:43:32 +02:00
|
|
|
~checkpoint() noexcept;
|
2017-09-19 04:19:02 +02:00
|
|
|
};
|
|
|
|
|
2018-01-30 18:58:36 +01:00
|
|
|
struct ircd::db::txn::opts
|
2017-09-19 04:19:02 +02:00
|
|
|
{
|
|
|
|
size_t reserve_bytes = 0;
|
|
|
|
size_t max_bytes = 0;
|
|
|
|
};
|
2017-10-16 06:13:44 +02:00
|
|
|
|
|
|
|
template<class... T>
|
2018-01-30 18:58:36 +01:00
|
|
|
ircd::db::txn::append::append(txn &txn,
|
2017-10-16 06:13:44 +02:00
|
|
|
const string_view &key,
|
2018-03-25 06:36:19 +02:00
|
|
|
const json::tuple<T...> &tuple,
|
|
|
|
const op &op)
|
2017-10-16 06:13:44 +02:00
|
|
|
{
|
2018-03-25 06:36:19 +02:00
|
|
|
for_each(tuple, [&txn, &key, &op]
|
|
|
|
(const auto &col, auto&& val)
|
2017-10-16 06:13:44 +02:00
|
|
|
{
|
2018-04-12 07:57:10 +02:00
|
|
|
if(!value_required(op) || defined(json::value(val))) append
|
2017-10-16 06:13:44 +02:00
|
|
|
{
|
2018-01-30 18:58:36 +01:00
|
|
|
txn, delta
|
2017-10-16 06:13:44 +02:00
|
|
|
{
|
2018-03-25 06:36:19 +02:00
|
|
|
op,
|
|
|
|
col,
|
|
|
|
key,
|
|
|
|
value_required(op)?
|
|
|
|
byte_view<string_view>{val}:
|
|
|
|
byte_view<string_view>{}
|
2017-10-16 06:13:44 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
2018-03-10 01:21:23 +01:00
|
|
|
|
|
|
|
template<class... T>
|
|
|
|
ircd::db::txn::append::append(txn &txn,
|
|
|
|
const string_view &key,
|
|
|
|
const json::tuple<T...> &tuple,
|
2018-03-25 06:36:19 +02:00
|
|
|
std::array<column, sizeof...(T)> &col,
|
|
|
|
const op &op)
|
2018-03-10 01:21:23 +01:00
|
|
|
{
|
|
|
|
size_t i{0};
|
2018-03-25 06:36:19 +02:00
|
|
|
for_each(tuple, [&txn, &key, &col, &op, &i]
|
|
|
|
(const auto &, auto&& val)
|
2018-03-10 01:21:23 +01:00
|
|
|
{
|
2018-04-12 07:57:10 +02:00
|
|
|
if(!value_required(op) || defined(json::value(val))) append
|
2018-03-10 01:21:23 +01:00
|
|
|
{
|
|
|
|
txn, col.at(i), column::delta
|
|
|
|
{
|
2018-03-25 06:36:19 +02:00
|
|
|
op,
|
|
|
|
key,
|
|
|
|
value_required(op)?
|
|
|
|
byte_view<string_view>{val}:
|
|
|
|
byte_view<string_view>{}
|
2018-03-10 01:21:23 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
++i;
|
|
|
|
});
|
|
|
|
}
|