Skip to content

Commit

Permalink
Add syntax highlighting for some code
Browse files Browse the repository at this point in the history
Add syntax highlighting for some code
  • Loading branch information
wincsb authored May 17, 2022
1 parent 68d5db9 commit 46d2e2a
Showing 1 changed file with 45 additions and 45 deletions.
90 changes: 45 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Normally, you can install *hiredis* with a C++ package manager, and that's the e

Note again: DO NOT INSTALL MULTIPLE VERSIONS OF HIREDIS.

```
```shell
git clone https://github.com/redis/hiredis.git

cd hiredis
Expand All @@ -81,7 +81,7 @@ make install

By default, *hiredis* is installed at */usr/local*. If you want to install *hiredis* at non-default location, use the following commands to specify the installation path.

```
```shell
make PREFIX=/non/default/path

make PREFIX=/non/default/path install
Expand All @@ -91,7 +91,7 @@ make PREFIX=/non/default/path install

*redis-plus-plus* is built with [CMAKE](https://cmake.org).

```
```shell
git clone https://github.com/sewenew/redis-plus-plus.git

cd redis-plus-plus
Expand All @@ -111,21 +111,21 @@ cd ..

If *hiredis* is installed at non-default location, you should use `CMAKE_PREFIX_PATH` to specify the installation path of *hiredis*. By default, *redis-plus-plus* is installed at */usr/local*. However, you can use `CMAKE_INSTALL_PREFIX` to install *redis-plus-plus* at non-default location.

```
```shell
cmake -DCMAKE_PREFIX_PATH=/path/to/hiredis -DCMAKE_INSTALL_PREFIX=/path/to/install/redis-plus-plus ..
```

Since version 1.3.0, by default, *redis-plus-plus* is built with the `-std=c++17` standard. So that we can use the [std::string_view](#stringview) and [std::optional](#optional) features. However, it can also be built with the `-std=c++11` or `-std=c++14` standard, and in that case, we have our own simple implementation of `std::string_view` and `std::optional`. In order to explicitly specify c++ standard, you can use the following cmake flag: `-DREDIS_PLUS_PLUS_CXX_STANDARD=11`.

```
```shell
cmake -DCMAKE_PREFIX_PATH=/path/to/hiredis -DCMAKE_INSTALL_PREFIX=/path/to/install/redis-plus-plus -DREDIS_PLUS_PLUS_CXX_STANDARD=11 ..
```

**NOTE**: You should build *redis-plus-plus* and your application with the same standard, e.g. if you build *redis-plus-plus* with C++17 standard, you MUST also build your application code with C++17 standard.

When compiling *redis-plus-plus*, it also compiles a test program, which might take a while. However, you can disable building test with the following cmake option: `-DREDIS_PLUS_PLUS_BUILD_TEST=OFF`.

```
```shell
cmake -DCMAKE_PREFIX_PATH=/path/to/hiredis -DCMAKE_INSTALL_PREFIX=/path/to/install/redis-plus-plus -DREDIS_PLUS_PLUS_BUILD_TEST=OFF ..
```

Expand All @@ -152,7 +152,7 @@ The following are some links on how to build CMake project with Visual Studio 20

First of all, you need to get the latest code of *hiredis* on master branch. Older version might not support Windows platform. *hiredis*' CMakeLists.txt uses `add_compile_definitions` method, which is only supported by cmake 3.12 or later. However, Visual Studio 2017's cmake version is older than that. So if you're using Visual Studio 2017, you need to comment the following line in the CMakeLists.txt file:

```
```cmake
#IF(WIN32)
# ADD_COMPILE_DEFINITIONS(_CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN)
#ENDIF()
Expand All @@ -164,7 +164,7 @@ You can use the **Open Folder** feature to open *hiredis* project, and build it

Since *redis-plus-plus* depends on *hiredis*, we need to specify the installation paths of *hiredis* before building it. You can use the **Open Folder** feature to open *redis-plus-plus* project. You need to edit the *CMakeSetting.json* file (automatically generated by Visual Studio) to set *HIREDIS_HEADER*, *HIREDIS_LIB* and *TEST_HIREDIS_LIB* variables to specify the installation path of hiredis headers, installation path of hiredis dynamic library and installation path of hiredis static library. The following is an example of *CMakeSetting.json* file:

```
```json
{
"configurations": [
{
Expand Down Expand Up @@ -212,15 +212,15 @@ On Windows platform, if your application code also needs to include *windows.h*.
Basic support for building a GNU/Debian package is supplied with the use of cmake.
The following example shows how to build the Debian package:

```
```shell
mkdir build; cd build
cmake ..
cpack -G DEB
```

The install prefix may be modified as follows:

```
```shell
mkdir build; cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
cpack -G DEB
Expand All @@ -230,7 +230,7 @@ cpack -G DEB

*redis-plus-plus* has been fully tested with the following compilers:

```
```shell
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
gcc version 5.5.0 20171010 (Ubuntu 5.5.0-12ubuntu1)
gcc version 6.5.0 20181026 (Ubuntu 6.5.0-2ubuntu1~18.04)
Expand Down Expand Up @@ -259,7 +259,7 @@ In order to run the tests, you need to set up a Redis instance, and a Redis Clus

In order to run tests with both Redis and Redis Cluster, you can run the test program with the following command:

```
```shell
./build/test/test_redis++ -h host -p port -a auth -n cluster_node -c cluster_port
```

Expand All @@ -269,25 +269,25 @@ In order to run tests with both Redis and Redis Cluster, you can run the test pr

If you only want to run tests with Redis, you only need to specify *host*, *port* and *auth* options:

```
```shell
./build/test/test_redis++ -h host -p port -a auth
```

Similarly, if you only want to run tests with Redis Cluster, just specify *cluster_node*, *cluster_port* and *auth* options:

```
```shell
./build/test/test_redis++ -a auth -n cluster_node -c cluster_port
```

By default, the test program will not test running *redis-plus-plus* in multi-threads environment. If you want to do multi-threads test, which might cost a long time, you can specify the *-m* option:

```
```shell
./build/test/test_redis++ -h host -p port -a auth -n cluster_node -c cluster_port -m
```

If all tests have been passed, the test program will print the following message:

```
```shell
Pass all tests
```

Expand All @@ -297,7 +297,7 @@ Otherwise, it prints the error message.

*redis-plus-plus* runs as fast as *hiredis*, since it's a wrapper of *hiredis*. You can run *test_redis++* in benchmark mode to check the performance in your environment.

```
```shell
./build/test/test_redis++ -h host -p port -a auth -n cluster_node -c cluster_port -b -t thread_num -s connection_pool_size -r request_num -k key_len -v val_len
```

Expand All @@ -318,37 +318,37 @@ After compiling the code, you'll get both shared library and static library. Sin

Take gcc as an example.

```
```shell
g++ -std=c++17 -o app app.cpp /path/to/libredis++.a /path/to/libhiredis.a -pthread
```

If *hiredis* and *redis-plus-plus* are installed at non-default location, you should use `-I` option to specify the header path.

```
```shell
g++ -std=c++17 -I/non-default/install/include/path -o app app.cpp /path/to/libredis++.a /path/to/libhiredis.a -pthread
```

#### Use Shared Libraries

```
```shell
g++ -std=c++17 -o app app.cpp -lredis++ -lhiredis -pthread
```

If *hiredis* and *redis-plus-plus* are installed at non-default location, you should use `-I` and `-L` options to specify the header and library paths.

```
```shell
g++ -std=c++17 -I/non-default/install/include/path -L/non-default/install/lib/path -o app app.cpp -lredis++ -lhiredis -pthread
```

When linking with shared libraries, and running your application, you might get the following error message:

```
```shell
error while loading shared libraries: xxx: cannot open shared object file: No such file or directory.
```
That's because the linker cannot find the shared libraries. In order to solve the problem, you can add the path where you installed *hiredis* and *redis-plus-plus* libraries, to `LD_LIBRARY_PATH` environment variable. For example:
```
```shell
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
```
Expand Down Expand Up @@ -771,23 +771,23 @@ for (auto idx = 0; idx < 100; ++idx) {
When building *hiredis* with TLS support, you need to download *hiredis* of version *v1.0.0* or latter, and specify `USE_SSL=1` flag:
```
```shell
make PREFIX=/non/default/path USE_SSL=1
make PREFIX=/non/default/path USE_SSL=1 install
```
Then you can build *redis-plus-plus* to enable TLS support by specifying the `-DREDIS_PLUS_PLUS_USE_TLS=ON` option:
```
```shell
cmake -DREDIS_PLUS_PLUS_USE_TLS=ON ..
```
##### Connection Options
In order to connect to Redis with TLS support, you need to specify the following connection options:
```
```c++
ConnectionOptions opts;
opts.host = "127.0.0.1";
opts.port = 6379;
Expand Down Expand Up @@ -953,7 +953,7 @@ using OptionalStringPair = Optional<std::pair<std::string, std::string>>;
[std::variant](https://en.cppreference.com/w/cpp/utility/variant) is a good option for return type, if the reply might be of different types. For example, the `MEMORY STATS` command returns an array reply, which is, in fact, a map of key-value pairs of configurations:
```
```shell
127.0.0.1:6379> memory stats
1) "peak.allocated"
2) (integer) 4471104
Expand All @@ -973,7 +973,7 @@ However, as you can see, the value part of the result might be of type long long
In this case, `Variant`, which is a typedef of `std::variant` if you build redis-plus-plus with C++17 standard, is very helpful. You can parse the result into a `std::unordered_map<std::string, Variant<double, long long, std::unordered_map<std::string, long long>>>`.
```
```c++
using Var = Variant<double, long long, std::unordered_map<std::string, long long>>;
auto r = Redis("tcp://127.0.0.1");
auto v = r.command<std::unordered_map<std::string, Var>>("memory", "stats");
Expand All @@ -990,7 +990,7 @@ Also check the [generic command section](https://github.com/sewenew/redis-plus-p
When using generic command interface, instead of parsing the reply to output iterator, you can also parse it into a STL container.
```
```c++
auto r = Redis("tcp://127.0.0.1");
auto v = r.command<std::unordered_map<std::string, std::string>>("config", "get", "*");
```
Expand Down Expand Up @@ -1343,7 +1343,7 @@ Normally, when exception happens, you don't need to create a `Redis` object. It'
The following is an example on how to catch these exceptions:
```
```c++
try {
redis.set("key", "value");
Expand Down Expand Up @@ -1502,7 +1502,7 @@ When you subscribe to a channel with a connection, all messages published to the
If you want to have different connection options, e.g. `ConnectionOptions::socket_timeout`, for different channels, you should create `Redis` objects with different connection options, then you can create `Subscriber` objects with these `Redis` objects. Check [this issue](https://github.com/sewenew/redis-plus-plus/issues/307#issuecomment-1002015671) for a use case.
```
```c++
ConnectionOptions opts1;
opts1.host = "127.0.0.1";
opts1.port = 6379;
Expand Down Expand Up @@ -1705,7 +1705,7 @@ In fact, you can also create a `Pipeline` object with a connection from the unde
The prototype of `Redis::pipeline` is as follows: `Pipeline pipeline(bool new_connection = true);`. If `new_connection` is false, the `Pipeline` object will be created with a connection from the underlying pool.
```
```c++
ConnectionOptions connection_options;
ConnectionPoolOptions pool_options;
Expand All @@ -1721,7 +1721,7 @@ However, in this case, you MUST be very careful, otherwise, you might get bad pe
Check the following dead lock example:
```
```c++
// By defaul, create a `Redis` object with only ONE connection in pool.
// Also by default, the `ConnectionPoolOptions::wait_timeout` is 0ms,
// which means if the pool is empty, `Redis` method will be blocked until
Expand Down Expand Up @@ -1759,7 +1759,7 @@ When creating `Pipeline` without creating a new connection:
- Better chain `Pipeline` methods and the `Pipeline::exec` in one statements.
- Better leave `Pipeline` related code in a block scope.
```
```c++
ConnectionOptions opts;
opts.host = "127.0.0.1";
opts.port = 6379;
Expand Down Expand Up @@ -1945,7 +1945,7 @@ In fact, you can also create a `transaction` object with a connection from the u
The prototype of `Redis::transaction` is as follows: `Transaction transaction(bool piped = false, bool new_connection = true);`. If `new_connection` is false, the `Transaction` object will be created with a connection from the underlying pool.
```
```c++
ConnectionOptions connection_options;
ConnectionPoolOptions pool_options;
Expand Down Expand Up @@ -2387,7 +2387,7 @@ You must install *libuv*(e.g. *apt-get install libuv1-dev*) before install *hire
When installing *redis-plus-plus*, you should specify the following command line option: `-DREDIS_PLUS_PLUS_BUILD_ASYNC=libuv`.
```
```shell
cmake -DCMAKE_PREFIX_PATH=/installation/path/to/libuv/and/hiredis -DREDIS_PLUS_PLUS_BUILD_ASYNC=libuv ..
make
Expand All @@ -2401,7 +2401,7 @@ The async interface is similar to sync interface, except that you should include
**NOTE**: When building your application code, don't forget to link libuv.
```
```c++
#include <sw/redis++/async_redis++.h>
ConnectionOptions opts;
Expand Down Expand Up @@ -2452,7 +2452,7 @@ if (val) {
Aysnc interface also supports Redis Sentinel.
```
```c++
#include <sw/redis++/async_redis++.h>
SentinelOptions sentinel_opts;
Expand Down Expand Up @@ -2491,7 +2491,7 @@ The async support for sentinel is similar with the sync one, except that you nee
Aysnc interface also supports Redis Cluster. Instead of `AsyncRedis`, you need to create an `AsyncRedisCluster` object.
```
```c++
ConnectionOptions opts;
opts.host = "127.0.0.1";
opts.port = 6379;
Expand Down Expand Up @@ -2533,7 +2533,7 @@ You can use `AsyncSubscriber` to subscribe to channels or patterns asynchronousl
The following example is a common pattern to use `AsyncSubscriber`:
```
```c++
// Create an `AsyncSubscriber`. You can create it with either an `AsyncRedis` or `AsyncRedisCluster` object.
auto sub = async_redis.subscriber();
Expand Down Expand Up @@ -2571,7 +2571,7 @@ Future<void> fut2 = sub.psubscribe("pattern1*");
By default, `AsyncRedis` and `AsyncRedisCluster` create a default event loop, and runs the loop in a dedicated thread to handle read and write operations. However, you can also share the underlying event loop with multiple `AsyncRedis` and `AsyncRedisCluster` objects. In order to do that, you need to create a `std::shared_ptr<EventLoop>`, and pass it to the constructors of `AsyncRedis` and `AsyncRedisCluster`.
```
```c++
auto event_loop = std::make_shared<EventLoop>();
auto redis = AsyncRedis(connection_opts, pool_opts, loop);
Expand All @@ -2585,15 +2585,15 @@ Unfortunately, `std::future` doesn't support [continuation](https://en.cpprefere
By default, *redis-plus-plus* returns `std::future` for async interface. However, you can also make it return `boost::future` by specifying `-DREDIS_PLUS_PLUS_ASYNC_FUTURE=boost` when running cmake (`folly` and other libraries might be supported in the future). Of course, in this case, you need to install Boost first (the minimum version requirement for Boost is **1.55.0**).
```
```shell
cmake -DREDIS_PLUS_PLUS_BUILD_ASYNC=libuv -DREDIS_PLUS_PLUS_ASYNC_FUTURE=boost ..
```
**NOTE**: When building your application code, don't forget to link boost related libs, e.g. -lboost_thread, -lboost_system.
Then you can take advantage of `boost::future`'s continuation support:
```
```c++
#include <sw/redis++/async_redis++.h>
ConnectionOptions opts;
Expand All @@ -2612,7 +2612,7 @@ fut.get();
You can also use a thread pool to run the continuation:
```
```c++
#define BOOST_THREAD_PROVIDES_EXECUTORS
// You might also need to `#define BOOST_THREAD_USES_MOVE` with some version of Boost.
Expand Down Expand Up @@ -2645,7 +2645,7 @@ We can create many interesting data structures and algorithms based on Redis, su
#### Examples
```
```c++
auto redis1 = Redis("tcp://127.0.0.1:7000");
auto redis2 = Redis("tcp://127.0.0.1:7001");
auto redis3 = Redis("tcp://127.0.0.1:7002");
Expand Down

0 comments on commit 46d2e2a

Please sign in to comment.