mirror of
https://github.com/matrix-construct/construct
synced 2024-11-25 16:22:35 +01:00
ircd::db: row cleanup / fixes.
This commit is contained in:
parent
47cd7790ed
commit
5261f9dd25
4 changed files with 32 additions and 180 deletions
|
@ -98,7 +98,7 @@ struct ircd::db::column
|
|||
using iterator = const_iterator;
|
||||
|
||||
protected:
|
||||
database::column *c;
|
||||
database::column *c {nullptr};
|
||||
|
||||
public:
|
||||
explicit operator const database &() const;
|
||||
|
|
|
@ -40,7 +40,7 @@ struct ircd::db::cursor
|
|||
using index_iterator = ircd::db::index::const_iterator;
|
||||
|
||||
struct index index;
|
||||
const where_type *where;
|
||||
const where_type *where{nullptr};
|
||||
|
||||
const_iterator end();
|
||||
const_iterator begin();
|
||||
|
@ -204,7 +204,7 @@ const
|
|||
if(stale)
|
||||
{
|
||||
for(const auto &cell : row)
|
||||
if(cell.valid() && cell.key() == idx->first)
|
||||
if(cell.valid(idx->first))
|
||||
json::set(v, cell.col(), cell.val());
|
||||
else
|
||||
json::set(v, cell.col(), string_view{});
|
||||
|
|
|
@ -31,28 +31,26 @@ namespace ircd::db
|
|||
void del(row &, const sopts & = {});
|
||||
}
|
||||
|
||||
// A `row` is a collection of cells from different columns which all share the same
|
||||
// key. This is an interface for dealing with those cells in the aggregate.
|
||||
//
|
||||
// Note that in a `row` each `cell` comes from a different `column`, but `cell::key()`
|
||||
// will all return the same index value across the whole `row`. To get the names
|
||||
// of the columns themselves to build ex. the key name of a JSON key-value pair,
|
||||
// use `cell::col()`, which will be different for each `cell` across the `row`.
|
||||
//
|
||||
// The db::row::iterator iterates over the cells in a row; to iterate over
|
||||
// multiple rows use the db::cursor
|
||||
/// A `row` is a collection of cells from different columns which all share the same
|
||||
/// key. This is an interface for dealing with those cells in the aggregate.
|
||||
///
|
||||
/// Note that in a `row` each `cell` comes from a different `column`, but `cell::key()`
|
||||
/// will all return the same index value across the whole `row`. To get the names
|
||||
/// of the columns themselves to build ex. the key name of a JSON key-value pair,
|
||||
/// use `cell::col()`, which will be different for each `cell` across the `row`.
|
||||
///
|
||||
/// The db::row::iterator iterates over the cells in a row; to iterate over
|
||||
/// multiple rows use the db::cursor
|
||||
struct ircd::db::row
|
||||
{
|
||||
struct delta;
|
||||
struct iterator;
|
||||
struct const_iterator;
|
||||
using value_type = cell &;
|
||||
using reference = cell &;
|
||||
using pointer = cell *;
|
||||
using difference_type = size_t;
|
||||
|
||||
private: public:
|
||||
std::vector<cell> its;
|
||||
using vector = std::vector<cell>;
|
||||
using iterator = vector::iterator;
|
||||
using const_iterator = vector::const_iterator;
|
||||
using value_type = vector::value_type;
|
||||
|
||||
vector its;
|
||||
|
||||
public:
|
||||
auto empty() const { return its.empty(); }
|
||||
|
@ -77,8 +75,8 @@ struct ircd::db::row
|
|||
// [SET] Perform operation
|
||||
void operator()(const op &, const string_view &col, const string_view &val = {}, const sopts & = {});
|
||||
|
||||
row(std::vector<cell> cells = {})
|
||||
:its{std::move(cells)}
|
||||
row(std::vector<cell> its = {})
|
||||
:its{std::move(its)}
|
||||
{}
|
||||
|
||||
row(database &,
|
||||
|
@ -93,9 +91,6 @@ struct ircd::db::row
|
|||
gopts opts = {});
|
||||
|
||||
template<class pos> friend size_t seek(row &, const pos &);
|
||||
friend size_t trim(row &, const std::function<bool (cell &)> &);
|
||||
friend size_t trim(row &, const string_view &key); // remove invalid or not equal
|
||||
friend size_t trim(row &); // remove invalid
|
||||
};
|
||||
|
||||
namespace ircd::db
|
||||
|
@ -108,64 +103,6 @@ namespace ircd::db
|
|||
void write(const row::delta &, const sopts & = {});
|
||||
}
|
||||
|
||||
struct ircd::db::row::const_iterator
|
||||
{
|
||||
using value_type = const cell &;
|
||||
using reference = const cell &;
|
||||
using pointer = const cell *;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
|
||||
private:
|
||||
friend class row;
|
||||
|
||||
decltype(row::its)::const_iterator it;
|
||||
|
||||
const_iterator(decltype(row::its)::const_iterator it)
|
||||
:it{std::move(it)}
|
||||
{}
|
||||
|
||||
public:
|
||||
reference operator*() const { return it.operator*(); }
|
||||
pointer operator->() const { return it.operator->(); }
|
||||
|
||||
const_iterator &operator++() { ++it; return *this; }
|
||||
const_iterator &operator--() { --it; return *this; }
|
||||
|
||||
const_iterator() = default;
|
||||
|
||||
friend bool operator==(const const_iterator &, const const_iterator &);
|
||||
friend bool operator!=(const const_iterator &, const const_iterator &);
|
||||
};
|
||||
|
||||
struct ircd::db::row::iterator
|
||||
{
|
||||
using value_type = cell &;
|
||||
using reference = cell &;
|
||||
using pointer = cell *;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
|
||||
private:
|
||||
friend class row;
|
||||
|
||||
decltype(row::its)::iterator it;
|
||||
|
||||
iterator(decltype(row::its)::iterator it)
|
||||
:it{std::move(it)}
|
||||
{}
|
||||
|
||||
public:
|
||||
reference operator*() const { return it.operator*(); }
|
||||
pointer operator->() const { return it.operator->(); }
|
||||
|
||||
iterator &operator++() { ++it; return *this; }
|
||||
iterator &operator--() { --it; return *this; }
|
||||
|
||||
iterator() = default;
|
||||
|
||||
friend bool operator==(const iterator &, const iterator &);
|
||||
friend bool operator!=(const iterator &, const iterator &);
|
||||
};
|
||||
|
||||
//
|
||||
// A delta is an element of a database transaction. You can use this to make
|
||||
// an all-succeed-or-all-fail commitment to multiple rows at once. It is also
|
||||
|
@ -223,49 +160,25 @@ const
|
|||
inline ircd::db::row::iterator
|
||||
ircd::db::row::end()
|
||||
{
|
||||
return { std::end(its) };
|
||||
return std::end(its);
|
||||
}
|
||||
|
||||
inline ircd::db::row::iterator
|
||||
ircd::db::row::begin()
|
||||
{
|
||||
return { std::begin(its) };
|
||||
return std::begin(its);
|
||||
}
|
||||
|
||||
inline ircd::db::row::const_iterator
|
||||
ircd::db::row::end()
|
||||
const
|
||||
{
|
||||
return { std::end(its) };
|
||||
return std::end(its);
|
||||
}
|
||||
|
||||
inline ircd::db::row::const_iterator
|
||||
ircd::db::row::begin()
|
||||
const
|
||||
{
|
||||
return { std::begin(its) };
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::operator!=(const row::iterator &a, const row::iterator &b)
|
||||
{
|
||||
return a.it != b.it;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::operator==(const row::iterator &a, const row::iterator &b)
|
||||
{
|
||||
return a.it == b.it;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::operator!=(const row::const_iterator &a, const row::const_iterator &b)
|
||||
{
|
||||
return a.it != b.it;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::db::operator==(const row::const_iterator &a, const row::const_iterator &b)
|
||||
{
|
||||
return a.it == b.it;
|
||||
return std::begin(its);
|
||||
}
|
||||
|
|
75
ircd/db.cc
75
ircd/db.cc
|
@ -1702,37 +1702,9 @@ ircd::db::seek(row &r,
|
|||
template size_t ircd::db::seek<ircd::db::pos>(row &, const pos &);
|
||||
template size_t ircd::db::seek<ircd::string_view>(row &, const string_view &);
|
||||
|
||||
size_t
|
||||
ircd::db::trim(row &r)
|
||||
{
|
||||
return trim(r, []
|
||||
(const auto &cell)
|
||||
{
|
||||
return !valid(*cell.it);
|
||||
});
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::db::trim(row &r,
|
||||
const string_view &index)
|
||||
{
|
||||
return trim(r, [&index]
|
||||
(const auto &cell)
|
||||
{
|
||||
return !valid_eq(*cell.it, index);
|
||||
});
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::db::trim(row &r,
|
||||
const std::function<bool (cell &)> &closure)
|
||||
{
|
||||
const auto end(std::remove_if(std::begin(r.its), std::end(r.its), closure));
|
||||
const auto ret(std::distance(end, std::end(r.its)));
|
||||
r.its.erase(end, std::end(r.its));
|
||||
r.its.shrink_to_fit();
|
||||
return ret;
|
||||
}
|
||||
//
|
||||
// row
|
||||
//
|
||||
|
||||
ircd::db::row::row(database &d,
|
||||
const string_view &key,
|
||||
|
@ -1798,36 +1770,9 @@ ircd::db::row::row(database &d,
|
|||
}()}
|
||||
{
|
||||
if(key.empty())
|
||||
{
|
||||
seek(*this, pos::FRONT);
|
||||
return;
|
||||
}
|
||||
|
||||
seek(*this, key);
|
||||
|
||||
// without the noempty flag, all cells for a row show up in the row
|
||||
// i.e all the columns of the db, etc
|
||||
const bool noempty
|
||||
{
|
||||
has_opt(opts, get::NO_EMPTY)
|
||||
};
|
||||
|
||||
const auto trimmer([&key, &noempty]
|
||||
(auto &cell)
|
||||
{
|
||||
if(noempty)
|
||||
return cell.key() != key;
|
||||
|
||||
// seek() returns a lower_bound so we have to compare equality
|
||||
// here to not give the user data from the wrong row. The cell itself
|
||||
// is not removed to allow the column to be visible in the row.
|
||||
if(cell.key() != key)
|
||||
cell.it.reset();
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
trim(*this, trimmer);
|
||||
else
|
||||
seek(*this, key);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1842,28 +1787,22 @@ ircd::db::row::operator()(const op &op,
|
|||
ircd::db::row::iterator
|
||||
ircd::db::row::find(const string_view &col)
|
||||
{
|
||||
iterator ret;
|
||||
ret.it = std::find_if(std::begin(its), std::end(its), [&col]
|
||||
return std::find_if(std::begin(its), std::end(its), [&col]
|
||||
(const auto &cell)
|
||||
{
|
||||
return name(cell.c) == col;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ircd::db::row::const_iterator
|
||||
ircd::db::row::find(const string_view &col)
|
||||
const
|
||||
{
|
||||
const_iterator ret;
|
||||
ret.it = std::find_if(std::begin(its), std::end(its), [&col]
|
||||
return std::find_if(std::begin(its), std::end(its), [&col]
|
||||
(const auto &cell)
|
||||
{
|
||||
return name(cell.c) == col;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in a new issue