0
0
Fork 0
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:
Jason Volk 2018-02-27 22:42:25 -08:00
parent f76d82a553
commit 14d5bd4f99
3 changed files with 144 additions and 1 deletions

View file

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

View file

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

View file

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