#pragma once
#include <stdexcept>
-#include <string_view>
-#include <sstream>
-#include <iostream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
+#include <utility>
#include "lmdb-safe.hh"
/**
* LMDB ID Vector Type.
*/
-typedef std::vector<uint32_t> LmdbIdVec;
+using LmdbIdVec = std::vector<uint32_t>;
/**
* Return the highest ID used in a database. Returns 0 for an empty DB. This makes us
template <class T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type* = nullptr>
inline std::string keyConv(const T& value)
{
- return std::string((char*)&value, sizeof(value));
+ return string{(char*)&value, sizeof(value)};
}
/**
throw std::runtime_error("combined key too short to get ID from");
}
- MDBOutVal ret;
+ MDBOutVal ret{};
ret.d_mdbval.mv_data = combined.d_mdbval.mv_data;
ret.d_mdbval.mv_size = combined.d_mdbval.mv_size - sizeof(uint32_t);
throw std::runtime_error("combined key too short to get ID from");
}
- MDBOutVal ret;
+ MDBOutVal ret{};
ret.d_mdbval.mv_data = (char*) combined.d_mdbval.mv_data + combined.d_mdbval.mv_size - sizeof(uint32_t);
ret.d_mdbval.mv_size = sizeof(uint32_t);
void put(MDBRWTransaction& txn, const Class& t, uint32_t id, int flags=0)
{
- std::string sempty("");
+ std::string sempty;
MDBInVal empty(sempty);
auto scombined = makeCombinedKey(keyConv(d_parent->getMember(t)), id);
auto scombined = makeCombinedKey(keyConv(d_parent->getMember(t)), id);
MDBInVal combined(scombined);
- if(int rc = txn->del(d_idx, combined)) {
- throw std::runtime_error("Error deleting from index: " + std::string(mdb_strerror(rc)));
+ int errCode = txn->del(d_idx, combined);
+ if (errCode != 0) {
+ throw std::runtime_error("Error deleting from index: " + std::string(mdb_strerror(errCode)));
}
}
return c.*PtrToMember;
}
- typedef Type type;
+ using type = Type;
};
/** This is a calculated index */
return f(c);
}
- typedef Type type;
+ using type = Type;
};
/** nop index, so we can fill our N indexes, even if you don't use them all */
{
}
- typedef uint32_t type; // dummy
+
+ using type = uint32_t; // dummy
};
/** The main class. Templatized only on the indexes and typename right now */
#undef openMacro
}
-
// we get a lot of our smarts from this tuple, it enables get<0> etc
- typedef std::tuple<I1, I2, I3, I4> tuple_t;
+ using tuple_t = std::tuple<I1, I2, I3, I4>;
tuple_t d_tuple;
// We support readonly and rw transactions. Here we put the Readonly operations
//! Get item with id, from main table directly
bool get(uint32_t id, T& t)
{
- MDBOutVal data;
- if((*d_parent.d_txn)->get(d_parent.d_parent->d_main, id, data))
+ MDBOutVal data{};
+ if((*d_parent.d_txn)->get(d_parent.d_parent->d_main, id, data)) {
return false;
+ }
deserializeFromBuffer(data.get<std::string>(), t);
return true;
// id.d_mdbval.mv_size -= LS_HEADER_SIZE;
// id.d_mdbval.mv_data = (char*)d_id.d_mdbval.mv_data + LS_HEADER_SIZE;
-
- if(d_on_index) {
- if((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
+ if (d_on_index) {
+ if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data)) {
throw std::runtime_error("Missing id in constructor");
+ }
deserializeFromBuffer(d_data.get<std::string>(), d_t);
}
- else
+ else {
deserializeFromBuffer(d_id.get<std::string>(), d_t);
+ }
}
- explicit iter_t(Parent* parent, typename Parent::cursor_t&& cursor, const std::string& prefix) :
+ explicit iter_t(Parent* parent, typename Parent::cursor_t&& cursor, std::string prefix) :
d_parent(parent),
d_cursor(std::move(cursor)),
d_on_index(true), // is this an iterator on main database or on index?
d_one_key(false),
- d_prefix(prefix),
- d_end(false)
+ d_prefix(std::move(prefix))
{
- if(d_end)
+ if (d_end) {
return;
+ }
- if(d_cursor.get(d_key, d_id, MDB_GET_CURRENT)) {
+ if (d_cursor.get(d_key, d_id, MDB_GET_CURRENT)) {
d_end = true;
return;
}
d_id = getIDFromCombinedKey(d_key);
- if(d_on_index) {
- if((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
+ if (d_on_index) {
+ if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data)) {
throw std::runtime_error("Missing id in constructor");
+ }
deserializeFromBuffer(d_data.get<std::string>(), d_t);
}
- else
+ else {
deserializeFromBuffer(d_id.get<std::string>(), d_t);
+ }
}
-
// std::function<bool(const MDBOutVal&)> filter;
void del()
{
// implements generic ++ or --
iter_t& genoperator(MDB_cursor_op op)
{
- MDBOutVal data;
- int rc;
+ MDBOutVal data{};
+ int rc = 0;
// next:;
if (!d_one_key) {
rc = d_cursor.get(d_key, d_id, op);
if(d_one_key || rc == MDB_NOTFOUND) {
d_end = true;
}
- else if(rc) {
+ else if(rc != 0) {
throw std::runtime_error("in genoperator, " + std::string(mdb_strerror(rc)));
}
else if(!d_prefix.empty() &&
if(d_on_index) {
d_id = getIDFromCombinedKey(d_key);
- if((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, data))
+ if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, data)) {
throw std::runtime_error("Missing id field");
+ }
// if(filter && !filter(data))
// goto next;
// get ID this iterator points to
uint32_t getID()
{
- if(d_on_index) {
+ if (d_on_index) {
// return d_id.get<uint32_t>();
return d_id.getNoStripHeader<uint32_t>();
}
- else {
- return d_key.getNoStripHeader<uint32_t>();
- }
+ return d_key.getNoStripHeader<uint32_t>();
}
const MDBOutVal& getKey()
return d_key;
}
-
// transaction we are part of
Parent* d_parent;
typename Parent::cursor_t d_cursor;
// gcc complains if I don't zero-init these, which is worrying XXX
- MDBOutVal d_key{{0,0}}, d_data{{0,0}}, d_id{{0,0}};
+ MDBOutVal d_key{{0, nullptr}};
+ MDBOutVal d_data{{0, nullptr}};
+ MDBOutVal d_id{{0, nullptr}};
bool d_on_index;
bool d_one_key;
std::string d_prefix;
{
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
if(cursor.get(out, id, op)) {
// on_index, one_key, end
{
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(d_parent.d_parent->d_main);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
if(cursor.get(out, id, MDB_FIRST)) {
// on_index, one_key, end
std::string keystr = makeCombinedKey(keyConv(key), MDBInVal(""));
MDBInVal in(keystr);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
out.d_mdbval = in.d_mdbval;
if(cursor.get(out, id, op)) {
std::string keyString=makeCombinedKey(keyConv(key), MDBInVal(""));
MDBInVal in(keyString);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
out.d_mdbval = in.d_mdbval;
if(cursor.get(out, id, MDB_SET)) {
std::string keyString=makeCombined(keyConv(key), MDBInVal(""));
MDBInVal in(keyString);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
out.d_mdbval = in.d_mdbval;
if(cursor.get(out, id, MDB_SET_RANGE) ||
std::string keyString=makeCombinedKey(keyConv(key), MDBInVal(""));
MDBInVal in(keyString);
- MDBOutVal out, id;
+ MDBOutVal out{};
+ MDBOutVal id{};
out.d_mdbval = in.d_mdbval;
int rc = cursor.get(out, id, MDB_SET_RANGE);
if (sthiskey == keyString) {
auto _id = getIDFromCombinedKey(out);
uint64_t ts = LMDBLS::LSgetTimestamp(id.getNoStripHeader<string_view>());
- uint32_t __id = _id.getNoStripHeader<uint32_t>();
+ auto __id = _id.getNoStripHeader<uint32_t>();
if (onlyOldest) {
if (ts < oldestts) {
return d_txn;
}
- typedef MDBROCursor cursor_t;
+ using cursor_t = MDBROCursor;
TypedDBI* d_parent;
std::shared_ptr<MDBROTransaction> d_txn;
};
-
class RWTransaction : public ReadonlyOperations<RWTransaction>
{
public:
- explicit RWTransaction(TypedDBI* parent) : ReadonlyOperations<RWTransaction>(*this), d_parent(parent)
+ explicit RWTransaction(TypedDBI* parent) :
+ ReadonlyOperations<RWTransaction>(*this), d_parent(parent), d_txn(std::make_shared<MDBRWTransaction>(d_parent->d_env->getRWTransaction()))
{
- d_txn = std::make_shared<MDBRWTransaction>(d_parent->d_env->getRWTransaction());
}
explicit RWTransaction(TypedDBI* parent, std::shared_ptr<MDBRWTransaction> txn) : ReadonlyOperations<RWTransaction>(*this), d_parent(parent), d_txn(txn)
{
}
-
RWTransaction(RWTransaction&& rhs) :
ReadonlyOperations<RWTransaction>(*this),
d_parent(rhs.d_parent), d_txn(std::move(rhs.d_txn))
void modify(uint32_t id, std::function<void(T&)> func)
{
T t;
- if(!this->get(id, t))
- throw std::runtime_error("Could not modify id "+std::to_string(id));
+ if (!this->get(id, t)) {
+ throw std::runtime_error("Could not modify id " + std::to_string(id));
+ }
func(t);
del(id); // this is the lazy way. We could test for changed index fields
void del(uint32_t id)
{
T t;
- if(!this->get(id, t))
+ if (!this->get(id, t)) {
return;
+ }
(*d_txn)->del(d_parent->d_main, id);
clearIndex(id, t);
{
auto cursor = (*d_txn)->getRWCursor(d_parent->d_main);
bool first = true;
- MDBOutVal key, data;
+ MDBOutVal key{};
+ MDBOutVal data{};
while(!cursor.get(key, data, first ? MDB_FIRST : MDB_NEXT)) {
first = false;
T t;
(*d_txn)->abort();
}
- typedef MDBRWCursor cursor_t;
+ using cursor_t = MDBRWCursor;
std::shared_ptr<MDBRWTransaction> getTransactionHandle()
{