1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2025-07-03 14:14:11 +00:00

Add support for the MATCH and COUNT options for the SCAN commands.

This commit is contained in:
King_DuckZ 2016-06-14 19:11:13 +01:00
parent 423effa6cb
commit 874783e8da
3 changed files with 36 additions and 15 deletions

View file

@ -25,7 +25,13 @@
namespace redis { namespace redis {
namespace implem { namespace implem {
ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand) : ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand) :
m_command(parCommand) ScanIteratorBaseClass(parCommand, boost::string_ref())
{
}
ScanIteratorBaseClass::ScanIteratorBaseClass (Command* parCommand, boost::string_ref parMatchPattern) :
m_command(parCommand),
m_match_pattern(parMatchPattern)
{ {
assert(m_command); assert(m_command);
assert(m_command->is_connected()); assert(m_command->is_connected());
@ -35,12 +41,22 @@ namespace redis {
return m_command and m_command->is_connected(); return m_command and m_command->is_connected();
} }
Reply ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext) { Reply ScanIteratorBaseClass::run (const char* parCommand, long long parScanContext, std::size_t parCount) {
return m_command->run(parCommand, boost::lexical_cast<std::string>(parScanContext)); const auto scan_context = boost::lexical_cast<std::string>(parScanContext);
const auto count_hint = boost::lexical_cast<std::string>(parCount);
if (m_match_pattern.empty())
return m_command->run(parCommand, scan_context, "COUNT", count_hint);
else
return m_command->run(parCommand, scan_context, "MATCH", m_match_pattern, "COUNT", count_hint);
} }
Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext) { Reply ScanIteratorBaseClass::run (const char* parCommand, const boost::string_ref& parParameter, long long parScanContext, std::size_t parCount) {
return m_command->run(parCommand, parParameter, boost::lexical_cast<std::string>(parScanContext)); const auto scan_context = boost::lexical_cast<std::string>(parScanContext);
const auto count_hint = boost::lexical_cast<std::string>(parCount);
if (m_match_pattern.empty())
return m_command->run(parCommand, parParameter, scan_context, "COUNT", count_hint);
else
return m_command->run(parCommand, parParameter, scan_context, "MATCH", m_match_pattern, "COUNT", count_hint);
} }
} //namespace implem } //namespace implem
} //namespace redis } //namespace redis

View file

