mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 23:44:01 +01:00
ircd:Ⓜ️;dbs: Add _room_space metadata column.
This commit is contained in:
parent
65be94b140
commit
e486d8907e
3 changed files with 341 additions and 4 deletions
|
@ -54,6 +54,7 @@ namespace ircd::m::dbs::appendix
|
|||
#include "room_events.h" // room_id | depth, event_idx => node_id
|
||||
#include "room_joined.h" // room_id | origin, member => event_idx
|
||||
#include "room_state.h" // room_id | type, state_key => event_idx
|
||||
#include "room_space.h" // room_id | type, state_key, depth, event_idx
|
||||
#include "state_node.h" // node_id => (m::state::node JSON)
|
||||
|
||||
/// Options that affect the dbs::write() of an event to the transaction.
|
||||
|
@ -205,6 +206,9 @@ enum ircd::m::dbs::appendix::index
|
|||
|
||||
/// Involves room_state (present state) table.
|
||||
ROOM_STATE,
|
||||
|
||||
/// Involves room_space (all states) table.
|
||||
ROOM_SPACE,
|
||||
};
|
||||
|
||||
struct ircd::m::dbs::init
|
||||
|
@ -216,6 +220,7 @@ struct ircd::m::dbs::init
|
|||
// Internal interface; not for public. (TODO: renamespace)
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
void _index__room_space(db::txn &, const event &, const write_opts &);
|
||||
void _index__room_state(db::txn &, const event &, const write_opts &);
|
||||
void _index__room_events(db::txn &, const event &, const write_opts &, const string_view &);
|
||||
void _index__room_joined(db::txn &, const event &, const write_opts &);
|
||||
|
|
40
include/ircd/m/dbs/room_space.h
Normal file
40
include/ircd/m/dbs/room_space.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
// 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.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_M_DBS_ROOM_SPACE_H
|
||||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
constexpr size_t ROOM_SPACE_KEY_MAX_SIZE
|
||||
{
|
||||
id::MAX_SIZE + event::TYPE_MAX_SIZE + event::STATE_KEY_MAX_SIZE + sizeof(int64_t)
|
||||
};
|
||||
|
||||
string_view room_space_key(const mutable_buffer &out, const id::room &, const string_view &type, const string_view &state_key, const int64_t &depth, const event::idx & = 0);
|
||||
string_view room_space_key(const mutable_buffer &out, const id::room &, const string_view &type, const string_view &state_key);
|
||||
string_view room_space_key(const mutable_buffer &out, const id::room &, const string_view &type);
|
||||
std::tuple<string_view, string_view, int64_t, event::idx> room_space_key(const string_view &amalgam);
|
||||
|
||||
// room_id | type, state_key, depth, event_idx => --
|
||||
extern db::index room_space;
|
||||
}
|
||||
|
||||
namespace ircd::m::dbs::desc
|
||||
{
|
||||
extern conf::item<size_t> events__room_space__block__size;
|
||||
extern conf::item<size_t> events__room_space__meta_block__size;
|
||||
extern conf::item<size_t> events__room_space__cache__size;
|
||||
extern conf::item<size_t> events__room_space__cache_comp__size;
|
||||
extern conf::item<size_t> events__room_space__bloom__bits;
|
||||
extern const db::prefix_transform events__room_space__pfx;
|
||||
extern const db::comparator events__room_space__cmp;
|
||||
extern const db::descriptor events__room_space;
|
||||
}
|
300
ircd/m_dbs.cc
300
ircd/m_dbs.cc
|
@ -71,6 +71,11 @@ decltype(ircd::m::dbs::room_state)
|
|||
ircd::m::dbs::room_state
|
||||
{};
|
||||
|
||||
/// Linkage for a reference to the room_space column
|
||||
decltype(ircd::m::dbs::room_space)
|
||||
ircd::m::dbs::room_space
|
||||
{};
|
||||
|
||||
/// Linkage for a reference to the state_node column.
|
||||
decltype(ircd::m::dbs::state_node)
|
||||
ircd::m::dbs::state_node
|
||||
|
@ -162,6 +167,7 @@ ircd::m::dbs::init::init(std::string dbopts)
|
|||
room_events = db::index{*events, desc::events__room_events.name};
|
||||
room_joined = db::index{*events, desc::events__room_joined.name};
|
||||
room_state = db::index{*events, desc::events__room_state.name};
|
||||
room_space = db::index{*events, desc::events__room_space.name};
|
||||
state_node = db::column{*events, desc::events__state_node.name};
|
||||
}
|
||||
|
||||
|
@ -1047,6 +1053,9 @@ try
|
|||
if(opts.appendix.test(appendix::ROOM_STATE))
|
||||
_index__room_state(txn, event, opts);
|
||||
|
||||
if(opts.appendix.test(appendix::ROOM_SPACE))
|
||||
_index__room_space(txn, event, opts);
|
||||
|
||||
return new_root;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
|
@ -1289,8 +1298,6 @@ ircd::m::dbs::_index__room_joined(db::txn &txn,
|
|||
};
|
||||
}
|
||||
|
||||
/// Adds the entry for the room_joined column into the txn.
|
||||
/// This only is affected if opts.present=true
|
||||
void
|
||||
ircd::m::dbs::_index__room_state(db::txn &txn,
|
||||
const event &event,
|
||||
|
@ -1324,6 +1331,29 @@ ircd::m::dbs::_index__room_state(db::txn &txn,
|
|||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::dbs::_index__room_space(db::txn &txn,
|
||||
const event &event,
|
||||
const write_opts &opts)
|
||||
{
|
||||
assert(opts.appendix.test(appendix::ROOM_SPACE));
|
||||
|
||||
const ctx::critical_assertion ca;
|
||||
thread_local char buf[ROOM_SPACE_KEY_MAX_SIZE];
|
||||
const string_view &key
|
||||
{
|
||||
room_space_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event), at<"depth"_>(event), opts.event_idx)
|
||||
};
|
||||
|
||||
db::txn::append
|
||||
{
|
||||
txn, room_space,
|
||||
{
|
||||
opts.op, key, string_view{}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ircd::m::event::idx
|
||||
ircd::m::dbs::find_event_idx(const event::id &event_id,
|
||||
const write_opts &wopts)
|
||||
|
@ -2933,7 +2963,7 @@ ircd::m::dbs::desc::events__room_joined
|
|||
};
|
||||
|
||||
//
|
||||
// state sequential
|
||||
// room present state sequential
|
||||
//
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_state__block__size)
|
||||
|
@ -3109,6 +3139,264 @@ ircd::m::dbs::desc::events__room_state
|
|||
size_t(events__room_state__meta_block__size),
|
||||
};
|
||||
|
||||
//
|
||||
// room all states sequential
|
||||
//
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_space__block__size)
|
||||
ircd::m::dbs::desc::events__room_space__block__size
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._room_space.block.size" },
|
||||
{ "default", 512L },
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_space__meta_block__size)
|
||||
ircd::m::dbs::desc::events__room_space__meta_block__size
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._room_space.meta_block.size" },
|
||||
{ "default", 8192L },
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_space__cache__size)
|
||||
ircd::m::dbs::desc::events__room_space__cache__size
|
||||
{
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._room_space.cache.size" },
|
||||
{ "default", long(16_MiB) },
|
||||
}, []
|
||||
{
|
||||
const size_t &value{events__room_space__cache__size};
|
||||
db::capacity(db::cache(room_space), value);
|
||||
}
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_space__cache_comp__size)
|
||||
ircd::m::dbs::desc::events__room_space__cache_comp__size
|
||||
{
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._room_space.cache_comp.size" },
|
||||
{ "default", long(8_MiB) },
|
||||
}, []
|
||||
{
|
||||
const size_t &value{events__room_space__cache_comp__size};
|
||||
db::capacity(db::cache_compressed(room_space), value);
|
||||
}
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__room_space__bloom__bits)
|
||||
ircd::m::dbs::desc::events__room_space__bloom__bits
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._room_space.bloom.bits" },
|
||||
{ "default", 10L },
|
||||
};
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::room_space_key(const mutable_buffer &out_,
|
||||
const id::room &room_id,
|
||||
const string_view &type)
|
||||
{
|
||||
return room_space_key(out_, room_id, type, string_view{}, 0L);
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::room_space_key(const mutable_buffer &out_,
|
||||
const id::room &room_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key)
|
||||
{
|
||||
return room_space_key(out_, room_id, type, string_view{}, 0L);
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::room_space_key(const mutable_buffer &out_,
|
||||
const id::room &room_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key,
|
||||
const int64_t &depth,
|
||||
const event::idx &event_idx)
|
||||
{
|
||||
mutable_buffer out{out_};
|
||||
consume(out, copy(out, room_id));
|
||||
|
||||
if(!defined(type))
|
||||
return { data(out_), data(out) };
|
||||
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
consume(out, copy(out, type));
|
||||
|
||||
if(!defined(state_key))
|
||||
return { data(out_), data(out) };
|
||||
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
consume(out, copy(out, state_key));
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
consume(out, copy(out, byte_view<string_view>(depth)));
|
||||
consume(out, copy(out, byte_view<string_view>(event_idx)));
|
||||
return { data(out_), data(out) };
|
||||
}
|
||||
|
||||
std::tuple<ircd::string_view, ircd::string_view, int64_t, ircd::m::event::idx>
|
||||
ircd::m::dbs::room_space_key(const string_view &amalgam)
|
||||
{
|
||||
const auto &key
|
||||
{
|
||||
lstrip(amalgam, "\0"_sv)
|
||||
};
|
||||
|
||||
const auto &type_split
|
||||
{
|
||||
split(key, "\0"_sv)
|
||||
};
|
||||
|
||||
const auto &state_key_split
|
||||
{
|
||||
split(type_split.second, "\0"_sv)
|
||||
};
|
||||
|
||||
const auto &type
|
||||
{
|
||||
type_split.first
|
||||
};
|
||||
|
||||
const auto &state_key
|
||||
{
|
||||
state_key_split.first
|
||||
};
|
||||
|
||||
const int64_t &depth
|
||||
{
|
||||
size(state_key_split.second) >= 8?
|
||||
int64_t(byte_view<int64_t>(state_key_split.second.substr(0, 8))):
|
||||
0L
|
||||
};
|
||||
|
||||
const event::idx &event_idx
|
||||
{
|
||||
size(state_key_split.second) >= 16?
|
||||
event::idx(byte_view<event::idx>(state_key_split.second.substr(8, 8))):
|
||||
0L
|
||||
};
|
||||
|
||||
return
|
||||
{
|
||||
type, state_key, depth, event_idx
|
||||
};
|
||||
}
|
||||
|
||||
const ircd::db::prefix_transform
|
||||
ircd::m::dbs::desc::events__room_space__pfx
|
||||
{
|
||||
"_room_space",
|
||||
[](const string_view &key)
|
||||
{
|
||||
return has(key, "\0"_sv);
|
||||
},
|
||||
|
||||
[](const string_view &key)
|
||||
{
|
||||
return split(key, "\0"_sv).first;
|
||||
}
|
||||
};
|
||||
|
||||
const ircd::db::comparator
|
||||
ircd::m::dbs::desc::events__room_space__cmp
|
||||
{
|
||||
"_room_space",
|
||||
|
||||
// less
|
||||
[](const string_view &a, const string_view &b)
|
||||
{
|
||||
static const auto &pt
|
||||
{
|
||||
events__room_space__pfx
|
||||
};
|
||||
|
||||
const string_view pre[2]
|
||||
{
|
||||
pt.get(a),
|
||||
pt.get(b),
|
||||
};
|
||||
|
||||
if(size(pre[0]) != size(pre[1]))
|
||||
return size(pre[0]) < size(pre[1]);
|
||||
|
||||
if(pre[0] != pre[1])
|
||||
return pre[0] < pre[1];
|
||||
|
||||
const string_view post[2]
|
||||
{
|
||||
a.substr(size(pre[0])),
|
||||
b.substr(size(pre[1])),
|
||||
};
|
||||
|
||||
// These conditions are matched on some queries when the user only
|
||||
// supplies a room_id.
|
||||
if(empty(post[0]))
|
||||
return true;
|
||||
|
||||
if(empty(post[1]))
|
||||
return false;
|
||||
|
||||
// Perform standard comparison over the typed tuple.
|
||||
const auto _a(room_space_key(post[0]));
|
||||
const auto _b(room_space_key(post[1]));
|
||||
return _a < _b;
|
||||
},
|
||||
|
||||
// equal
|
||||
[](const string_view &a, const string_view &b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
|
||||
const ircd::db::descriptor
|
||||
ircd::m::dbs::desc::events__room_space
|
||||
{
|
||||
// name
|
||||
"_room_space",
|
||||
|
||||
// explanation
|
||||
R"(All states of the room.
|
||||
|
||||
)",
|
||||
|
||||
// typing (key, value)
|
||||
{
|
||||
typeid(string_view), typeid(uint64_t)
|
||||
},
|
||||
|
||||
// options
|
||||
{},
|
||||
|
||||
// comparator
|
||||
{},
|
||||
|
||||
// prefix transform
|
||||
events__room_space__pfx,
|
||||
|
||||
// drop column
|
||||
false,
|
||||
|
||||
// cache size
|
||||
bool(events_cache_enable)? -1 : 0,
|
||||
|
||||
// cache size for compressed assets
|
||||
bool(events_cache_comp_enable)? -1 : 0,
|
||||
|
||||
// bloom filter bits
|
||||
size_t(events__room_space__bloom__bits),
|
||||
|
||||
// expect queries hit
|
||||
false,
|
||||
|
||||
// block size
|
||||
size_t(events__room_space__block__size),
|
||||
|
||||
// meta_block size
|
||||
size_t(events__room_space__meta_block__size),
|
||||
};
|
||||
|
||||
//
|
||||
// state node
|
||||
//
|
||||
|
@ -4559,10 +4847,14 @@ ircd::m::dbs::desc::events
|
|||
// Sequence of all PRESENTLY JOINED joined for a room.
|
||||
events__room_joined,
|
||||
|
||||
// (room_id, (type, state_key)) => (event_id)
|
||||
// (room_id, (type, state_key)) => (event_idx)
|
||||
// Sequence of the PRESENT STATE of the room.
|
||||
events__room_state,
|
||||
|
||||
// (room_id, (type, state_key, depth, event_idx))
|
||||
// Sequence of all states of the room.
|
||||
events__room_space,
|
||||
|
||||
// (state tree node id) => (state tree node)
|
||||
// Mapping of state tree node id to node data.
|
||||
events__state_node,
|
||||
|
|
Loading…
Reference in a new issue