0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-28 15:53:46 +02:00

ircd:Ⓜ️;dbs: Add _room_space metadata column.

This commit is contained in:
Jason Volk 2019-05-11 17:48:35 -07:00
parent 65be94b140
commit e486d8907e
3 changed files with 341 additions and 4 deletions

View file

@ -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 &);

View 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;
}

View file

@ -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,