0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-16 15:00:51 +01:00

ircd::db: Fix issues with txn interface.

This commit is contained in:
Jason Volk 2018-04-16 15:16:51 -07:00
parent cae6964fa5
commit e009d6763e
3 changed files with 81 additions and 86 deletions

View file

@ -15,8 +15,7 @@ namespace ircd::db
{ {
struct txn; struct txn;
bool test(const txn &, const std::function<bool (const delta &)> &); bool for_each(const txn &, const std::function<bool (const delta &)> &);
bool until(const txn &, const std::function<bool (const delta &)> &);
void for_each(const txn &, const std::function<void (const delta &)> &); void for_each(const txn &, const std::function<void (const delta &)> &);
std::string debug(const txn &); std::string debug(const txn &);
@ -38,17 +37,21 @@ struct ircd::db::txn
struct append; struct append;
struct handler; struct handler;
using delta_closure = std::function<void (const delta &)>;
using delta_closure_bool = std::function<bool (const delta &)>;
using value_closure = std::function<void (const string_view &)>;
explicit operator const rocksdb::WriteBatch &() const; explicit operator const rocksdb::WriteBatch &() const;
explicit operator const database &() const; explicit operator const database &() const;
explicit operator rocksdb::WriteBatch &(); explicit operator rocksdb::WriteBatch &();
explicit operator database &(); explicit operator database &();
string_view get(const op &, const string_view &col, const string_view &key) const; bool get(const op &, const string_view &col, const string_view &key, const value_closure &) const;
string_view at(const op &, const string_view &col, const string_view &key) const; void at(const op &, const string_view &col, const string_view &key, const value_closure &) const;
bool has(const op &, const string_view &col, const string_view &key) const; bool has(const op &, const string_view &col, const string_view &key) const;
delta get(const op &, const string_view &col) const; bool get(const op &, const string_view &col, const delta_closure &) const;
delta at(const op &, const string_view &col) const; void at(const op &, const string_view &col, const delta_closure &) const;
bool has(const op &, const string_view &col) const; bool has(const op &, const string_view &col) const;
bool has(const op &) const; bool has(const op &) const;

View file

@ -2581,12 +2581,9 @@ ircd::db::for_each(const txn &t,
wb.Iterate(&h); wb.Iterate(&h);
} }
/// Iterate the txn using the "until protocol"
/// reminder: the closure remains-true-until-the-end; false to break;
/// returns true if the end reached; false if broken early
bool bool
ircd::db::until(const txn &t, ircd::db::for_each(const txn &t,
const std::function<bool (const delta &)> &closure) const std::function<bool (const delta &)> &closure)
{ {
const database &d(t); const database &d(t);
const rocksdb::WriteBatch &wb{t}; const rocksdb::WriteBatch &wb{t};
@ -2595,20 +2592,6 @@ ircd::db::until(const txn &t,
return h._continue; return h._continue;
} }
/// Iterate the txn using the "test protocol"
/// reminder: the closure returns true to break, false to continue;
/// returns true if broken early, false if the end reached.
bool
ircd::db::test(const txn &t,
const std::function<bool (const delta &)> &closure)
{
return !until(t, [&closure]
(const delta &delta)
{
return !closure(delta);
});
}
/// ///
/// handler (db/database/txn.h) /// handler (db/database/txn.h)
/// ///
@ -2821,12 +2804,46 @@ ircd::db::txn::has(const op &op,
const string_view &col) const string_view &col)
const const
{ {
return test(*this, [&op, &col] return !for_each(*this, delta_closure_bool{[&op, &col]
(const auto &delta) (const auto &delta)
{ {
return std::get<delta.OP>(delta) == op && return std::get<delta.OP>(delta) == op &&
std::get<delta.COL>(delta) == col; std::get<delta.COL>(delta) == col;
}); }});
}
void
ircd::db::txn::at(const op &op,
const string_view &col,
const delta_closure &closure)
const
{
if(!get(op, col, closure))
throw not_found
{
"db::txn::at(%s, %s): no matching delta in transaction",
reflect(op),
col
};
}
bool
ircd::db::txn::get(const op &op,
const string_view &col,
const delta_closure &closure)
const
{
return !for_each(*this, delta_closure_bool{[&op, &col, &closure]
(const delta &delta)
{
if(std::get<delta.OP>(delta) == op &&
std::get<delta.COL>(delta) == col)
{
closure(delta);
return false;
}
else return true;
}});
} }
bool bool
@ -2835,85 +2852,51 @@ ircd::db::txn::has(const op &op,
const string_view &key) const string_view &key)
const const
{ {
return test(*this, [&op, &col, &key] return !for_each(*this, delta_closure_bool{[&op, &col, &key]
(const auto &delta) (const auto &delta)
{ {
return std::get<delta.OP>(delta) == op && return std::get<delta.OP>(delta) == op &&
std::get<delta.COL>(delta) == col && std::get<delta.COL>(delta) == col &&
std::get<delta.KEY>(delta) == key; std::get<delta.KEY>(delta) == key;
}); }});
} }
ircd::db::delta void
ircd::db::txn::at(const op &op,
const string_view &col)
const
{
const auto ret(get(op, col));
if(unlikely(!std::get<ret.KEY>(ret)))
throw not_found("db::txn::at(%s, %s): no matching delta in transaction",
reflect(op),
col);
return ret;
}
ircd::db::delta
ircd::db::txn::get(const op &op,
const string_view &col)
const
{
delta ret;
test(*this, [&ret, &op, &col]
(const delta &delta)
{
if(std::get<delta.OP>(delta) == op &&
std::get<delta.COL>(delta) == col)
{
ret = delta;
return true;
}
else return false;
});
return ret;
}
ircd::string_view
ircd::db::txn::at(const op &op, ircd::db::txn::at(const op &op,
const string_view &col, const string_view &col,
const string_view &key) const string_view &key,
const value_closure &closure)
const const
{ {
const auto ret(get(op, col, key)); if(!get(op, col, key, closure))
if(unlikely(!ret)) throw not_found
throw not_found("db::txn::at(%s, %s, %s): no matching delta in transaction", {
reflect(op), "db::txn::at(%s, %s, %s): no matching delta in transaction",
col, reflect(op),
key); col,
return ret; key
};
} }
ircd::string_view bool
ircd::db::txn::get(const op &op, ircd::db::txn::get(const op &op,
const string_view &col, const string_view &col,
const string_view &key) const string_view &key,
const value_closure &closure)
const const
{ {
string_view ret; return !for_each(*this, delta_closure_bool{[&op, &col, &key, &closure]
test(*this, [&ret, &op, &col, &key]
(const delta &delta) (const delta &delta)
{ {
if(std::get<delta.OP>(delta) == op && if(std::get<delta.OP>(delta) == op &&
std::get<delta.COL>(delta) == col && std::get<delta.COL>(delta) == col &&
std::get<delta.KEY>(delta) == key) std::get<delta.KEY>(delta) == key)
{ {
ret = std::get<delta.VAL>(delta); closure(std::get<delta.VAL>(delta));
return true; return false;
} }
else return false; else return true;
}); }});
return ret;
} }
ircd::db::txn::operator ircd::db::txn::operator

View file

@ -839,10 +839,19 @@ try
for_each(database, seqnum, db::seq_closure_bool{[&out, &limit] for_each(database, seqnum, db::seq_closure_bool{[&out, &limit]
(db::txn &txn, const uint64_t &seqnum) -> bool (db::txn &txn, const uint64_t &seqnum) -> bool
{ {
if(txn.has(db::op::SET, "event_id")) m::event::id::buf event_id;
out << std::setw(12) << std::right << seqnum << " : " txn.get(db::op::SET, "event_id", [&event_id]
<< std::get<db::delta::KEY>(txn.get(db::op::SET, "event_id")) (const db::delta &delta)
<< std::endl; {
event_id = std::get<delta.KEY>(delta);
});
if(event_id)
return true;
out << std::setw(12) << std::right << seqnum << " : "
<< string_view{event_id}
<< std::endl;
return --limit; return --limit;
}}); }});