unify RO and RW cursor operations, move serFromString to a view
This commit is contained in:
parent
7dac111b02
commit
bdcd9150a9
156
lmdb-safe.hh
156
lmdb-safe.hh
|
@ -294,35 +294,12 @@ public:
|
|||
"If the parent transaction commits, the cursor must not be used again."
|
||||
*/
|
||||
|
||||
class MDBROCursor
|
||||
template<class Transaction>
|
||||
class MDBGenCursor
|
||||
{
|
||||
public:
|
||||
MDBROCursor(MDBROTransaction* parent, const MDB_dbi& dbi) : d_parent(parent)
|
||||
{
|
||||
int rc= mdb_cursor_open(d_parent->d_txn, dbi, &d_cursor);
|
||||
if(rc) {
|
||||
throw std::runtime_error("Error creating RO cursor: "+std::string(mdb_strerror(rc)));
|
||||
}
|
||||
}
|
||||
MDBROCursor(MDBROCursor&& rhs)
|
||||
{
|
||||
d_cursor = rhs.d_cursor;
|
||||
rhs.d_cursor=0;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
mdb_cursor_close(d_cursor);
|
||||
d_cursor=0;
|
||||
}
|
||||
|
||||
~MDBROCursor()
|
||||
{
|
||||
if(d_cursor)
|
||||
mdb_cursor_close(d_cursor);
|
||||
}
|
||||
|
||||
|
||||
MDBGenCursor(Transaction *t) : d_parent(t)
|
||||
{}
|
||||
int get(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op);
|
||||
|
@ -339,7 +316,7 @@ public:
|
|||
throw std::runtime_error("Unable to find from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
key.d_mdbval = in.d_mdbval;
|
||||
|
@ -350,16 +327,78 @@ public:
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int nextprev(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, op);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("Unable to prevnext from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int next(MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, MDB_NEXT);
|
||||
return nextprev(key, data, MDB_NEXT);
|
||||
}
|
||||
|
||||
int prev(MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
return nextprev(key, data, MDB_PREV);
|
||||
}
|
||||
|
||||
int currentlast(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, op);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("Unable to next from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int current(MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
return currentlast(key, data, MDB_GET_CURRENT);
|
||||
}
|
||||
int last(MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
return currentlast(key, data, MDB_LAST);
|
||||
}
|
||||
|
||||
operator MDB_cursor*&()
|
||||
{
|
||||
return d_cursor;
|
||||
}
|
||||
|
||||
MDB_cursor* d_cursor;
|
||||
MDBROTransaction* d_parent;
|
||||
Transaction* d_parent;
|
||||
};
|
||||
|
||||
class MDBROCursor : public MDBGenCursor<MDBROTransaction>
|
||||
{
|
||||
public:
|
||||
MDBROCursor(MDBROTransaction* parent, const MDB_dbi& dbi) : MDBGenCursor<MDBROTransaction>(parent)
|
||||
{
|
||||
int rc= mdb_cursor_open(d_parent->d_txn, dbi, &d_cursor);
|
||||
if(rc) {
|
||||
throw std::runtime_error("Error creating RO cursor: "+std::string(mdb_strerror(rc)));
|
||||
}
|
||||
}
|
||||
MDBROCursor(MDBROCursor&& rhs) : MDBGenCursor<MDBROTransaction>(rhs.d_parent)
|
||||
{
|
||||
rhs.d_cursor=0;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
mdb_cursor_close(d_cursor);
|
||||
d_cursor=0;
|
||||
}
|
||||
|
||||
~MDBROCursor()
|
||||
{
|
||||
if(d_cursor)
|
||||
mdb_cursor_close(d_cursor);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class MDBRWCursor;
|
||||
|
@ -510,10 +549,10 @@ public:
|
|||
/* "A cursor in a write-transaction can be closed before its transaction ends, and will otherwise be closed when its transaction ends"
|
||||
This is a problem for us since it may means we are closing the cursor twice, which is bad
|
||||
*/
|
||||
class MDBRWCursor
|
||||
class MDBRWCursor : public MDBGenCursor<MDBRWTransaction>
|
||||
{
|
||||
public:
|
||||
MDBRWCursor(MDBRWTransaction* parent, const MDB_dbi& dbi) : d_parent(parent)
|
||||
MDBRWCursor(MDBRWTransaction* parent, const MDB_dbi& dbi) : MDBGenCursor<MDBRWTransaction>(parent)
|
||||
{
|
||||
int rc= mdb_cursor_open(d_parent->d_txn, dbi, &d_cursor);
|
||||
if(rc) {
|
||||
|
@ -521,9 +560,8 @@ public:
|
|||
}
|
||||
d_parent->reportCursor(this);
|
||||
}
|
||||
MDBRWCursor(MDBRWCursor&& rhs)
|
||||
MDBRWCursor(MDBRWCursor&& rhs) : MDBGenCursor<MDBRWTransaction>(rhs.d_parent)
|
||||
{
|
||||
d_parent = rhs.d_parent;
|
||||
d_cursor = rhs.d_cursor;
|
||||
rhs.d_cursor=0;
|
||||
d_parent->reportCursorMove(&rhs, this);
|
||||
|
@ -543,12 +581,14 @@ public:
|
|||
d_parent->unreportCursor(this);
|
||||
}
|
||||
|
||||
int get(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
|
||||
|
||||
void put(const MDBOutVal& key, const MDBInVal& data)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("mdb_cursor_get: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
int rc = mdb_cursor_put(d_cursor,
|
||||
const_cast<MDB_val*>(&key.d_mdbval),
|
||||
const_cast<MDB_val*>(&data.d_mdbval), MDB_CURRENT);
|
||||
if(rc)
|
||||
throw std::runtime_error("mdb_cursor_put: " + std::string(mdb_strerror(rc)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -560,45 +600,9 @@ public:
|
|||
const_cast<MDB_val*>(&data.d_mdbval), flags);
|
||||
}
|
||||
|
||||
int find(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
key.d_mdbval = in.d_mdbval;
|
||||
int rc=mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, MDB_SET);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("Unable to find from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
key.d_mdbval = in.d_mdbval;
|
||||
|
||||
int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, MDB_SET_RANGE);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("Unable to lower_bound from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int next(MDBOutVal& key, MDBOutVal& data)
|
||||
{
|
||||
int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), &data.d_mdbval, MDB_NEXT);
|
||||
if(rc && rc != MDB_NOTFOUND)
|
||||
throw std::runtime_error("Unable to next from cursor: " + std::string(mdb_strerror(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int del(int flags=0)
|
||||
{
|
||||
return mdb_cursor_del(d_cursor, flags);
|
||||
}
|
||||
|
||||
operator MDB_cursor*&()
|
||||
{
|
||||
return d_cursor;
|
||||
}
|
||||
|
||||
MDB_cursor* d_cursor;
|
||||
MDBRWTransaction* d_parent;
|
||||
};
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ std::string serToString(const T& t)
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
void serFromString(const std::string& str, T& ret)
|
||||
void serFromString(const string_view& str, T& ret)
|
||||
{
|
||||
ret = T();
|
||||
|
||||
boost::iostreams::array_source source(str.c_str(), str.size());
|
||||
boost::iostreams::array_source source(&str[0], str.size());
|
||||
boost::iostreams::stream<boost::iostreams::array_source> stream(source);
|
||||
boost::archive::binary_iarchive in_archive(stream, boost::archive::no_header|boost::archive::no_codecvt);
|
||||
in_archive >> ret;
|
||||
|
|
Loading…
Reference in New Issue