mirror of
https://github.com/matrix-construct/construct
synced 2024-12-28 00:14:07 +01:00
516d7e8ad7
ircd::db::database::allocator: Implement callback for true allocated size hint.
315 lines
11 KiB
C++
315 lines
11 KiB
C++
// Matrix Construct
|
|
//
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
// Copyright (C) 2016-2019 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
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
namespace ircd::db
|
|
{
|
|
const descriptor &describe(const database::column &);
|
|
const std::string &name(const database::column &);
|
|
uint32_t id(const database::column &);
|
|
|
|
bool dropped(const database::column &);
|
|
void drop(database::column &); // Request to erase column from db
|
|
|
|
std::shared_ptr<const database::column> shared_from(const database::column &);
|
|
std::shared_ptr<database::column> shared_from(database::column &);
|
|
}
|
|
|
|
#if ROCKSDB_MAJOR > 6 \
|
|
|| (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR > 4) \
|
|
|| (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR == 4 && ROCKSDB_PATCH >= 6)
|
|
#define IRCD_DB_HAS_CACHE_GETCHARGE
|
|
#endif
|
|
|
|
#if ROCKSDB_MAJOR > 5 \
|
|
|| (ROCKSDB_MAJOR == 5 && ROCKSDB_MINOR >= 18)
|
|
#define IRCD_DB_HAS_ALLOCATOR
|
|
#endif
|
|
|
|
struct ircd::db::database::cache final
|
|
:rocksdb::Cache
|
|
{
|
|
using Slice = rocksdb::Slice;
|
|
using Status = rocksdb::Status;
|
|
using deleter = void (*)(const Slice &key, void *value);
|
|
using callback = void (*)(void *, size_t);
|
|
using Statistics = rocksdb::Statistics;
|
|
|
|
static const int DEFAULT_SHARD_BITS;
|
|
static const double DEFAULT_HI_PRIO;
|
|
static const bool DEFAULT_STRICT;
|
|
|
|
database *d;
|
|
std::string name;
|
|
std::shared_ptr<struct database::stats> stats;
|
|
std::shared_ptr<struct database::allocator> allocator;
|
|
std::shared_ptr<rocksdb::Cache> c;
|
|
|
|
const char *Name() const noexcept override;
|
|
Status Insert(const Slice &key, void *value, size_t charge, deleter, Handle **, Priority) noexcept override;
|
|
Handle *Lookup(const Slice &key, Statistics *) noexcept override;
|
|
bool Ref(Handle *) noexcept override;
|
|
bool Release(Handle *, bool force_erase) noexcept override;
|
|
void *Value(Handle *) noexcept override;
|
|
void Erase(const Slice &key) noexcept override;
|
|
uint64_t NewId() noexcept override;
|
|
void SetCapacity(size_t capacity) noexcept override;
|
|
void SetStrictCapacityLimit(bool strict_capacity_limit) noexcept override;
|
|
bool HasStrictCapacityLimit() const noexcept override;
|
|
size_t GetCapacity() const noexcept override;
|
|
size_t GetUsage() const noexcept override;
|
|
size_t GetUsage(Handle *) const noexcept override;
|
|
size_t GetPinnedUsage() const noexcept override;
|
|
void DisownData() noexcept override;
|
|
void ApplyToAllCacheEntries(callback, bool thread_safe) noexcept override;
|
|
void EraseUnRefEntries() noexcept override;
|
|
std::string GetPrintableOptions() const noexcept override;
|
|
#ifdef IRCD_DB_HAS_CACHE_GETCHARGE
|
|
size_t GetCharge(Handle *) const noexcept override;
|
|
#endif
|
|
|
|
cache(database *const &,
|
|
std::shared_ptr<struct database::stats>,
|
|
std::shared_ptr<struct database::allocator>,
|
|
std::string name,
|
|
const ssize_t &initial_capacity = -1);
|
|
|
|
~cache() noexcept override;
|
|
};
|
|
|
|
struct ircd::db::database::comparator final
|
|
:rocksdb::Comparator
|
|
{
|
|
using Slice = rocksdb::Slice;
|
|
|
|
database *d;
|
|
db::comparator user;
|
|
|
|
bool CanKeysWithDifferentByteContentsBeEqual() const noexcept override;
|
|
bool IsSameLengthImmediateSuccessor(const Slice &s, const Slice &t) const noexcept override;
|
|
void FindShortestSeparator(std::string *start, const Slice &limit) const noexcept override;
|
|
void FindShortSuccessor(std::string *key) const noexcept override;
|
|
int Compare(const Slice &a, const Slice &b) const noexcept override;
|
|
bool Equal(const Slice &a, const Slice &b) const noexcept override;
|
|
const char *Name() const noexcept override;
|
|
|
|
comparator(database *const &d, db::comparator user);
|
|
};
|
|
|
|
struct ircd::db::database::prefix_transform final
|
|
:rocksdb::SliceTransform
|
|
{
|
|
using Slice = rocksdb::Slice;
|
|
|
|
database *d;
|
|
db::prefix_transform user;
|
|
|
|
const char *Name() const noexcept override;
|
|
bool InDomain(const Slice &key) const noexcept override;
|
|
bool InRange(const Slice &key) const noexcept override;
|
|
Slice Transform(const Slice &key) const noexcept override;
|
|
|
|
prefix_transform(database *const &d,
|
|
db::prefix_transform user)
|
|
noexcept
|
|
:d{d}
|
|
,user{std::move(user)}
|
|
{}
|
|
};
|
|
|
|
struct ircd::db::database::mergeop final
|
|
:std::enable_shared_from_this<struct ircd::db::database::mergeop>
|
|
,rocksdb::AssociativeMergeOperator
|
|
{
|
|
database *d;
|
|
merge_closure merger;
|
|
|
|
bool Merge(const rocksdb::Slice &, const rocksdb::Slice *, const rocksdb::Slice &, std::string *, rocksdb::Logger *) const noexcept override;
|
|
const char *Name() const noexcept override;
|
|
|
|
mergeop(database *const &d, merge_closure merger = nullptr);
|
|
~mergeop() noexcept;
|
|
};
|
|
|
|
struct ircd::db::database::compaction_filter final
|
|
:rocksdb::CompactionFilter
|
|
{
|
|
using Slice = rocksdb::Slice;
|
|
|
|
column *c;
|
|
database *d;
|
|
db::compactor user;
|
|
|
|
const char *Name() const noexcept override;
|
|
bool IgnoreSnapshots() const noexcept override;
|
|
Decision FilterV2(const int level, const Slice &key, const ValueType v, const Slice &oldval, std::string *newval, std::string *skipuntil) const noexcept override;
|
|
|
|
compaction_filter(column *const &c, db::compactor);
|
|
~compaction_filter() noexcept override;
|
|
};
|
|
|
|
struct ircd::db::database::column final
|
|
:std::enable_shared_from_this<database::column>
|
|
,rocksdb::ColumnFamilyDescriptor
|
|
{
|
|
database *d;
|
|
db::descriptor *descriptor;
|
|
std::type_index key_type;
|
|
std::type_index mapped_type;
|
|
comparator cmp;
|
|
prefix_transform prefix;
|
|
compaction_filter cfilter;
|
|
std::shared_ptr<struct database::stats> stats;
|
|
std::shared_ptr<struct database::allocator> allocator;
|
|
rocksdb::BlockBasedTableOptions table_opts;
|
|
custom_ptr<rocksdb::ColumnFamilyHandle> handle;
|
|
|
|
public:
|
|
operator const rocksdb::ColumnFamilyOptions &() const;
|
|
operator const rocksdb::ColumnFamilyHandle *() const;
|
|
operator const database &() const;
|
|
|
|
operator rocksdb::ColumnFamilyHandle *();
|
|
operator database &();
|
|
|
|
explicit column(database &d, db::descriptor &);
|
|
column() = delete;
|
|
column(column &&) = delete;
|
|
column(const column &) = delete;
|
|
column &operator=(column &&) = delete;
|
|
column &operator=(const column &) = delete;
|
|
~column() noexcept;
|
|
};
|
|
|
|
struct ircd::db::database::events final
|
|
:std::enable_shared_from_this<struct ircd::db::database::events>
|
|
,rocksdb::EventListener
|
|
{
|
|
database *d;
|
|
|
|
void OnFlushBegin(rocksdb::DB *, const rocksdb::FlushJobInfo &) noexcept override;
|
|
void OnFlushCompleted(rocksdb::DB *, const rocksdb::FlushJobInfo &) noexcept override;
|
|
void OnCompactionCompleted(rocksdb::DB *, const rocksdb::CompactionJobInfo &) noexcept override;
|
|
void OnTableFileDeleted(const rocksdb::TableFileDeletionInfo &) noexcept override;
|
|
void OnTableFileCreated(const rocksdb::TableFileCreationInfo &) noexcept override;
|
|
void OnTableFileCreationStarted(const rocksdb::TableFileCreationBriefInfo &) noexcept override;
|
|
void OnMemTableSealed(const rocksdb::MemTableInfo &) noexcept override;
|
|
void OnColumnFamilyHandleDeletionStarted(rocksdb::ColumnFamilyHandle *) noexcept override;
|
|
void OnExternalFileIngested(rocksdb::DB *, const rocksdb::ExternalFileIngestionInfo &) noexcept override;
|
|
void OnBackgroundError(rocksdb::BackgroundErrorReason, rocksdb::Status *) noexcept override;
|
|
void OnStallConditionsChanged(const rocksdb::WriteStallInfo &) noexcept override;
|
|
|
|
events(database *const &d)
|
|
noexcept
|
|
:d{d}
|
|
{}
|
|
};
|
|
|
|
struct ircd::db::database::logger final
|
|
:std::enable_shared_from_this<struct database::logger>
|
|
,rocksdb::Logger
|
|
{
|
|
database *d;
|
|
|
|
void Logv(const rocksdb::InfoLogLevel level, const char *fmt, va_list ap) noexcept override;
|
|
void Logv(const char *fmt, va_list ap) noexcept override;
|
|
void LogHeader(const char *fmt, va_list ap) noexcept override;
|
|
|
|
rocksdb::Status Close() noexcept override;
|
|
|
|
logger(database *const &d);
|
|
~logger() noexcept override;
|
|
};
|
|
|
|
struct ircd::db::database::stats final
|
|
:rocksdb::Statistics
|
|
{
|
|
struct passthru;
|
|
|
|
database *d {nullptr};
|
|
std::array<uint64_t, rocksdb::TICKER_ENUM_MAX> ticker {{0}};
|
|
std::array<struct db::histogram, rocksdb::HISTOGRAM_ENUM_MAX> histogram;
|
|
|
|
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
|
|
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
|
|
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
|
|
bool HistEnabledForType(const uint32_t type) const noexcept override;
|
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
|
rocksdb::Status Reset() noexcept override;
|
|
|
|
stats(database *const &d = nullptr);
|
|
~stats() noexcept;
|
|
};
|
|
|
|
struct ircd::db::database::stats::passthru final
|
|
:rocksdb::Statistics
|
|
{
|
|
std::array<rocksdb::Statistics *, 2> pass {{nullptr}};
|
|
|
|
void recordTick(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
void measureTime(const uint32_t histogramType, const uint64_t time) noexcept override;
|
|
bool HistEnabledForType(const uint32_t type) const noexcept override;
|
|
uint64_t getTickerCount(const uint32_t tickerType) const noexcept override;
|
|
void setTickerCount(const uint32_t tickerType, const uint64_t count) noexcept override;
|
|
void histogramData(const uint32_t type, rocksdb::HistogramData *) const noexcept override;
|
|
uint64_t getAndResetTickerCount(const uint32_t tickerType) noexcept override;
|
|
rocksdb::Status Reset() noexcept override;
|
|
|
|
passthru(rocksdb::Statistics *const &a, rocksdb::Statistics *const &b);
|
|
~passthru() noexcept;
|
|
};
|
|
|
|
/// Callback surface for iterating/recovering the write-ahead-log journal.
|
|
struct ircd::db::database::wal_filter
|
|
:rocksdb::WalFilter
|
|
{
|
|
using WriteBatch = rocksdb::WriteBatch;
|
|
using log_number_map = std::map<uint32_t, uint64_t>;
|
|
using name_id_map = std::map<std::string, uint32_t>;
|
|
|
|
static conf::item<bool> debug;
|
|
|
|
database *d {nullptr};
|
|
log_number_map log_number;
|
|
name_id_map name_id;
|
|
|
|
const char *Name() const noexcept override;
|
|
WalProcessingOption LogRecord(const WriteBatch &, WriteBatch *const replace, bool *replaced) const noexcept override;
|
|
WalProcessingOption LogRecordFound(unsigned long long log_nr, const std::string &name, const WriteBatch &, WriteBatch *const replace, bool *replaced) noexcept override;
|
|
void ColumnFamilyLogNumberMap(const log_number_map &, const name_id_map &) noexcept override;
|
|
|
|
wal_filter(database *const &);
|
|
~wal_filter() noexcept;
|
|
};
|
|
|
|
#ifdef IRCD_DB_HAS_ALLOCATOR
|
|
/// Dynamic memory
|
|
struct ircd::db::database::allocator final
|
|
:rocksdb::MemoryAllocator
|
|
{
|
|
static const size_t ALIGN_DEFAULT;
|
|
|
|
database *d {nullptr};
|
|
database::column *c {nullptr};
|
|
size_t alignment {ALIGN_DEFAULT};
|
|
|
|
const char *Name() const noexcept override;
|
|
void *Allocate(size_t) noexcept override;
|
|
void Deallocate(void *) noexcept override;
|
|
size_t UsableSize(void *, size_t) const noexcept override;
|
|
|
|
allocator(database *const &,
|
|
database::column *const & = nullptr,
|
|
const size_t &alignment = ALIGN_DEFAULT);
|
|
|
|
~allocator() noexcept;
|
|
};
|
|
#endif
|