0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::db: Fix reverse iteration; cleanup seek; add ORDERED flag (prelim).

This commit is contained in:
Jason Volk 2017-09-23 19:47:36 -07:00
parent 7f7ef9a4bf
commit 0b1c37c585
2 changed files with 46 additions and 21 deletions

View file

@ -58,7 +58,8 @@ enum class ircd::db::get
NO_CACHE = 0x0004, // Do not update the cache (NO_CACHE is default for iterators)
NO_SNAPSHOT = 0x0008, // This iterator will have the latest data (tailing)
NO_CHECKSUM = 0x0010, // Integrity of data will be checked unless this is specified
PREFIX = 0x0020, // Iteration over a single prefix in column (prefix_same_as_start)
PREFIX = 0x0020, // (prefix_same_as_start); automatic for index columns with pfx
ORDERED = 0x0040, // (total_order_seek); relevant to index columns
};
template<class T>

View file

@ -1782,6 +1782,12 @@ ircd::db::index::end(const string_view &key,
return ret;
}
/// NOTE: RocksDB says they don't support reverse iteration over a prefix range
/// This means we have to forward scan to the end and then walk back! Reverse
/// iterations of an index shoud only be used for debugging and statistics! The
/// index should be ordered the way it will be primarily accessed using the
/// comparator. If it will be accessed in different directions, make another
/// index column.
ircd::db::index::const_reverse_iterator
ircd::db::index::rbegin(const string_view &key,
gopts opts)
@ -1791,9 +1797,11 @@ ircd::db::index::rbegin(const string_view &key,
c, {}, opts.snapshot
};
opts |= get::NO_CACHE;
if(seek(ret, key, opts))
seek(ret, pos::BACK, opts);
{
while(seek(ret, pos::NEXT, opts));
seek(ret, pos::PREV, opts);
}
return ret;
}
@ -3217,9 +3225,10 @@ ircd::db::has(const rocksdb::WriteBatch &wb,
namespace ircd::db
{
static rocksdb::Iterator &_seek_(rocksdb::Iterator &, const rocksdb::Slice &);
static rocksdb::Iterator &_seek_(rocksdb::Iterator &, const string_view &);
static rocksdb::Iterator &_seek_(rocksdb::Iterator &, const pos &);
static rocksdb::Iterator &_seek_(rocksdb::Iterator &, const string_view &);
static rocksdb::Iterator &_seek_lower_(rocksdb::Iterator &, const string_view &);
static rocksdb::Iterator &_seek_upper_(rocksdb::Iterator &, const string_view &);
static std::unique_ptr<rocksdb::Iterator> _seek_offload(database::column &c, const rocksdb::ReadOptions &opts, const std::function<void (rocksdb::Iterator &)> &closure);
bool _seek(database::column &, const pos &, const rocksdb::ReadOptions &, std::unique_ptr<rocksdb::Iterator> &it);
bool _seek(database::column &, const string_view &, const rocksdb::ReadOptions &, std::unique_ptr<rocksdb::Iterator> &it);
@ -3386,7 +3395,10 @@ ircd::db::_seek(database::column &c,
(rocksdb::Iterator &blocking_it)
{
if(valid_it)
_seek_(blocking_it, it->key());
{
assert(valid(*it));
_seek_(blocking_it, slice(it->key()));
}
_seek_(blocking_it, p);
})
@ -3449,6 +3461,32 @@ ircd::db::_seek_offload(database::column &c,
return blocking_it;
}
/// Seek to entry NOT GREATER THAN key. That is, equal to or less than key
rocksdb::Iterator &
ircd::db::_seek_lower_(rocksdb::Iterator &it,
const string_view &sv)
{
it.SeekForPrev(slice(sv));
return it;
}
/// Seek to entry NOT LESS THAN key. That is, equal to or greater than key
rocksdb::Iterator &
ircd::db::_seek_upper_(rocksdb::Iterator &it,
const string_view &sv)
{
it.Seek(slice(sv));
return it;
}
/// Defaults to _seek_upper_ because it has better support from RocksDB.
rocksdb::Iterator &
ircd::db::_seek_(rocksdb::Iterator &it,
const string_view &sv)
{
return _seek_upper_(it, sv);
}
rocksdb::Iterator &
ircd::db::_seek_(rocksdb::Iterator &it,
const pos &p)
@ -3473,21 +3511,6 @@ ircd::db::_seek_(rocksdb::Iterator &it,
return it;
}
rocksdb::Iterator &
ircd::db::_seek_(rocksdb::Iterator &it,
const string_view &sv)
{
return _seek_(it, slice(sv));
}
rocksdb::Iterator &
ircd::db::_seek_(rocksdb::Iterator &it,
const rocksdb::Slice &sk)
{
it.Seek(sk);
return it;
}
///////////////////////////////////////////////////////////////////////////////
//
// Misc
@ -3746,6 +3769,7 @@ ircd::db::operator+=(rocksdb::ReadOptions &ret,
ret.tailing = test(opts, get::NO_SNAPSHOT);
ret.verify_checksums = !test(opts, get::NO_CHECKSUM);
ret.prefix_same_as_start = test(opts, get::PREFIX);
ret.total_order_seek = test(opts, get::ORDERED);
return ret;
}