mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Improvements in the documentation.
This commit is contained in:
@@ -16,8 +16,8 @@ namespace adapter {
|
||||
\ingroup any
|
||||
|
||||
The adapter returned by this function ignores responses and is
|
||||
useful to avoid wasting time with responses which the user is
|
||||
insterested in.
|
||||
useful to avoid wasting time with responses on which the user is
|
||||
not insterested in.
|
||||
|
||||
Example usage:
|
||||
|
||||
@@ -32,34 +32,8 @@ auto adapt() noexcept
|
||||
/** \brief Adapts user data to read operations.
|
||||
* \ingroup any
|
||||
*
|
||||
* For example
|
||||
* The following types are supported.
|
||||
*
|
||||
* - Integer data types e.g. `int`, `unsigned`, etc.
|
||||
*
|
||||
* - `std::string`
|
||||
*
|
||||
* We also support the following C++ containers
|
||||
*
|
||||
* - `std::vector<T>`. Can be used with any RESP3 aggregate type.
|
||||
*
|
||||
* - `std::deque<T>`. Can be used with any RESP3 aggregate type.
|
||||
*
|
||||
* - `std::list<T>`. Can be used with any RESP3 aggregate type.
|
||||
*
|
||||
* - `std::set<T>`. Can be used with RESP3 set type.
|
||||
*
|
||||
* - `std::unordered_set<T>`. Can be used with RESP3 set type.
|
||||
*
|
||||
* - `std::map<T>`. Can be used with RESP3 hash type.
|
||||
*
|
||||
* - `std::unordered_map<T>`. Can be used with RESP3 hash type.
|
||||
*
|
||||
* All these types can be wrapped in an `boost::optional<T>`. This
|
||||
* function also support \c std::tuple to read the response to
|
||||
* tuples. At the moment this feature supports only transactions that
|
||||
* contain simple types or aggregates that don't contain aggregates
|
||||
* themselves (as in most cases).
|
||||
* All STL containers, \c std::tuple and built-in types are supported and
|
||||
* can be used in conjunction with \c boost::optional<T>.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
@@ -71,19 +45,19 @@ auto adapt() noexcept
|
||||
* For a transaction
|
||||
*
|
||||
* @code
|
||||
sr.push(command::multi);
|
||||
sr.push(command::ping, ...);
|
||||
sr.push(command::incr, ...);
|
||||
sr.push_range(command::rpush, ...);
|
||||
sr.push(command::lrange, ...);
|
||||
sr.push(command::incr, ...);
|
||||
sr.push(command::exec);
|
||||
|
||||
co_await async_write(socket, buffer(request));
|
||||
|
||||
// Reads the response to a transaction
|
||||
std::tuple<std::string, int, int, std::vector<std::string>, int> execs;
|
||||
co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(execs));
|
||||
* sr.push(command::multi);
|
||||
* sr.push(command::ping, ...);
|
||||
* sr.push(command::incr, ...);
|
||||
* sr.push_range(command::rpush, ...);
|
||||
* sr.push(command::lrange, ...);
|
||||
* sr.push(command::incr, ...);
|
||||
* sr.push(command::exec);
|
||||
*
|
||||
* co_await async_write(socket, buffer(request));
|
||||
*
|
||||
* // Reads the response to a transaction
|
||||
* std::tuple<std::string, int, int, std::vector<std::string>, int> execs;
|
||||
* co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(execs));
|
||||
* @endcode
|
||||
*/
|
||||
template<class T>
|
||||
|
||||
@@ -21,20 +21,25 @@
|
||||
namespace aedis {
|
||||
namespace adapter {
|
||||
|
||||
/** \brief Traits class for response objects.
|
||||
* \ingroup any
|
||||
/** @brief Traits class for response objects.
|
||||
* @ingroup any
|
||||
*
|
||||
* Provides traits for all supported response types i.e. all STL containers
|
||||
* and C++ buil-in types.
|
||||
*/
|
||||
template <class ResponseType>
|
||||
struct response_traits
|
||||
{
|
||||
/// The response type.
|
||||
using response_type = ResponseType;
|
||||
|
||||
/// The adapter type.
|
||||
using adapter_type = adapter::detail::wrapper<response_type>;
|
||||
using adapter_type = adapter::detail::wrapper<ResponseType>;
|
||||
|
||||
/// Returns an adapter for the reponse r
|
||||
static auto adapt(response_type& r) noexcept { return adapter_type{&r}; }
|
||||
/** @brief Returns an adapter for the reponse r
|
||||
*
|
||||
* @param r The response object e.g a C++ container.
|
||||
* @return An adapter suitable for use in resp3::read or resp3::async_read.
|
||||
* @remark Users can also use the free adapt function for type deduction.
|
||||
*/
|
||||
static auto adapt(ResponseType& r) noexcept { return adapter_type{&r}; }
|
||||
};
|
||||
|
||||
/// Template typedef for response_traits.
|
||||
|
||||
@@ -20,20 +20,21 @@
|
||||
|
||||
\section Overview
|
||||
|
||||
Aedis is a redis client library built on top of Asio that provides
|
||||
simple and efficient communication with a Redis server. Some of
|
||||
its distinctive features are
|
||||
Aedis is a [Redis](https://redis.io/) client library built on top
|
||||
of [Asio](https://www.boost.org/doc/libs/release/doc/html/boost_asio.html)
|
||||
that provides simple and efficient communication with a Redis
|
||||
server. Some of its distinctive features are
|
||||
|
||||
@li Support for the latest version of the Redis communication protocol RESP3.
|
||||
@li Support for the latest version of the Redis communication protocol [RESP3](https://github.com/antirez/RESP3/blob/master/spec.md).
|
||||
@li First class support for STL containers and C++ built-in types.
|
||||
@li Serialization and deserialization of your own data types that avoid unnecessary copies.
|
||||
@li Sentinel support (https://redis.io/docs/manual/sentinel).
|
||||
@li Support for Redis [sentinel](https://redis.io/docs/manual/sentinel).
|
||||
@li Sync and async API.
|
||||
|
||||
In addition to that, Aedis provides a high level client that offers the following functionality
|
||||
|
||||
@li Management of message queues.
|
||||
@li Simplified handling of server pushs.
|
||||
@li Simplified handling of server pushes.
|
||||
@li Zero asymptotic allocations by means of memory reuse.
|
||||
|
||||
If you never heard about Redis the best place to start is on
|
||||
@@ -41,7 +42,7 @@
|
||||
|
||||
\section low-level-api Low-level API
|
||||
|
||||
The low-level API is very usefull for simple tasks, for example,
|
||||
The low-level API is very useful for simple tasks, for example,
|
||||
assume we want to perform the following steps
|
||||
|
||||
@li Set the value of a Redis key.
|
||||
@@ -76,7 +77,7 @@
|
||||
}
|
||||
@endcode
|
||||
|
||||
The simplicity of the code above makes it self expanatory
|
||||
The simplicity of the code above makes it self explanatory
|
||||
|
||||
@li Connect to the Redis server.
|
||||
@li Declare a \c std::string to hold the request and add some commands in it with a serializer.
|
||||
@@ -91,8 +92,8 @@
|
||||
As stated above, request are created by defining a storage object
|
||||
and a serializer that knowns how to convert user data into valid
|
||||
RESP3 wire-format. Redis request are composed of one or more
|
||||
commands (in Redis documentation they are called pipelines, see
|
||||
https://redis.io/topics/pipelining), which means users can add
|
||||
commands (in Redis documentation they are called [pipelines](https://redis.io/topics/pipelining)),
|
||||
which means users can add
|
||||
as many commands to the request as they like, a feature that aids
|
||||
performance.
|
||||
|
||||
@@ -183,7 +184,7 @@
|
||||
hgetall | Map | https://redis.io/commands/hgetall
|
||||
|
||||
Once the RESP3 type of a given response is known we can choose a
|
||||
proper C++ data structure to receive it in. Fourtunately,
|
||||
proper C++ data structure to receive it in. Fortunately,
|
||||
this is a simple task for most types, for example
|
||||
|
||||
RESP3 type | C++ | Type
|
||||
@@ -200,7 +201,7 @@
|
||||
Push | \c std::vector, \c std::map, \c std::unordered_map | Aggregate
|
||||
|
||||
Exceptions to this rule are responses that contain nested
|
||||
aggregates or heterogeneuos data types, those will be treated
|
||||
aggregates or heterogeneous data types, those will be treated
|
||||
later. As of this writing, not all RESP3 types are used by the
|
||||
Redis server, which means in practice users will be concerned with
|
||||
a reduced subset of the RESP3 specification. Now let us see some
|
||||
@@ -304,10 +305,10 @@
|
||||
co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(trans));
|
||||
@endcode
|
||||
|
||||
Note that we are not ignoring the response to the comands
|
||||
Note that we are not ignoring the response to the commands
|
||||
themselves above but whether they have been successfully queued.
|
||||
Only after @c exec is received Redis will execute them in
|
||||
sequence. The response will then be sent in a single chunck to the
|
||||
sequence. The response will then be sent in a single chunk to the
|
||||
client.
|
||||
|
||||
\subsubsection Serialization
|
||||
@@ -432,7 +433,7 @@
|
||||
@li \b Performance: Keep opening and closing connections impact performance.
|
||||
@li \b Pipeline: Code such as shown in \ref low-level-api don't
|
||||
support pipelines well since it can only send a fixed number of
|
||||
commands at time. It misses important optimization oportunities
|
||||
commands at time. It misses important optimization opportunities
|
||||
(https://redis.io/topics/pipelining).
|
||||
|
||||
To avoid these drawbacks users will address the points above
|
||||
@@ -466,25 +467,17 @@
|
||||
@code
|
||||
class receiver {
|
||||
public:
|
||||
void on_resp3(command cmd, node<boost::string_view> const& nd, boost::system::error_code& ec)
|
||||
{
|
||||
// Called when a new chunck of user data becomes available.
|
||||
}
|
||||
|
||||
void on_read(command cmd)
|
||||
{
|
||||
// Called when a response becomes available.
|
||||
}
|
||||
|
||||
void on_write(std::size_t n)
|
||||
{
|
||||
// Called when a request has been writen to the socket.
|
||||
}
|
||||
|
||||
void on_push()
|
||||
{
|
||||
// Called when a server push is received.
|
||||
}
|
||||
// Called when a new chunck of user data becomes available.
|
||||
void on_resp3(command cmd, node<boost::string_view> const& nd, boost::system::error_code& ec);
|
||||
|
||||
// Called when a response becomes available.
|
||||
void on_read(command cmd);
|
||||
|
||||
// Called when a request has been writen to the socket.
|
||||
void on_write(std::size_t n);
|
||||
|
||||
// Called when a server push is received.
|
||||
void on_push();
|
||||
};
|
||||
@endcode
|
||||
|
||||
|
||||
@@ -23,16 +23,18 @@
|
||||
namespace aedis {
|
||||
namespace generic {
|
||||
|
||||
/** \brief A high level resp3 client.
|
||||
* \ingroup any
|
||||
/** \brief A high level Redis client.
|
||||
* \ingroup any
|
||||
*
|
||||
* This class represents a connection to the Redis server. It keeps
|
||||
* an internal queue of user commands that is managed automatically.
|
||||
* It also achieves asymptotic zero allocation by reusing memory.
|
||||
* This class represents a connection to the Redis server. Some of
|
||||
* its most important features are
|
||||
*
|
||||
* It also reuses its internal buffers for requests and
|
||||
* for reading Redis responses. With time it will allocate less and
|
||||
* less.
|
||||
* 1. Automatic management of commands. The implementation will send
|
||||
* commands and read responses automatically for the user.
|
||||
* 2. Memory reuse. Dynamic memory allocations will decrease with time.
|
||||
*
|
||||
* For more details, please see the documentation of each individual
|
||||
* function.
|
||||
*/
|
||||
template <class AsyncReadWriteStream, class Command>
|
||||
class client {
|
||||
@@ -41,6 +43,209 @@ public:
|
||||
using executor_type = typename stream_type::executor_type;
|
||||
using default_completion_token_type = boost::asio::default_completion_token_t<executor_type>;
|
||||
|
||||
/** \brief Constructor.
|
||||
*
|
||||
* \param ex The executor.
|
||||
*/
|
||||
client(boost::asio::any_io_executor ex)
|
||||
: socket_{ex}
|
||||
, timer_{ex}
|
||||
{
|
||||
timer_.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
send(Command::hello, 3);
|
||||
}
|
||||
|
||||
/// Returns the executor.
|
||||
auto get_executor() {return socket_.get_executor();}
|
||||
|
||||
/** @brief Adds a command to the output command queue.
|
||||
*
|
||||
* Adds a command to the output command queue and signals the write
|
||||
* operation there are new messages awaiting to be sent to Redis.
|
||||
*
|
||||
* @sa serializer.hpp
|
||||
*
|
||||
* @param cmd The command to send.
|
||||
* @param args Arguments to commands.
|
||||
*/
|
||||
template <class... Ts>
|
||||
void send(Command cmd, Ts const&... args)
|
||||
{
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push(cmd, args...);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** @brief Adds a command to the output command queue.
|
||||
*
|
||||
* Adds a command to the output command queue and signals the write
|
||||
* operation there are new messages awaiting to be sent to Redis.
|
||||
*
|
||||
* @sa serializer.hpp
|
||||
*
|
||||
* @param cmd The command.
|
||||
* @param key The key the commands refers to
|
||||
* @param begin Begin of the range.
|
||||
* @param end End of the range.
|
||||
*/
|
||||
template <class Key, class ForwardIterator>
|
||||
void send_range2(Command cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push_range2(cmd, key, begin, end);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** @brief Adds a command to the output command queue.
|
||||
*
|
||||
* Adds a command to the output command queue and signals the write
|
||||
* operation there are new messages awaiting to be sent to Redis.
|
||||
*
|
||||
* @sa serializer.hpp
|
||||
*
|
||||
* @param cmd The command.
|
||||
* @param begin Begin of the range.
|
||||
* @param end End of the range.
|
||||
*/
|
||||
template <class ForwardIterator>
|
||||
void send_range2(Command cmd, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push_range2(cmd, begin, end);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** @brief Adds a command to the output command queue.
|
||||
*
|
||||
* Adds a command to the output command queue and signals the write
|
||||
* operation there are new messages awaiting to be sent to Redis.
|
||||
*
|
||||
* @sa serializer.hpp
|
||||
*
|
||||
* @param cmd The command.
|
||||
* @param key The key the commands refers to.
|
||||
* @param range Range of elements to send.
|
||||
*/
|
||||
template <class Key, class Range>
|
||||
void send_range(Command cmd, Key const& key, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
send_range2(cmd, key, begin(range), end(range));
|
||||
}
|
||||
|
||||
/** @brief Adds a command to the output command queue.
|
||||
*
|
||||
* Adds a command to the output command queue and signals the write
|
||||
* operation there are new messages awaiting to be sent to Redis.
|
||||
*
|
||||
* @sa serializer.hpp
|
||||
*
|
||||
* @param cmd The command.
|
||||
* @param range End of the range.
|
||||
*/
|
||||
template <class Range>
|
||||
void send_range(Command cmd, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
send_range2(cmd, begin(range), end(range));
|
||||
}
|
||||
|
||||
/** @brief Starts communication with the Redis server asynchronously.
|
||||
*
|
||||
* This class performs the following steps
|
||||
*
|
||||
* @li Connect to the endpoint passed in the function parameter.
|
||||
* @li Start the async read operation that keeps reading responses to commands and server pushes.
|
||||
* @li Start the async write operation that keeps sending commands to Redis.
|
||||
*
|
||||
* \param recv The receiver (see below)
|
||||
* \param ep The address of the Redis server.
|
||||
* \param token The completion token (ASIO jargon)
|
||||
*
|
||||
* The receiver is a class that privides the following member functions
|
||||
*
|
||||
* @code
|
||||
* class receiver {
|
||||
* public:
|
||||
* // Called when a new chunck of user data becomes available.
|
||||
* void on_resp3(command cmd, node<boost::string_view> const& nd, boost::system::error_code& ec);
|
||||
*
|
||||
* // Called when a response becomes available.
|
||||
* void on_read(command cmd);
|
||||
*
|
||||
* // Called when a request has been writen to the socket.
|
||||
* void on_write(std::size_t n);
|
||||
*
|
||||
* // Called when a server push is received.
|
||||
* void on_push();
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
template <
|
||||
class Receiver,
|
||||
class CompletionToken = default_completion_token_type
|
||||
>
|
||||
auto
|
||||
async_run(
|
||||
Receiver& recv,
|
||||
boost::asio::ip::tcp::endpoint ep = {boost::asio::ip::make_address("127.0.0.1"), 6379},
|
||||
CompletionToken token = CompletionToken{})
|
||||
{
|
||||
endpoint_ = ep;
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code)
|
||||
>(run_op<client, Receiver>{this, &recv}, token, socket_, timer_);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class T, class U, class V> friend struct read_op;
|
||||
template <class T, class U> friend struct writer_op;
|
||||
@@ -163,139 +368,6 @@ private:
|
||||
, void(boost::system::error_code)
|
||||
>(read_write_op<client, Receiver>{this, recv}, token, socket_, timer_);
|
||||
}
|
||||
public:
|
||||
/** \brief Client constructor.
|
||||
*
|
||||
* Constructos the client from an executor.
|
||||
*
|
||||
* \param ex The executor.
|
||||
*/
|
||||
client(boost::asio::any_io_executor ex)
|
||||
: socket_{ex}
|
||||
, timer_{ex}
|
||||
{
|
||||
timer_.expires_at(std::chrono::steady_clock::time_point::max());
|
||||
send(Command::hello, 3);
|
||||
}
|
||||
|
||||
/// Returns the executor used for I/O with Redis.
|
||||
auto get_executor() {return socket_.get_executor();}
|
||||
|
||||
/** \brief Adds a command to the command queue.
|
||||
*
|
||||
* \sa serializer.hpp
|
||||
*/
|
||||
template <class... Ts>
|
||||
void send(Command cmd, Ts const&... args)
|
||||
{
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push(cmd, args...);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** \brief Sends and iterator range (overload with key).
|
||||
*/
|
||||
template <class Key, class ForwardIterator>
|
||||
void send_range2(Command cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push_range2(cmd, key, begin, end);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** \brief Sends and iterator range (overload without key).
|
||||
*/
|
||||
template <class ForwardIterator>
|
||||
void send_range2(Command cmd, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
if (begin == end)
|
||||
return;
|
||||
|
||||
auto const can_write = prepare_next();
|
||||
|
||||
serializer<std::string> sr(requests_);
|
||||
auto const before = requests_.size();
|
||||
sr.push_range2(cmd, begin, end);
|
||||
auto const after = requests_.size();
|
||||
assert(after - before != 0);
|
||||
req_info_.front().size += after - before;;
|
||||
|
||||
if (!has_push_response(cmd)) {
|
||||
commands_.push_back(cmd);
|
||||
++req_info_.front().cmds;
|
||||
}
|
||||
|
||||
if (can_write)
|
||||
timer_.cancel_one();
|
||||
}
|
||||
|
||||
/** \brief Sends a range.
|
||||
*/
|
||||
template <class Key, class Range>
|
||||
void send_range(Command cmd, Key const& key, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
send_range2(cmd, key, begin(range), end(range));
|
||||
}
|
||||
|
||||
/** \brief Sends a range.
|
||||
*/
|
||||
template <class Range>
|
||||
void send_range(Command cmd, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
send_range2(cmd, begin(range), end(range));
|
||||
}
|
||||
|
||||
/** \brief Starts communication with the Redis server asynchronously.
|
||||
*/
|
||||
template <
|
||||
class Receiver,
|
||||
class CompletionToken = default_completion_token_type
|
||||
>
|
||||
auto
|
||||
async_run(
|
||||
Receiver& recv,
|
||||
boost::asio::ip::tcp::endpoint ep = {boost::asio::ip::make_address("127.0.0.1"), 6379},
|
||||
CompletionToken token = CompletionToken{})
|
||||
{
|
||||
endpoint_ = ep;
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code)
|
||||
>(run_op<client, Receiver>{this, &recv}, token, socket_, timer_);
|
||||
}
|
||||
};
|
||||
|
||||
} // generic
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace generic {
|
||||
* co_await async_write(socket, buffer(request));
|
||||
* @endcode
|
||||
*
|
||||
* \tparam Storage The storage type. This is currently a \c std::string.
|
||||
* \tparam Storage The storage type e.g \c std::string.
|
||||
* \tparam Command The command to serialize.
|
||||
*
|
||||
* \remarks Non-string types will be converted to string by using \c
|
||||
@@ -160,7 +160,9 @@ public:
|
||||
resp3::add_bulk(*request_, *begin);
|
||||
}
|
||||
|
||||
/** \brief Sends a range.
|
||||
/** @brief Appends a new command to the end of the request.
|
||||
*
|
||||
* Similar to the range version.
|
||||
*/
|
||||
template <class Command, class Key, class Range>
|
||||
void push_range(Command cmd, Key const& key, Range const& range)
|
||||
@@ -170,7 +172,9 @@ public:
|
||||
push_range2(cmd, key, begin(range), end(range));
|
||||
}
|
||||
|
||||
/** \brief Sends a range.
|
||||
/** @brief Appends a new command to the end of the request.
|
||||
*
|
||||
* Similar to the range version.
|
||||
*/
|
||||
template <class Command, class Range>
|
||||
void push_range(Command cmd, Range const& range)
|
||||
@@ -181,7 +185,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** \brief Creates a serializer for Sentinel commands.
|
||||
/** \brief Creates a serializer.
|
||||
* \ingroup any
|
||||
* \param storage The string.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,16 @@ namespace resp3 {
|
||||
*
|
||||
* Redis responses are the pre-order view of the response tree (see
|
||||
* https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR).
|
||||
*
|
||||
* The node class represent one element in the response tree. The string type
|
||||
* is a template give more flexibility, for example
|
||||
*
|
||||
* @li @c boost::string_view
|
||||
* @li @c std::string
|
||||
* @li @c boost::static_string
|
||||
*
|
||||
* \remark Any Redis response can be received in an array of nodes, for
|
||||
* example \c std::vector<node<std::string>>.
|
||||
*/
|
||||
template <class String>
|
||||
struct node {
|
||||
|
||||
@@ -179,7 +179,7 @@ STRIP_FROM_PATH =
|
||||
# specify the list of include paths that are normally passed to the compiler
|
||||
# using the -I flag.
|
||||
|
||||
STRIP_FROM_INC_PATH =
|
||||
STRIP_FROM_INC_PATH = .
|
||||
|
||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||
# less readable) file names. This can be useful is your file systems doesn't
|
||||
|
||||
Reference in New Issue
Block a user