0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::db: row cleanup / fixes.

This commit is contained in:
Jason Volk 2017-09-16 15:20:13 -07:00
parent 47cd7790ed
commit 5261f9dd25
4 changed files with 32 additions and 180 deletions

View file

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

View file

@ -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{});

View file

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

View file

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