@ -40,16 +40,18 @@ namespace redis {
class ScanIteratorBaseClass { class ScanIteratorBaseClass {
protected: protected:
explicit ScanIteratorBaseClass ( Command* parCommand ); explicit ScanIteratorBaseClass ( Command* parCommand );
ScanIteratorBaseClass ( Command* parCommand, boost::string_ref parMatchPattern );
~ScanIteratorBaseClass ( void ) noexcept = default; ~ScanIteratorBaseClass ( void ) noexcept = default;
bool is_connected ( void ) const; bool is_connected ( void ) const;
Reply run ( const char* parCommand, long long parScanContext ); Reply run ( const char* parCommand, long long parScanContext, std::size_t parCount );
Reply run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext ); Reply run ( const char* parCommand, const boost::string_ref& parParameter, long long parScanContext, std::size_t parCount );
bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; } bool is_equal ( const ScanIteratorBaseClass& parOther ) const { return m_command == parOther.m_command; }
private: private:
Command* m_command; Command* m_command;
boost::string_ref m_match_pattern;
}; };
} //namespace implem } //namespace implem
@ -70,9 +72,9 @@ namespace redis {
typedef typename base_iterator::iterator_category iterator_category; typedef typename base_iterator::iterator_category iterator_category;
template <typename Dummy=ValueFetch, typename=typename std::enable_if<not HasScanTargetMethod<Dummy>::value>::type> template <typename Dummy=ValueFetch, typename=typename std::enable_if<not HasScanTargetMethod<Dummy>::value>::type>
ScanIterator ( Command* parCommand, bool parEnd ); ScanIterator ( Command* parCommand, bool parEnd, boost::string_ref parMatchPattern=boost::string_ref() );
template <typename Dummy=ValueFetch, typename=typename std::enable_if<HasScanTargetMethod<Dummy>::value>::type> template <typename Dummy=ValueFetch, typename=typename std::enable_if<HasScanTargetMethod<Dummy>::value>::type>
ScanIterator ( Command* parCommand, boost::string_ref parKey, bool parEnd ); ScanIterator ( Command* parCommand, boost::string_ref parKey, bool parEnd, boost::string_ref parMatchPattern=boost::string_ref() );
private: private:
template <typename T> template <typename T>
@ -96,6 +98,7 @@ namespace redis {
static constexpr const char* command ( void ) { return "SCAN"; } static constexpr const char* command ( void ) { return "SCAN"; }
static constexpr const std::size_t step = 1; static constexpr const std::size_t step = 1;
static constexpr const std::size_t work_count = 10;
static const T& make_value ( const Reply* parItem ); static const T& make_value ( const Reply* parItem );
}; };
@ -108,6 +111,7 @@ namespace redis {
static constexpr const char* command ( void ) { return "SSCAN"; } static constexpr const char* command ( void ) { return "SSCAN"; }
static constexpr const std::size_t step = 1; static constexpr const std::size_t step = 1;
static constexpr const std::size_t work_count = 10;
static const T& make_value ( const Reply* parItem ); static const T& make_value ( const Reply* parItem );
boost::string_ref scan_target ( void ) const { return m_scan_target; } boost::string_ref scan_target ( void ) const { return m_scan_target; }
@ -125,6 +129,7 @@ namespace redis {
static constexpr const char* command ( void ) { return ScanCommands::_from_integral(Command)._to_string(); } static constexpr const char* command ( void ) { return ScanCommands::_from_integral(Command)._to_string(); }
static constexpr const std::size_t step = 2; static constexpr const std::size_t step = 2;
static constexpr const std::size_t work_count = 10;
static value_type make_value ( const Reply* parItem ); static value_type make_value ( const Reply* parItem );
boost::string_ref scan_target ( void ) const { return m_scan_target; } boost::string_ref scan_target ( void ) const { return m_scan_target; }

View file

@ -25,8 +25,8 @@ namespace redis {
template <typename ValueFetch> template <typename ValueFetch>
template <typename Dummy, typename> template <typename Dummy, typename>
ScanIterator<ValueFetch>::ScanIterator (Command* parCommand, bool parEnd) : ScanIterator<ValueFetch>::ScanIterator (Command* parCommand, bool parEnd, boost::string_ref parMatchPattern) :
implem::ScanIteratorBaseClass(parCommand), implem::ScanIteratorBaseClass(parCommand, parMatchPattern),
implem::ScanIteratorBaseIterator<ValueFetch>(), implem::ScanIteratorBaseIterator<ValueFetch>(),
ValueFetch(), ValueFetch(),
m_reply(), m_reply(),
@ -45,8 +45,8 @@ namespace redis {
template <typename ValueFetch> template <typename ValueFetch>
template <typename Dummy, typename> template <typename Dummy, typename>
ScanIterator<ValueFetch>::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd) : ScanIterator<ValueFetch>::ScanIterator (Command* parCommand, boost::string_ref parKey, bool parEnd, boost::string_ref parMatchPattern) :
implem::ScanIteratorBaseClass(parCommand), implem::ScanIteratorBaseClass(parCommand, parMatchPattern),
implem::ScanIteratorBaseIterator<ValueFetch>(), implem::ScanIteratorBaseIterator<ValueFetch>(),
ValueFetch(parKey), ValueFetch(parKey),
m_reply(), m_reply(),
@ -132,13 +132,13 @@ namespace redis {
template <typename ValueFetch> template <typename ValueFetch>
template <typename T> template <typename T>
Reply ScanIterator<ValueFetch>::forward_scan_command (typename std::enable_if<HasScanTargetMethod<T>::value, int>::type) { Reply ScanIterator<ValueFetch>::forward_scan_command (typename std::enable_if<HasScanTargetMethod<T>::value, int>::type) {
return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context); return implem::ScanIteratorBaseClass::run(T::command(), T::scan_target(), m_scan_context, T::work_count);
} }
template <typename ValueFetch> template <typename ValueFetch>
template <typename T> template <typename T>
Reply ScanIterator<ValueFetch>::forward_scan_command (typename std::enable_if<not HasScanTargetMethod<T>::value, int>::type) { Reply ScanIterator<ValueFetch>::forward_scan_command (typename std::enable_if<not HasScanTargetMethod<T>::value, int>::type) {
return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context); return implem::ScanIteratorBaseClass::run(T::command(), m_scan_context, T::work_count);
} }
template <typename T> template <typename T>