GitHub - wingunder/redis-plus-plus-modules: This library aims to supply a C++ interface to all major/popular Redis modules. (original) (raw)

redis-plus-plus-modules

Introduction

This library aims to supply a C++ interface to all major/popular Redis modules. It uses redis-plus-plus, which in turn uses hiredis.

The following Redis Modules are fully implemented:

The following Redis Modules are in the process of being implemented:

Motivation

After using redis-plus-plusfor a while, one simply gets addicted to the ease of having proper interfaces to Redis commands. These interfaces save a lot of boiler-plate code and therefore a lot of time, and that's why I decided to write this library.

Design

The goal of this library is to useredis-plus-plus andhiredis with no modification. These two projects are included as git submodules and are built as part of the finalredis-plus-plus-moduleslibrary.

redis-plus-plus-modulesis a C++ library in the form of C++ headers, containing C++ template classes. This means that there is no library to link with. The only requirement is that one or more of the desired header files are included:

This Class Diagram was generated by Doxygen:Class Diagram, generated with Doxygen

Building

GNU/Automake is used as building tool and g++ is used for building.

git clone https://github.com/wingunder/redis-plus-plus-modules.git cd redis-plus-plus-modules ./bootstrap.sh ./configure make -j8

Tests can be performed by running:

Quickstart

Quickstart using Docker

The fastest way to get started, is to simply useDocker and docker-compose. ADockerfileand a simpledocker-compose.ymlfile is supplied.

Optionally you could start off, by building the Docker image called rppm (short for redis-plus-plus-modules). This step is not needed, but just demostrates that building a pure Docker image of this library is possible.

$ docker build . -t rppm:0

For running applications inside Docker, you need to use docker-compose. The following demonstrates the running of the unit tests and some examples, inside Docker.

$ docker-compose up -d Starting redis-plus-plus-modules_redis_1 ... done Starting redis-plus-plus-modules_test_1 ... done Creating redis-plus-plus-modules_multi_info_1 ... done Creating redis-plus-plus-modules_single_info_1 ... done

To view the logs of the test example, simply run:

$ docker-compose logs test

To view the logs of the singleInfo example, simply run:

$ docker-compose logs single_info Attaching to redis-plus-plus-modules_single_info_1 single_info_1 | make: Entering directory '/usr/src/redis-plus-plus-modules/examples/singleInfo' single_info_1 | g++ -I../../include -L../../lib -o singleInfo singleInfo.cpp -lhiredis -lredis++ -lpthread single_info_1 | make: Leaving directory '/usr/src/redis-plus-plus-modules/examples/singleInfo' single_info_1 | Expansion rate: 2 single_info_1 | Number of items inserted: 0 single_info_1 | Capacity: 100 single_info_1 | Number of filters: 1 single_info_1 | Size: 232

To view the logs of the multiInfo example, simply run:

$ docker-compose logs multi_info Attaching to redis-plus-plus-modules_multi_info_1 multi_info_1 | make: Entering directory '/usr/src/redis-plus-plus-modules/examples/multiInfo' multi_info_1 | g++ -I../../include -L../../lib -o multiInfo multiInfo.cpp -lhiredis -lredis++ -lpthread multi_info_1 | make: Leaving directory '/usr/src/redis-plus-plus-modules/examples/multiInfo' multi_info_1 | Expansion rate: 2 multi_info_1 | Number of items inserted: 0 multi_info_1 | Capacity: 100 multi_info_1 | Number of filters: 1 multi_info_1 | Size: 232 multi_info_1 | Max iterations: 0 multi_info_1 | Expansion rate: 1 multi_info_1 | Number of buckets: 16 multi_info_1 | Number of filters: 1 multi_info_1 | Number of items inserted: 0 multi_info_1 | Number of items deleted: 0 multi_info_1 | Size: 216 multi_info_1 | Bucket size: 10

You can now use the docker-compose.yml file and beef it up with your own application(s).

Quickstart without using Docker

First of all you'll need to have access to a Redis database with the_loaded_ module(s) that you'd like to program against.

Once your Redis database is set up and running, you can run theMODULE LIST command on it, in order to see if the modules are available:

