mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd:Ⓜ️:state: Checkpoint removal entry point.
This commit is contained in:
parent
f76d82a553
commit
14d5bd4f99
3 changed files with 144 additions and 1 deletions
|
@ -53,6 +53,10 @@ namespace ircd::m::state
|
|||
id set_node(db::txn &txn, const mutable_buffer &id, const json::object &node);
|
||||
void get_node(const string_view &id, const node_closure &);
|
||||
|
||||
id remove(db::txn &, const mutable_buffer &rootout, const id &rootin, const json::array &key);
|
||||
id remove(db::txn &, const mutable_buffer &rootout, const id &rootin, const string_view &type, const string_view &state_key);
|
||||
id remove(db::txn &, const mutable_buffer &rootout, const id &rootin, const event &);
|
||||
|
||||
id insert(db::txn &, const mutable_buffer &rootout, const id &rootin, const json::array &key, const m::id::event &);
|
||||
id insert(db::txn &, const mutable_buffer &rootout, const id &rootin, const string_view &type, const string_view &state_key, const m::id::event &);
|
||||
id insert(db::txn &, const mutable_buffer &rootout, const id &rootin, const event &);
|
||||
|
|
|
@ -79,6 +79,7 @@ namespace ircd::m::dbs
|
|||
{
|
||||
static void _index__room_events(db::txn &, const string_view &state_root, const event &);
|
||||
static string_view _index_state(db::txn &, const mutable_buffer &root_out, const string_view &state_root, const event &);
|
||||
static string_view _index_redact(db::txn &, const mutable_buffer &root_out, const string_view &state_root, const event &);
|
||||
static string_view _index_ephem(db::txn &, const string_view &state_root, const event &);
|
||||
}
|
||||
|
||||
|
@ -96,6 +97,9 @@ ircd::m::dbs::write(db::txn &txn,
|
|||
if(defined(json::get<"state_key"_>(event)))
|
||||
return _index_state(txn, root_out, root_in, event);
|
||||
|
||||
if(at<"type"_>(event) == "m.room.redaction")
|
||||
return _index_redact(txn, root_out, root_in, event);
|
||||
|
||||
return _index_ephem(txn, root_in, event);
|
||||
}
|
||||
|
||||
|
@ -108,6 +112,55 @@ ircd::m::dbs::_index_ephem(db::txn &txn,
|
|||
return state_root_in;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::_index_redact(db::txn &txn,
|
||||
const mutable_buffer &state_root_out,
|
||||
const string_view &state_root_in,
|
||||
const event &event)
|
||||
try
|
||||
{
|
||||
const auto &target_id
|
||||
{
|
||||
at<"redacts"_>(event)
|
||||
};
|
||||
|
||||
event::fetch target
|
||||
{
|
||||
target_id, std::nothrow
|
||||
};
|
||||
|
||||
if(unlikely(!target.valid(target_id)))
|
||||
log::error
|
||||
{
|
||||
"Redaction from '%s' missing redaction target '%s'",
|
||||
at<"event_id"_>(event),
|
||||
target_id
|
||||
};
|
||||
|
||||
if(!defined(json::get<"state_key"_>(target)))
|
||||
{
|
||||
_index__room_events(txn, state_root_in, event);
|
||||
return state_root_in;
|
||||
}
|
||||
|
||||
const string_view new_root
|
||||
{
|
||||
state_root_in //state::remove(txn, state_root_out, state_root_in, target)
|
||||
};
|
||||
|
||||
_index__room_events(txn, new_root, event);
|
||||
return new_root;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::error
|
||||
{
|
||||
"Failed to update state from redaction: %s", e.what()
|
||||
};
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::dbs::_index_state(db::txn &txn,
|
||||
const mutable_buffer &state_root_out,
|
||||
|
|
|
@ -326,16 +326,20 @@ ircd::m::state::_dfs_recurse(const search_closure &closure,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Internal insertion operations
|
||||
// Internal operations
|
||||
namespace ircd::m::state
|
||||
{
|
||||
static mutable_buffer _getbuffer(const uint8_t &height);
|
||||
|
||||
static string_view _remove(int8_t &height, db::txn &, const json::array &key, const node &node, const mutable_buffer &idbuf, node::rep &push);
|
||||
|
||||
static string_view _insert_overwrite(db::txn &, const json::array &key, const string_view &val, const mutable_buffer &idbuf, node::rep &, const size_t &pos);
|
||||
static string_view _insert_leaf_nonfull(db::txn &, const json::array &key, const string_view &val, const mutable_buffer &idbuf, node::rep &, const size_t &pos);
|
||||
static json::object _insert_leaf_full(const int8_t &height, db::txn &, const json::array &key, const string_view &val, node::rep &, const size_t &pos, node::rep &push);
|
||||
static string_view _insert_branch_nonfull(db::txn &, const mutable_buffer &idbuf, node::rep &, const size_t &pos, node::rep &pushed);
|
||||
static json::object _insert_branch_full(const int8_t &height, db::txn &, node::rep &, const size_t &pos, node::rep &push, const node::rep &pushed);
|
||||
static string_view _insert(int8_t &height, db::txn &, const json::array &key, const string_view &val, const node &node, const mutable_buffer &idbuf, node::rep &push);
|
||||
|
||||
static string_view _create(db::txn &, const mutable_buffer &root, const string_view &type, const string_view &state_key, const string_view &val);
|
||||
}
|
||||
|
||||
|
@ -673,6 +677,88 @@ ircd::m::state::_insert_overwrite(db::txn &txn,
|
|||
return rep.write(txn, idbuf);
|
||||
}
|
||||
|
||||
ircd::m::state::id
|
||||
ircd::m::state::remove(db::txn &txn,
|
||||
const mutable_buffer &rootout,
|
||||
const string_view &rootin,
|
||||
const event &event)
|
||||
{
|
||||
const auto &type{at<"type"_>(event)};
|
||||
const auto &state_key{at<"state_key"_>(event)};
|
||||
|
||||
assert(!empty(rootin));
|
||||
return remove(txn, rootout, rootin, type, state_key);
|
||||
}
|
||||
|
||||
/// State update for room_id inserting (type,state_key) = event_id into the
|
||||
/// tree. Leaves the root node ID in the root buffer; returns view.
|
||||
ircd::m::state::id
|
||||
ircd::m::state::remove(db::txn &txn,
|
||||
const mutable_buffer &rootout,
|
||||
const string_view &rootin,
|
||||
const string_view &type,
|
||||
const string_view &state_key)
|
||||
{
|
||||
// The removal process reads from the DB and will yield this ircd::ctx
|
||||
// so the key buffer must stay on this stack.
|
||||
char key[KEY_MAX_SZ];
|
||||
return remove(txn, rootout, rootin, make_key(key, type, state_key));
|
||||
}
|
||||
|
||||
ircd::m::state::id
|
||||
ircd::m::state::remove(db::txn &txn,
|
||||
const mutable_buffer &rootout,
|
||||
const string_view &rootin,
|
||||
const json::array &key)
|
||||
{
|
||||
node::rep push;
|
||||
int8_t height{0};
|
||||
string_view root{rootin};
|
||||
get_node(root, [&](const node &node)
|
||||
{
|
||||
root = _remove(height, txn, key, node, rootout, push);
|
||||
});
|
||||
|
||||
if(push.kn)
|
||||
root = push.write(txn, rootout);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
ircd::m::state::id
|
||||
ircd::m::state::_remove(int8_t &height,
|
||||
db::txn &txn,
|
||||
const json::array &key,
|
||||
const node &node,
|
||||
const mutable_buffer &idbuf,
|
||||
node::rep &push)
|
||||
{
|
||||
const unwind down{[&height]{ --height; }};
|
||||
if(unlikely(++height >= MAX_HEIGHT))
|
||||
throw assertive{"recursion limit exceeded"};
|
||||
|
||||
node::rep rep{node};
|
||||
const auto pos{node.find(key)};
|
||||
|
||||
if(keycmp(node.key(pos), key) == 0)
|
||||
{
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// These collect data from the next level.
|
||||
node::rep pushed;
|
||||
string_view child;
|
||||
|
||||
// Recurse
|
||||
get_node(node.child(pos), [&](const auto &node)
|
||||
{
|
||||
|
||||
child = _remove(height, txn, key, node, idbuf, pushed);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// This function returns a thread_local buffer intended for writing temporary
|
||||
/// nodes which may be "pushed" down the tree during the btree insertion
|
||||
/// process. This is an alternative to allocating such space in each stack
|
||||
|
|
Loading…
Reference in a new issue