From f11282f5836f6971423e889852f008c07374e019 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 4 Feb 2019 19:36:43 -0800 Subject: [PATCH] ircd::db: Fix prefixed iterator seek to pos::BACK. --- include/ircd/db/index.h | 3 ++- ircd/db.cc | 33 ++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/ircd/db/index.h b/include/ircd/db/index.h index 1f764d890..13f8914f6 100644 --- a/include/ircd/db/index.h +++ b/include/ircd/db/index.h @@ -66,7 +66,8 @@ struct ircd::db::index::const_iterator_base using column::const_iterator_base::const_iterator_base; - template friend bool seek(index::const_iterator_base &, const pos &); + friend bool seek(index::const_iterator_base &, const string_view &); + friend bool seek(index::const_iterator_base &, const pos &); }; struct ircd::db::index::const_iterator diff --git a/ircd/db.cc b/ircd/db.cc index 9e5f6aa98..f6846ef76 100644 --- a/ircd/db.cc +++ b/ircd/db.cc @@ -4086,16 +4086,38 @@ ircd::db::index::applied_opts { get::PREFIX } }; -template bool ircd::db::seek(index::const_iterator_base &it, const pos &p) +{ + switch(p) + { + case pos::BACK: + { + // This is inefficient as per RocksDB's prefix impl. unknown why + // a seek to NEXT is still needed after walking back one. + while(seek(it, pos::NEXT)); + if(seek(it, pos::PREV)) + seek(it, pos::NEXT); + + return bool(it); + } + + default: + break; + } + + it.opts |= index::applied_opts; + return seek(static_cast(it), p); +} + +bool +ircd::db::seek(index::const_iterator_base &it, + const string_view &p) { it.opts |= index::applied_opts; return seek(static_cast(it), p); } -template bool ircd::db::seek(index::const_iterator_base &, const pos &); -template bool ircd::db::seek(index::const_iterator_base &, const string_view &); ircd::db::index::const_iterator ircd::db::index::begin(const string_view &key, @@ -4141,10 +4163,7 @@ ircd::db::index::rbegin(const string_view &key, }; if(seek(ret, key)) - { - while(seek(ret, pos::NEXT)); - seek(ret, pos::PREV); - } + seek(ret, pos::BACK); return ret; }