$ redis-cli MODULE LIST

    1. "name"
    2. "ai"
    3. "ver"
    4. (integer) 10002
    1. "name"
    2. "ReJSON"
    3. "ver"
    4. (integer) 10007
    1. "name"
    2. "bf"
    3. "ver"
    4. (integer) 20205
    1. "name"
    2. "search"
    3. "ver"
    4. (integer) 20006
    1. "name"
    2. "timeseries"
    3. "ver"
    4. (integer) 10408
    1. "name"
    2. "rg"
    3. "ver"
    4. (integer) 10006
    1. "name"
    2. "graph"
    3. "ver"
    4. (integer) 20402

In the above example, 7 modules are available. The 3rd module, BloomFilter (bf), supplies BloomFilter (BF), CuckooFilter (CF), Count-Min-Sketch (CMS) and Top-K (TOPK).

The ./test directory contains test cases for all implemented API calls. In order to run the tests, simply run:

If you have gotten this far and the test succeeded, we can continue with a simple example. For the impatient, just look at thisexample and the other examples in the examples directory.

We're going to create a Redis instance, using redis-plus-plus:

#include #include <redismods++/BloomFilter.h>

int main() {

// Setup the connection options.
sw::redis::ConnectionOptions opts;
opts.host = "127.0.0.1";
opts.port = 6379;
opts.password = "";

// Choose the instance type.
using RedisInstance = sw::redis::Redis;
// use RedisInstance = sw::redis::RedisCluster;

// Create a redis-plus-plus object.
RedisInstance redis(opts);

// Create a BloomFilter object.
redis::module::BloomFilter<RedisInstance> bloomFilter(redis);

getInfo<RedisInstance>("some_test_key", bloomFilter, redis);

return 0;

}

Now we'll implement the getInfo() template function. BTW, it needs to be a template function, as we're keeping the option open to use it on non-clustered, as well as clustered Redis servers.

#include

template void getInfo(const std::string &key, redis::module::BloomFilter &bloomFilter, RedisInstance &redis) { // Make sure the key does not exist. // Note: The BloomFilter object does not have a 'del' call, // so we need to call the native redis 'DEL' command // via the underlying redis-plus-plus lib. redis.del(key);

// Create a BloomFilter.
bloomFilter.reserve(key, 0.1, 100, false);

// Prepare the output buffer.
std::unordered_map<std::string, sw::redis::OptionalLongLong> output;
bloomFilter.info(key, output);

// Print the result.
for (auto &item : output) {
    std::cout << item.first << ": ";
    if (item.second) {
        std::cout << *item.second;
    }
    else {
        std::cout << "nil";
    }
    std::cout << std::endl;
}

// Clean up.
redis.del(key);

}

We now need to compile it. Note that we need to link with the hiredis, redis++ and pthread libraries. The hiredis and redis++ libraries are installed in the ${REDIS_PLUS_PLUS_MODULES_DIR}/lib directory. All include files are in the ${REDIS_PLUS_PLUS_MODULES_DIR}/includedirectory.

$ g++ -I${REDIS_PLUS_PLUS_MODULES_DIR}/include -L${REDIS_PLUS_PLUS_MODULES_DIR}/lib -o singleInfo singleInfo.cpp -lhiredis -lredis++ -lpthread

Finally, we can run it:

$ LD_LIBRARY_PATH=$REDIS_PLUS_PLUS_MODULES_DIR/lib ./singleInfo Expansion rate: 2 Number of items inserted: 0 Size: 232 Number of filters: 1 Capacity: 100

Code Documentation

A Doxygen configuration file,DoxyFile is included, so you can simply install Doxygen and run it:

The above should create an html and latex directory, where you can find the generated Doxygen output files.

APIs

NOTE: This project is still under heavy development. Although a lot of effort will go into keeping the API stable, it is not guaranteed.

RedisBloom API Documentation

TODO

Contributing

Contributions are very welcome. Also please feel free to open issues and post reviews.

Authors

The initial version ofredis-plus-plus-moduleswas written by wingunder. Some ideas and code originate fromsewenew and his amazingredis-plus-plus library.

This software is copyrighted under Apache License V2.0.

History

This project was started during the RedisConf 2021 hackathlon.