0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-27 11:18:51 +02:00

ircd:Ⓜ️ Curse the cursor.

modules/console: Update dump; add errcount.
This commit is contained in:
Jason Volk 2018-02-16 11:52:43 -08:00
parent acdb99887f
commit 632b1e6f0f
5 changed files with 14 additions and 274 deletions

View file

@ -1,265 +0,0 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_M_DBS_CURSOR_H
struct ircd::m::dbs::cursor
{
template<class index_iterator> struct const_iterator_base;
struct const_reverse_iterator;
struct const_iterator;
using iterator_type = const_iterator;
db::index index;
const_iterator end(const string_view &key = {});
const_iterator begin(const string_view &key = {});
const_reverse_iterator rend(const string_view &key = {});
const_reverse_iterator rbegin(const string_view &key = {});
cursor(const string_view &index)
:index{*dbs::events, index}
{}
};
template<class index_iterator>
struct ircd::m::dbs::cursor::const_iterator_base
{
using value_type = const event;
using pointer = value_type *;
using reference = value_type &;
using difference_type = size_t;
using iterator_category = std::bidirectional_iterator_tag;
index_iterator idx;
std::array<db::cell, event_columns> cell;
db::row row;
mutable event v;
mutable bool stale{true};
bool invalid{true};
operator bool() const;
bool operator!() const;
bool operator==(const const_iterator_base &o) const;
bool operator!=(const const_iterator_base &o) const;
bool row_valid() const;
string_view row_key() const;
value_type &operator*() const;
value_type *operator->() const;
protected:
bool seek_row();
public:
const_iterator_base &operator++();
const_iterator_base &operator--();
const_iterator_base();
const_iterator_base(const cursor &, index_iterator, const db::gopts & = {});
};
struct ircd::m::dbs::cursor::const_iterator
:const_iterator_base<db::index::const_iterator>
{
using const_iterator_base<db::index::const_iterator>::const_iterator_base;
};
struct ircd::m::dbs::cursor::const_reverse_iterator
:const_iterator_base<db::index::const_reverse_iterator>
{
using const_iterator_base<db::index::const_reverse_iterator>::const_iterator_base;
};
//
// cursor
//
inline ircd::m::dbs::cursor::const_reverse_iterator
ircd::m::dbs::cursor::rbegin(const string_view &key)
{
return const_reverse_iterator { *this, index.rbegin(key), {} };
}
inline ircd::m::dbs::cursor::const_reverse_iterator
ircd::m::dbs::cursor::rend(const string_view &key)
{
return const_reverse_iterator { *this, index.rend(key), {} };
}
inline ircd::m::dbs::cursor::const_iterator
ircd::m::dbs::cursor::begin(const string_view &key)
{
return const_iterator { *this, index.begin(key), {} };
}
inline ircd::m::dbs::cursor::const_iterator
ircd::m::dbs::cursor::end(const string_view &key)
{
return const_iterator { *this, index.end(key), {} };
}
//
// const iterator
//
template<class index_iterator>
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::const_iterator_base(const cursor &c,
index_iterator idx,
const db::gopts &opts)
:idx{std::move(idx)}
,cell{}
,row
{
*dbs::events,
bool(this->idx) && this->idx->second? this->idx->second:
bool(this->idx)? this->idx->first:
string_view{},
event{},
cell,
opts
}
,stale
{
true
}
,invalid
{
!this->idx || !row_valid()
}
{}
template<class index_iterator>
ircd::m::dbs::cursor::const_iterator_base<index_iterator> &
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator++()
{
while(!(invalid = !bool(++idx)))
if(seek_row())
break;
return *this;
}
template<class index_iterator>
ircd::m::dbs::cursor::const_iterator_base<index_iterator> &
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator--()
{
while(!(invalid = !bool(--idx)))
if(seek_row())
break;
return *this;
}
template<class index_iterator>
bool
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::seek_row()
{
if(!db::seek(row, row_key()))
return false;
stale = true;
return true;
}
template<class index_iterator>
typename ircd::m::dbs::cursor::const_iterator_base<index_iterator>::value_type *
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator->()
const
{
return &this->operator*();
}
template<class index_iterator>
typename ircd::m::dbs::cursor::const_iterator_base<index_iterator>::value_type &
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator*()
const
{
if(!stale)
return v;
assign(v, row, row_key());
stale = false;
return v;
}
template<class index_iterator>
bool
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::row_valid()
const
{
return row.valid(row_key());
}
template<class index_iterator>
ircd::string_view
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::row_key()
const
{
if(!idx)
return {};
if(idx->second)
return idx->second;
assert(bool(idx->first));
return idx->first;
}
template<class index_iterator>
bool
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator!()
const
{
return !static_cast<bool>(*this);
}
template<class index_iterator>
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator
bool()
const
{
if(invalid)
return false;
if(!idx)
return false;
return row_valid();
}
template<class index_iterator>
bool
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator!=(const const_iterator_base<index_iterator> &o)
const
{
return !(*this == o);
}
template<class index_iterator>
bool
ircd::m::dbs::cursor::const_iterator_base<index_iterator>::operator==(const const_iterator_base<index_iterator> &o)
const
{
if(row_key() != o.row_key())
return false;
if(!row_valid() && !o.row_valid())
return true;
if(!row_valid() || !o.row_valid())
return false;
return true;
}

View file

@ -14,7 +14,6 @@
namespace ircd::m::dbs
{
struct init;
struct cursor;
// Database instance
extern std::shared_ptr<db::database> events;

View file

@ -46,7 +46,6 @@ namespace ircd
#include "id.h"
#include "event.h"
#include "dbs.h"
#include "cursor.h"
#include "state.h"
#include "room.h"
#include "user.h"

View file

@ -24,7 +24,6 @@ namespace ircd::m::vm
using closure = std::function<void (const event &)>;
using closure_bool = std::function<bool (const event &)>;
using dbs::cursor;
extern struct log::log log;
extern uint64_t current_sequence;

View file

@ -399,15 +399,16 @@ console_cmd__event__dump(const string_view &line)
token(line, ' ', 0)
};
m::dbs::cursor cursor
db::column column
{
"event_id"
*m::dbs::events, "event_id"
};
static char buf[512_KiB];
char *pos{buf};
size_t foff{0}, ecount{0}, acount{0};
for(auto it(begin(cursor)); it != end(cursor); ++it, ++ecount)
size_t foff{0}, ecount{0}, acount{0}, errcount{0};
m::event::fetch event;
for(auto it(begin(column)); it != end(column); ++it, ++ecount)
{
const auto remain
{
@ -416,9 +417,15 @@ console_cmd__event__dump(const string_view &line)
assert(remain >= 64_KiB && remain <= sizeof(buf));
const mutable_buffer mb{pos, remain};
const m::event event{*it};
pos += json::print(mb, event);
const string_view event_id{it->second};
seek(event, event_id, std::nothrow);
if(unlikely(!event.valid(event_id)))
{
++errcount;
continue;
}
pos += json::print(mb, event);
if(pos + 64_KiB > buf + sizeof(buf))
{
const const_buffer cb{buf, pos};
@ -439,6 +446,7 @@ console_cmd__event__dump(const string_view &line)
<< " using " << foff << " bytes"
<< " in " << acount << " writes"
<< " to " << filename
<< " with " << errcount << " errors"
<< std::endl;
return true;