mirror of
https://github.com/matrix-construct/construct
synced 2024-11-12 13:01:07 +01:00
ircd:Ⓜ️:dbs: Add _event_state column.
This commit is contained in:
parent
82cd48752d
commit
1d1f04126b
3 changed files with 292 additions and 0 deletions
|
@ -50,6 +50,7 @@ namespace ircd::m::dbs::appendix
|
|||
#include "event_horizon.h" // event_id | event_idx
|
||||
#include "event_sender.h" // sender | event_idx || hostpart | localpart, event_idx
|
||||
#include "event_type.h" // type | event_idx
|
||||
#include "event_state.h" // state_key, type, room_id, depth, event_idx
|
||||
#include "room_events.h" // room_id | depth, event_idx
|
||||
#include "room_state.h" // room_id | type, state_key => event_idx
|
||||
#include "room_state_space.h" // room_id | type, state_key, depth, event_idx
|
||||
|
@ -155,6 +156,9 @@ enum ircd::m::dbs::appendix::index
|
|||
/// Involves the event_type column (reverse index on the event type).
|
||||
EVENT_TYPE,
|
||||
|
||||
/// Involves the event_state column.
|
||||
EVENT_STATE,
|
||||
|
||||
/// Involves room_events table.
|
||||
ROOM_EVENTS,
|
||||
|
||||
|
|
45
include/ircd/m/dbs/event_state.h
Normal file
45
include/ircd/m/dbs/event_state.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
// 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_EVENT_STATE_H
|
||||
|
||||
namespace ircd::m::dbs
|
||||
{
|
||||
constexpr size_t EVENT_STATE_KEY_MAX_SIZE
|
||||
{
|
||||
0
|
||||
+ event::STATE_KEY_MAX_SIZE
|
||||
+ event::TYPE_MAX_SIZE
|
||||
+ id::MAX_SIZE
|
||||
+ 1
|
||||
+ 8
|
||||
+ 8
|
||||
};
|
||||
|
||||
using event_state_tuple = std::tuple<string_view, string_view, id::room, int64_t, event::idx>;
|
||||
|
||||
string_view event_state_key(const mutable_buffer &out, const event_state_tuple &);
|
||||
event_state_tuple event_state_key(const string_view &);
|
||||
|
||||
// state_key, type, room_id, depth, event_idx
|
||||
extern db::domain event_state;
|
||||
}
|
||||
|
||||
namespace ircd::m::dbs::desc
|
||||
{
|
||||
// events _event_state
|
||||
extern conf::item<size_t> events__event_state__block__size;
|
||||
extern conf::item<size_t> events__event_state__meta_block__size;
|
||||
extern conf::item<size_t> events__event_state__cache__size;
|
||||
extern conf::item<size_t> events__event_state__cache_comp__size;
|
||||
extern const db::comparator events__event_state__cmp;
|
||||
extern const db::descriptor events__event_state;
|
||||
}
|
243
matrix/dbs.cc
243
matrix/dbs.cc
|
@ -51,6 +51,11 @@ decltype(ircd::m::dbs::event_type)
|
|||
ircd::m::dbs::event_type
|
||||
{};
|
||||
|
||||
/// Linkage for a reference to the event_state column.
|
||||
decltype(ircd::m::dbs::event_state)
|
||||
ircd::m::dbs::event_state
|
||||
{};
|
||||
|
||||
/// Linkage for a reference to the room_head column
|
||||
decltype(ircd::m::dbs::room_head)
|
||||
ircd::m::dbs::room_head
|
||||
|
@ -184,6 +189,7 @@ ircd::m::dbs::init::init(const string_view &servername,
|
|||
event_horizon = db::domain{*events, desc::events__event_horizon.name};
|
||||
event_sender = db::domain{*events, desc::events__event_sender.name};
|
||||
event_type = db::domain{*events, desc::events__event_type.name};
|
||||
event_state = db::domain{*events, desc::events__event_state.name};
|
||||
room_head = db::domain{*events, desc::events__room_head.name};
|
||||
room_events = db::domain{*events, desc::events__room_events.name};
|
||||
room_joined = db::domain{*events, desc::events__room_joined.name};
|
||||
|
@ -243,6 +249,7 @@ namespace ircd::m::dbs
|
|||
static void _index_room_head(db::txn &, const event &, const write_opts &);
|
||||
static void _index_room_events(db::txn &, const event &, const write_opts &);
|
||||
static void _index_room(db::txn &, const event &, const write_opts &);
|
||||
static void _index_event_state(db::txn &, const event &, const write_opts &);
|
||||
static void _index_event_type(db::txn &, const event &, const write_opts &);
|
||||
static void _index_event_sender(db::txn &, const event &, const write_opts &);
|
||||
static void _index_event_horizon_resolve(db::txn &, const event &, const write_opts &); //query
|
||||
|
@ -351,6 +358,9 @@ ircd::m::dbs::_index_event(db::txn &txn,
|
|||
if(opts.appendix.test(appendix::EVENT_TYPE))
|
||||
_index_event_type(txn, event, opts);
|
||||
|
||||
if(opts.appendix.test(appendix::EVENT_STATE))
|
||||
_index_event_state(txn, event, opts);
|
||||
|
||||
if(opts.appendix.test(appendix::EVENT_REFS) && opts.event_refs.any())
|
||||
_index_event_refs(txn, event, opts);
|
||||
|
||||
|
@ -1186,6 +1196,35 @@ ircd::m::dbs::_index_event_type(db::txn &txn,
|
|||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::dbs::_index_event_state(db::txn &txn,
|
||||
const event &event,
|
||||
const write_opts &opts)
|
||||
{
|
||||
assert(opts.appendix.test(appendix::EVENT_STATE));
|
||||
assert(json::get<"type"_>(event));
|
||||
assert(opts.event_idx);
|
||||
|
||||
if(!defined(json::get<"state_key"_>(event)))
|
||||
return;
|
||||
|
||||
thread_local char buf[EVENT_STATE_KEY_MAX_SIZE];
|
||||
db::txn::append
|
||||
{
|
||||
txn, dbs::event_state,
|
||||
{
|
||||
opts.op, event_state_key(buf, event_state_tuple
|
||||
{
|
||||
at<"state_key"_>(event),
|
||||
at<"type"_>(event),
|
||||
at<"room_id"_>(event),
|
||||
at<"depth"_>(event),
|
||||
opts.event_idx,
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::dbs::_index_room(db::txn &txn,
|
||||
const event &event,
|
||||
|
@ -2505,6 +2544,206 @@ ircd::m::dbs::desc::events__event_type
|
|||
size_t(events__event_type__meta_block__size),
|
||||
};
|
||||
|
||||
//
|
||||
// event_state
|
||||
//
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__event_state__block__size)
|
||||
ircd::m::dbs::desc::events__event_state__block__size
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._event_state.block.size" },
|
||||
{ "default", 512L },
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__event_state__meta_block__size)
|
||||
ircd::m::dbs::desc::events__event_state__meta_block__size
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._event_state.meta_block.size" },
|
||||
{ "default", 2048L },
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__event_state__cache__size)
|
||||
ircd::m::dbs::desc::events__event_state__cache__size
|
||||
{
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._event_state.cache.size" },
|
||||
{ "default", long(16_MiB) },
|
||||
}, []
|
||||
{
|
||||
const size_t &value{events__event_state__cache__size};
|
||||
db::capacity(db::cache(event_state), value);
|
||||
}
|
||||
};
|
||||
|
||||
decltype(ircd::m::dbs::desc::events__event_state__cache_comp__size)
|
||||
ircd::m::dbs::desc::events__event_state__cache_comp__size
|
||||
{
|
||||
{
|
||||
{ "name", "ircd.m.dbs.events._event_state.cache_comp.size" },
|
||||
{ "default", long(0_MiB) },
|
||||
}, []
|
||||
{
|
||||
const size_t &value{events__event_state__cache_comp__size};
|
||||
db::capacity(db::cache_compressed(event_state), value);
|
||||
}
|
||||
};
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::event_state_key(const mutable_buffer &out_,
|
||||
const event_state_tuple &tuple)
|
||||
{
|
||||
assert(size(out_) >= EVENT_TYPE_KEY_MAX_SIZE);
|
||||
|
||||
const auto &[state_key, type, room_id, depth, event_idx]
|
||||
{
|
||||
tuple
|
||||
};
|
||||
|
||||
mutable_buffer out{out_};
|
||||
consume(out, copy(out, state_key));
|
||||
if(!type)
|
||||
return {data(out_), data(out)};
|
||||
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
consume(out, copy(out, type));
|
||||
if(!room_id)
|
||||
return {data(out_), data(out)};
|
||||
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
consume(out, copy(out, room_id));
|
||||
if(!room_id)
|
||||
return {data(out_), data(out)};
|
||||
|
||||
consume(out, copy(out, "\0"_sv));
|
||||
if(depth < 0)
|
||||
return {data(out_), data(out)};
|
||||
|
||||
consume(out, copy(out, byte_view<string_view>(depth)));
|
||||
if(!event_idx)
|
||||
return {data(out_), data(out)};
|
||||
|
||||
consume(out, copy(out, byte_view<string_view>(event_idx)));
|
||||
return {data(out_), data(out)};
|
||||
}
|
||||
|
||||
ircd::m::dbs::event_state_tuple
|
||||
ircd::m::dbs::event_state_key(const string_view &amalgam)
|
||||
{
|
||||
string_view parts[4];
|
||||
const auto num
|
||||
{
|
||||
tokens(amalgam, '\0', parts)
|
||||
};
|
||||
|
||||
assert(num <= 4);
|
||||
assert(num <= 3 || size(parts[3]) == 16);
|
||||
return event_state_tuple
|
||||
{
|
||||
parts[0],
|
||||
parts[1],
|
||||
num >= 3?
|
||||
m::room::id{parts[2]}:
|
||||
m::room::id{},
|
||||
num >= 4?
|
||||
int64_t(byte_view<int64_t>(parts[3].substr(0, 8))):
|
||||
-1L,
|
||||
num >= 4?
|
||||
event::idx(byte_view<uint64_t>(parts[3].substr(8))):
|
||||
0UL,
|
||||
};
|
||||
}
|
||||
|
||||
const ircd::db::comparator
|
||||
ircd::m::dbs::desc::events__event_state__cmp
|
||||
{
|
||||
"_event_state",
|
||||
|
||||
// less
|
||||
[](const string_view &a, const string_view &b)
|
||||
{
|
||||
const event_state_tuple key[2]
|
||||
{
|
||||
event_state_key(a),
|
||||
event_state_key(b),
|
||||
};
|
||||
|
||||
if(std::get<0>(key[0]) != std::get<0>(key[1]))
|
||||
return std::get<0>(key[0]) < std::get<0>(key[1]);
|
||||
|
||||
if(std::get<1>(key[0]) != std::get<1>(key[1]))
|
||||
return std::get<1>(key[0]) < std::get<1>(key[1]);
|
||||
|
||||
if(std::get<id::room>(key[0]) != std::get<id::room>(key[1]))
|
||||
return std::get<id::room>(key[0]) < std::get<id::room>(key[1]);
|
||||
|
||||
if(std::get<int64_t>(key[0]) != std::get<int64_t>(key[1]))
|
||||
return std::get<int64_t>(key[0]) > std::get<int64_t>(key[1]);
|
||||
|
||||
if(std::get<event::idx>(key[0]) != std::get<event::idx>(key[1]))
|
||||
return std::get<event::idx>(key[0]) > std::get<event::idx>(key[1]);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// equal
|
||||
[](const string_view &a, const string_view &b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
|
||||
const ircd::db::descriptor
|
||||
ircd::m::dbs::desc::events__event_state
|
||||
{
|
||||
// name
|
||||
"_event_state",
|
||||
|
||||
// explanation
|
||||
R"(Index of states of events.
|
||||
|
||||
state_key, type, room_id, depth, event_idx => --
|
||||
|
||||
The state transitions of events are indexed by this column,
|
||||
based on the state_key property.
|
||||
|
||||
)",
|
||||
|
||||
// typing (key, value)
|
||||
{
|
||||
typeid(string_view), typeid(string_view)
|
||||
},
|
||||
|
||||
// options
|
||||
{},
|
||||
|
||||
// comparator
|
||||
events__event_state__cmp,
|
||||
|
||||
// prefix transform
|
||||
{},
|
||||
|
||||
// drop column
|
||||
false,
|
||||
|
||||
// cache size
|
||||
bool(events_cache_enable)? -1 : 0, //uses conf item
|
||||
|
||||
// cache size for compressed assets
|
||||
bool(events_cache_comp_enable)? -1 : 0,
|
||||
|
||||
// bloom filter bits
|
||||
0,
|
||||
|
||||
// expect queries hit
|
||||
false,
|
||||
|
||||
// block size
|
||||
size_t(events__event_state__block__size),
|
||||
|
||||
// meta_block size
|
||||
size_t(events__event_state__meta_block__size),
|
||||
};
|
||||
|
||||
//
|
||||
// room_head
|
||||
//
|
||||
|
@ -4897,6 +5136,10 @@ ircd::m::dbs::desc::events
|
|||
// Mapping of type strings to event_idx's of that type.
|
||||
events__event_type,
|
||||
|
||||
// state_key, type, room_id, depth, event_idx
|
||||
// Mapping of event states, indexed for application features.
|
||||
events__event_state,
|
||||
|
||||
// (room_id, (depth, event_idx))
|
||||
// Sequence of all events for a room, ever.
|
||||
events__room_events,
|
||||
|
|
Loading…
Reference in a new issue