Working with Redis Bitmaps

Exploring Bitmaps in Redis

Welcome back! In this lesson, we dive into another advanced data structure in Redis: bitmaps. This lesson fits perfectly into our series as it continues to explore specialized data structures that enable powerful and efficient data handling.

What You'll Learn

In this lesson, you will gain insights into bitmaps in Redis, a data structure that allows you to manipulate individual bits within a string. Specifically, you will learn:

  1. How to set and get bits in a bitmap using Redis commands with Boost.Redis.
  2. Practical applications of bitmaps, such as tracking user statuses.
  3. How to batch multiple bitmap operations and handle their responses asynchronously.

Setting and Getting Bits in Bitmaps

To give you a taste, let's look at a simple example of setting and getting bits in a bitmap:

C++
#include <boost/redis.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/consign.hpp>
#include <iostream>

#include <boost/redis/src.hpp>

namespace net = boost::asio;
using boost::redis::connection;
using boost::redis::config;
using boost::redis::logger;
using boost::redis::request;
using boost::redis::response;

int main() {
    try {
        net::io_context ioc;

        auto conn = std::make_shared<connection>(ioc.get_executor());

        config cfg;
        conn->async_run(cfg, logger{logger::level::disabled},
                        net::consign(net::detached, conn));

        request req;
        req.push("SETBIT", "user_active", "0", "1");
        req.push("SETBIT", "user_active", "1", "1");
        req.push("SETBIT", "user_active", "2", "0");
        req.push("GETBIT", "user_active", "0");
        req.push("GETBIT", "user_active", "2");

        response<std::int64_t, std::int64_t, std::int64_t, std::int64_t, std::int64_t> resp;

        conn->async_exec(req, resp,
            [conn, &resp](boost::system::error_code ec, std::size_t) {
                if (!ec) {
                    const auto& user0_active = std::get<3>(resp);
                    const auto& user2_active = std::get<4>(resp);

                    if (user0_active && user2_active) {
                        std::cout << "User 0 active: " << user0_active.value()
                                  << ", User 2 active: " << user2_active.value() << "\n";
                    }
                } else {
                    std::cerr << "Error executing Redis commands: " << ec.message() << "\n";
                }
                conn->cancel();
            });

        ioc.run();
    } catch (const std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
        return 1;
    }
    return 0;
}

Let's break down the code snippet:

  • After setting up the connection (using io_context, connection, and async_run as you've seen in previous lessons), we create a request object to batch our bitmap commands.
  • We add commands to the request using req.push():
    • SETBIT to set the bit at index 0 to 1 in the user_active bitmap.
    • SETBIT to set the bit at index 1 to 1.
    • SETBIT to set the bit at index 2 to 0.
    • GETBIT to retrieve the bit at index 0.
    • GETBIT to retrieve the bit at index 2.
  • We define a response tuple that will hold the results of all five commands. Each SETBIT and GETBIT command returns an std::int64_t value.
  • We execute all commands asynchronously with async_exec, providing a callback that processes the results:
    • We check for errors using the error_code parameter.
    • We use std::get<3>(resp) and std::get<4>(resp) to access the fourth and fifth responses (the two GETBIT results, since indices start at 0).
    • We verify that the optional values contain data before accessing them with .value().
    • Finally, we print the results: User 0 active: 1, User 2 active: 0.

Note that if you set a value other than 0 or 1, it will be converted to 1 before setting the bit. For example, req.push("SETBIT", "user_active", "2", "2") will set the bit at index 2 to 1 — in other words, bitmaps are binary data structures that can only store 0 or 1.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal