Redis bitmaps
Introduction to Redis bitmaps
Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type which is treated like a bit vector. Since strings are binary safe blobs and their maximum length is 512 MB, they are suitable to set up to 2^32 different bits.
You can perform bitwise operations on one or more strings. Some examples of bitmap use cases include:
- Efficient set representations for cases where the members of a set correspond to the integers 0-N.
- Object permissions, where each bit represents a particular permission, similar to the way that file systems store permissions.
Basic commands
SETBIT
sets a bit at the provided offset to 0 or 1.GETBIT
returns the value of a bit at a given offset.
See the complete list of bitmap commands.
Example
Suppose you have 1000 cyclists racing through the country-side, with sensors on their bikes labeled 0-999. You want to quickly determine whether a given sensor has pinged a tracking server within the hour to check in on a rider.
You can represent this scenario using a bitmap whose key references the current hour.
- Rider 123 pings the server on January 1, 2024 within the 00:00 hour. You can then confirm that rider 123 pinged the server. You can also check to see if rider 456 has pinged the server for that same hour.
> SETBIT pings:2024-01-01-00:00 123 1
(integer) 0
> GETBIT pings:2024-01-01-00:00 123
1
> GETBIT pings:2024-01-01-00:00 456
0
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
Bit Operations
Bit operations are divided into two groups: constant-time single bit operations, like setting a bit to 1 or 0, or getting its value, and operations on groups of bits, for example counting the number of set bits in a given range of bits (e.g., population counting).
One of the biggest advantages of bitmaps is that they often provide extreme space savings when storing information. For example in a system where different users are represented by incremental user IDs, it is possible to remember a single bit information (for example, knowing whether a user wants to receive a newsletter) of 4 billion users using just 512 MB of memory.
The SETBIT
command takes as its first argument the bit number, and as its second
argument the value to set the bit to, which is 1 or 0. The command
automatically enlarges the string if the addressed bit is outside the
current string length.
GETBIT
just returns the value of the bit at the specified index.
Out of range bits (addressing a bit that is outside the length of the string
stored into the target key) are always considered to be zero.
There are three commands operating on group of bits:
BITOP
performs bit-wise operations between different strings. The provided operators areAND
,OR
,XOR
,NOT
,DIFF
,DIFF1
,ANDOR
, andONE
.BITCOUNT
performs population counting, reporting the number of bits set to 1.BITPOS
finds the first bit having the specified value of 0 or 1.
Both BITPOS
and BITCOUNT
are able to operate with byte ranges of the
string, instead of running for the whole length of the string. We can trivially see the number of bits that have been set in a bitmap.
> BITCOUNT pings:2024-01-01-00:00
(integer) 1
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
For example imagine you want to know the longest streak of daily visits of
your web site users. You start counting days starting from zero, that is the
day you made your web site public, and set a bit with SETBIT
every time
the user visits the web site. As a bit index you simply take the current unix
time, subtract the initial offset, and divide by the number of seconds in a day
(normally, 3600*24).
This way for each user you have a small string containing the visit
information for each day. With BITCOUNT
it is possible to easily get
the number of days a given user visited the web site, while with
a few BITPOS
calls, or simply fetching and analyzing the bitmap client-side,
it is possible to easily compute the longest streak.
Bitwise operations
The BITOP
command performs bitwise
operations over two or more source keys, storing the result in a destination key.
The examples below show the available operations using three keys: A
(with bit pattern
11011000
), B
(00011001
), and C
(01101100
).
Numbering the bits from left to right, starting at zero, the following SETBIT
commands
will create these bitmaps:
> SETBIT A 0 1
(integer) 0
> SETBIT A 1 1
(integer) 0
> SETBIT A 3 1
(integer) 0
> SETBIT A 4 1
(integer) 0
> GET A
"\xd8"
# Hex value: 0xd8 = 0b11011000
> SETBIT B 3 1
(integer) 0
> SETBIT B 4 1
(integer) 0
> SETBIT B 7 1
(integer) 0
> GET B
"\x19"
# Hex value: 0x19 = 0b00011001
> SETBIT C 1 1
(integer) 0
> SETBIT C 2 1
(integer) 0
> SETBIT C 4 1
(integer) 0
> SETBIT C 5 1
(integer) 0
> GET C
"l"
# ASCII "l" = hex 0x6c = 0b01101100
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
AND
Set a bit in the destination key to 1 only if it is set in all the source keys.
> BITOP AND R A B C
(integer) 1
> GET R
"\b"
# ASCII "\b" (backspace) = hex 0x08 = 0b00001000
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
OR
Set a bit in the destination key to 1 if it is set in at least one of the source keys.
> BITOP OR R A B C
(integer) 1
> GET R
"\xfd"
# Hex value: 0xfd = 0b11111101
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
XOR
For two source keys, set a bit in the destination key to 1 if the value of the bit is different in the two keys. For three or more source keys, the result of XORing the first two keys is then XORed with the next key, and so forth.
> BITOP XOR R A B
(integer) 1
> GET R
"\xc1"
# Hex value: 0xc1 = 0b11000001
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
NOT
Set a bit in the destination key to 1 if it is not set in the source key (this is the only unary operator).
> BITOP NOT R A
(integer) 1
> GET R
"'"
# ASCII "'" (single quote) = hex 0x27 = 0b00100111
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
DIFF
Set a bit in the destination key to 1 if it is set in the first source key, but not in any of the other source keys.
> BITOP DIFF R A B C
(integer) 1
> GET R
"\x80"
# Hex value: 0x80 = 0b10000000
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
DIFF1
Set a bit in the destination key to 1 if it is not set in the first source key, but set in at least one of the other source keys.
> BITOP DIFF1 R A B C
(integer) 1
> GET R
"%"
# ASCII "%" (percent) = hex 0x25 = 0b00100101
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
ANDOR
Set a bit in the destination key to 1 if it is set in the first source key and also in at least one of the other source keys.
> BITOP ANDOR R A B C
(integer) 1
> GET R
"X"
# ASCII "X" = hex 0x58 = 0b01011000
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
ONE
Set a bit in the destination key to 1 if it is set in exactly one of the source keys.
> BITOP ONE R A B C
(integer) 1
> GET R
"\xa5"
# Hex value: 0xa5 = 0b10100101
"""
Code samples for Bitmap doc pages:
https://redis.io/docs/latest/develop/data-types/bitmaps/
"""
import redis
# Connect without the usual `decode_responses=True` to
# see the binary values in the responses more easily.
r = redis.Redis()
res1 = r.setbit("pings:2024-01-01-00:00", 123, 1)
print(res1) # >>> 0
res2 = r.getbit("pings:2024-01-01-00:00", 123)
print(res2) # >>> 1
res3 = r.getbit("pings:2024-01-01-00:00", 456)
print(res3) # >>> 0
r.setbit("pings:2024-01-01-00:00", 123, 1)
res4 = r.bitcount("pings:2024-01-01-00:00")
print(res4) # >>> 1
r.setbit("A", 0, 1)
r.setbit("A", 1, 1)
r.setbit("A", 3, 1)
r.setbit("A", 4, 1)
res5 = r.get("A")
print("{:08b}".format(int.from_bytes(res5, "big")))
# >>> 11011000
r.setbit("B", 3, 1)
r.setbit("B", 4, 1)
r.setbit("B", 7, 1)
res6 = r.get("B")
print("{:08b}".format(int.from_bytes(res6, "big")))
# >>> 00011001
r.setbit("C", 1, 1)
r.setbit("C", 2, 1)
r.setbit("C", 4, 1)
r.setbit("C", 5, 1)
res7 = r.get("C")
print("{:08b}".format(int.from_bytes(res7, "big")))
# >>> 01101100
r.bitop("AND", "R", "A", "B", "C")
res8 = r.get("R")
print("{:08b}".format(int.from_bytes(res8, "big")))
# >>> 00001000
r.bitop("OR", "R", "A", "B", "C")
res9 = r.get("R")
print("{:08b}".format(int.from_bytes(res9, "big")))
# >>> 11111101
r.bitop("XOR", "R", "A", "B")
res10 = r.get("R")
print("{:08b}".format(int.from_bytes(res10, "big")))
# >>> 11000001
r.bitop("NOT", "R", "A")
res11 = r.get("R")
print("{:08b}".format(int.from_bytes(res11, "big")))
# >>> 00100111
r.bitop("DIFF", "R", "A", "B", "C")
res12 = r.get("R")
print("{:08b}".format(int.from_bytes(res12, "big")))
# >>> 10000000
r.bitop("DIFF1", "R", "A", "B", "C")
res13 = r.get("R")
print("{:08b}".format(int.from_bytes(res13, "big")))
# >>> 00100101
r.bitop("ANDOR", "R", "A", "B", "C")
res14 = r.get("R")
print("{:08b}".format(int.from_bytes(res14, "big")))
# >>> 01011000
r.bitop("ONE", "R", "A", "B", "C")
res15 = r.get("R")
print("{:08b}".format(int.from_bytes(res15, "big")))
# >>> 10100101
import { createClient, RESP_TYPES } from 'redis';
const client = createClient({
commandOptions: {
typeMapping: {
[RESP_TYPES.BLOB_STRING]: Buffer
}
}
});
await client.connect();
const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1)
console.log(res1) // >>> 0
const res2 = await client.getBit("pings:2024-01-01-00:00", 123)
console.log(res2) // >>> 1
const res3 = await client.getBit("pings:2024-01-01-00:00", 456)
console.log(res3) // >>> 0
await client.setBit("pings:2024-01-01-00:00", 123, 1)
const res4 = await client.bitCount("pings:2024-01-01-00:00")
console.log(res4) // >>> 1
await client.setBit("A", 0, 1)
await client.setBit("A", 1, 1)
await client.setBit("A", 3, 1)
await client.setBit("A", 4, 1)
const res5 = await client.get("A")
console.log(res5.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11011000
await client.setBit("B", 3, 1)
await client.setBit("B", 4, 1)
await client.setBit("B", 7, 1)
const res6 = await client.get("B")
console.log(res6.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00011001
await client.setBit("C", 1, 1)
await client.setBit("C", 2, 1)
await client.setBit("C", 4, 1)
await client.setBit("C", 5, 1)
const res7 = await client.get("C")
console.log(res7.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01101100
await client.bitOp("AND", "R", ["A", "B", "C"])
const res8 = await client.get("R")
console.log(res8.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00001000
await client.bitOp("OR", "R", ["A", "B", "C"])
const res9 = await client.get("R")
console.log(res9.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11111101
await client.bitOp("XOR", "R", ["A", "B"]) // XOR uses two keys here
const res10 = await client.get("R")
console.log(res10.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 11000001
await client.bitOp("NOT", "R", "A")
const res11 = await client.get("R")
console.log(res11.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100111
await client.bitOp("DIFF", "R", ["A", "B", "C"])
const res12 = await client.get("R")
console.log(res12.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10000000
await client.bitOp("DIFF1", "R", ["A", "B", "C"])
const res13 = await client.get("R")
console.log(res13.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 00100101
await client.bitOp("ANDOR", "R", ["A", "B", "C"])
const res14 = await client.get("R")
console.log(res14.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 01011000
await client.bitOp("ONE", "R", ["A", "B", "C"])
const res15 = await client.get("R")
console.log(res15.readUInt8(0).toString(2).padStart(8, '0'))
// >>> 10100101
package io.redis.examples;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.args.BitOP;
public class BitMapsExample {
public void run() {
UnifiedJedis jedis = new UnifiedJedis("redis://localhost:6379");
boolean res1 = jedis.setbit("pings:2024-01-01-00:00", 123, true);
System.out.println(res1); // >>> false
boolean res2 = jedis.getbit("pings:2024-01-01-00:00", 123);
System.out.println(res2); // >>> true
boolean res3 = jedis.getbit("pings:2024-01-01-00:00", 456);
System.out.println(res3); // >>> false
long res4 = jedis.bitcount("pings:2024-01-01-00:00");
System.out.println(res4); // >>> 1
jedis.setbit("A", 0, true);
jedis.setbit("A", 1, true);
jedis.setbit("A", 3, true);
jedis.setbit("A", 4, true);
byte[] res5 = jedis.get("A".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res5[0] & 0xFF)).replace(' ', '0'));
// >>> 11011000
jedis.setbit("B", 3, true);
jedis.setbit("B", 4, true);
jedis.setbit("B", 7, true);
byte[] res6 = jedis.get("B".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res6[0] & 0xFF)).replace(' ', '0'));
// >>> 00011001
jedis.setbit("C", 1, true);
jedis.setbit("C", 2, true);
jedis.setbit("C", 4, true);
jedis.setbit("C", 5, true);
byte[] res7 = jedis.get("C".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res7[0] & 0xFF)).replace(' ', '0'));
// >>> 01101100
jedis.bitop(BitOP.AND, "R", "A", "B", "C");
byte[] res8 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res8[0] & 0xFF)).replace(' ', '0'));
// >>> 00001000
jedis.bitop(BitOP.OR, "R", "A", "B", "C");
byte[] res9 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res9[0] & 0xFF)).replace(' ', '0'));
// >>> 11111101
jedis.bitop(BitOP.XOR, "R", "A", "B");
byte[] res10 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res10[0] & 0xFF)).replace(' ', '0'));
// >>> 11000001
jedis.bitop(BitOP.NOT, "R", "A");
byte[] res11 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res11[0] & 0xFF)).replace(' ', '0'));
// >>> 00100111
jedis.bitop(BitOP.DIFF, "R", "A", "B", "C");
byte[] res12 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res12[0] & 0xFF)).replace(' ', '0'));
// >>> 10000000
jedis.bitop(BitOP.DIFF1, "R", "A", "B", "C");
byte[] res13 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res13[0] & 0xFF)).replace(' ', '0'));
// >>> 00100101
jedis.bitop(BitOP.ANDOR, "R", "A", "B", "C");
byte[] res14 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res14[0] & 0xFF)).replace(' ', '0'));
// >>> 01011000
jedis.bitop(BitOP.ONE, "R", "A", "B", "C");
byte[] res15 = jedis.get("R".getBytes());
System.out.println(String.format("%8s", Integer.toBinaryString(res15[0] & 0xFF)).replace(' ', '0'));
// >>> 10100101
jedis.close();
}
}
package io.redis.examples.async;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import java.util.concurrent.CompletableFuture;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisAsyncCommands<String, String> async = connection.async();
RedisAsyncCommands<byte[], byte[]> asyncBytes = bytesConnection.async();
CompletableFuture<Void> ping = async.setbit("pings:2024-01-01-00:00", 123, 1).thenCompose(res1 -> {
System.out.println(res1); // >>> 0
return async.getbit("pings:2024-01-01-00:00", 123);
}).thenCompose(res2 -> {
System.out.println(res2); // >>> 1
return async.getbit("pings:2024-01-01-00:00", 456);
}).thenAccept(res3 -> {
System.out.println(res3); // >>> 0
}).toCompletableFuture();
ping.join();
CompletableFuture<Void> bitcount = async.bitcount("pings:2024-01-01-00:00").thenAccept(res4 -> {
System.out.println(res4); // >>> 1
}).toCompletableFuture();
bitcount.join();
CompletableFuture<Void> setup = async.setbit("A", 0, 1).thenCompose(v -> async.setbit("A", 1, 1))
.thenCompose(v -> async.setbit("A", 3, 1)).thenCompose(v -> async.setbit("A", 4, 1))
.thenCompose(v -> async.setbit("B", 3, 1)).thenCompose(v -> async.setbit("B", 4, 1))
.thenCompose(v -> async.setbit("B", 7, 1)).thenCompose(v -> async.setbit("C", 1, 1))
.thenCompose(v -> async.setbit("C", 2, 1)).thenCompose(v -> async.setbit("C", 4, 1))
.thenCompose(v -> async.setbit("C", 5, 1)).thenCompose(v -> asyncBytes.get("A".getBytes()))
.thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
return bitsA;
}).thenCompose(v -> asyncBytes.get("B".getBytes())).thenApply(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
return bitsB;
})
// Print C
.thenCompose(v -> asyncBytes.get("C".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).toCompletableFuture();
setup.join();
CompletableFuture<Void> andOp = async.bitopAnd("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).toCompletableFuture();
andOp.join();
CompletableFuture<Void> orOp = async.bitopOr("R", "A", "B", "C").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).toCompletableFuture();
orOp.join();
CompletableFuture<Void> xorOp = async.bitopXor("R", "A", "B").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).toCompletableFuture();
xorOp.join();
CompletableFuture<Void> notOp = async.bitopNot("R", "A").thenCompose(len -> asyncBytes.get("R".getBytes()))
.thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).toCompletableFuture();
notOp.join();
CompletableFuture<Void> diffOp = async.bitopDiff("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).toCompletableFuture();
diffOp.join();
CompletableFuture<Void> diff1Op = async.bitopDiff1("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).toCompletableFuture();
diff1Op.join();
CompletableFuture<Void> andorOp = async.bitopAndor("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).toCompletableFuture();
andorOp.join();
CompletableFuture<Void> oneOp = async.bitopOne("R", "A", "B", "C")
.thenCompose(len -> asyncBytes.get("R".getBytes())).thenAccept(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).toCompletableFuture();
oneOp.join();
} finally {
redisClient.shutdown();
}
}
}
package io.redis.examples.reactive;
import io.lettuce.core.*;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.codec.ByteArrayCodec;
import reactor.core.publisher.Mono;
public class BitmapExample {
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
try (StatefulRedisConnection<String, String> connection = redisClient.connect();
StatefulRedisConnection<byte[], byte[]> bytesConnection = redisClient.connect(ByteArrayCodec.INSTANCE)) {
RedisReactiveCommands<String, String> reactive = connection.reactive();
RedisReactiveCommands<byte[], byte[]> reactiveBytes = bytesConnection.reactive();
Mono<Void> ping = reactive.setbit("pings:2024-01-01-00:00", 123, 1).doOnNext(res1 -> {
System.out.println(res1); // >>> 0
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 123)).doOnNext(res2 -> {
System.out.println(res2); // >>> 1
}).flatMap(v -> reactive.getbit("pings:2024-01-01-00:00", 456)).doOnNext(res3 -> {
System.out.println(res3); // >>> 0
}).then();
ping.block();
Mono<Void> bitcount = reactive.bitcount("pings:2024-01-01-00:00").doOnNext(res4 -> {
System.out.println(res4); // >>> 1
}).then();
bitcount.block();
Mono<Void> setup = reactive.setbit("A", 0, 1).then(reactive.setbit("A", 1, 1)).then(reactive.setbit("A", 3, 1))
.then(reactive.setbit("A", 4, 1)).then(reactive.setbit("B", 3, 1)).then(reactive.setbit("B", 4, 1))
.then(reactive.setbit("B", 7, 1)).then(reactive.setbit("C", 1, 1)).then(reactive.setbit("C", 2, 1))
.then(reactive.setbit("C", 4, 1)).then(reactive.setbit("C", 5, 1)).then(reactiveBytes.get("A".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsA = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsA); // >>> 11011000
}).then(reactiveBytes.get("B".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsB = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsB); // >>> 00011001
}).then(reactiveBytes.get("C".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bitsC = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bitsC); // >>> 01101100
}).then();
setup.block();
Mono<Void> andOp = reactive.bitopAnd("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00001000
}).then();
andOp.block();
Mono<Void> orOp = reactive.bitopOr("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11111101
}).then();
orOp.block();
Mono<Void> xorOp = reactive.bitopXor("R", "A", "B").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 11000001
}).then();
xorOp.block();
Mono<Void> notOp = reactive.bitopNot("R", "A").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100111
}).then();
notOp.block();
Mono<Void> diffOp = reactive.bitopDiff("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10000000
}).then();
diffOp.block();
Mono<Void> diff1Op = reactive.bitopDiff1("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 00100101
}).then();
diff1Op.block();
Mono<Void> andorOp = reactive.bitopAndor("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes()))
.doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 01011000
}).then();
andorOp.block();
Mono<Void> oneOp = reactive.bitopOne("R", "A", "B", "C").then(reactiveBytes.get("R".getBytes())).doOnNext(res -> {
byte b = (res != null && res.length > 0) ? res[0] : 0;
String bits = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
System.out.println(bits); // >>> 10100101
}).then();
oneOp.block();
} finally {
redisClient.shutdown();
}
}
}
package example_commands_test
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func ExampleClient_ping() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res1, err := rdb.SetBit(ctx, "pings:2024-01-01-00:00", 123, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res1) // >>> 0
res2, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 123).Result()
if err != nil {
panic(err)
}
fmt.Println(res2) // >>> 1
res3, err := rdb.GetBit(ctx, "pings:2024-01-01-00:00", 456).Result()
if err != nil {
panic(err)
}
fmt.Println(res3) // >>> 0
}
func ExampleClient_bitcount() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
res4, err := rdb.BitCount(ctx, "pings:2024-01-01-00:00",
&redis.BitCount{
Start: 0,
End: 456,
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res4) // >>> 1
}
func ExampleClient_bitop_setup() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
ba, _ := rdb.Get(ctx, "A").Bytes()
fmt.Printf("%08b\n", ba[0])
// >>> 11011000
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
bb, _ := rdb.Get(ctx, "B").Bytes()
fmt.Printf("%08b\n", bb[0])
// >>> 00011001
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
bc, _ := rdb.Get(ctx, "C").Bytes()
fmt.Printf("%08b\n", bc[0])
// >>> 01101100
}
func ExampleClient_bitop_ops() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
rdb.SetBit(ctx, "A", 0, 1)
rdb.SetBit(ctx, "A", 1, 1)
rdb.SetBit(ctx, "A", 3, 1)
rdb.SetBit(ctx, "A", 4, 1)
rdb.SetBit(ctx, "B", 3, 1)
rdb.SetBit(ctx, "B", 4, 1)
rdb.SetBit(ctx, "B", 7, 1)
rdb.SetBit(ctx, "C", 1, 1)
rdb.SetBit(ctx, "C", 2, 1)
rdb.SetBit(ctx, "C", 4, 1)
rdb.SetBit(ctx, "C", 5, 1)
rdb.BitOpAnd(ctx, "R", "A", "B", "C")
br, _ := rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00001000
rdb.BitOpOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11111101
rdb.BitOpXor(ctx, "R", "A", "B")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 11000001
rdb.BitOpNot(ctx, "R", "A")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100111
rdb.BitOpDiff(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10000000
rdb.BitOpDiff1(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 00100101
rdb.BitOpAndOr(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 01011000
rdb.BitOpOne(ctx, "R", "A", "B", "C")
br, _ = rdb.Get(ctx, "R").Bytes()
fmt.Printf("%08b\n", br[0])
// >>> 10100101
}
using StackExchange.Redis;
public class BitmapTutorial
{
public void Run()
{
var muxer = ConnectionMultiplexer.Connect("localhost:6379");
var db = muxer.GetDatabase();
bool res1 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
Console.WriteLine(res1); // >>> 0
bool res2 = db.StringGetBit("pings:2024-01-01-00:00", 123);
Console.WriteLine(res2); // >>> True
bool res3 = db.StringGetBit("pings:2024-01-01-00:00", 456);
Console.WriteLine(res3); // >>> False
// Tests for 'ping' step.
bool res4 = db.StringSetBit("pings:2024-01-01-00:00", 123, true);
long res5 = db.StringBitCount("pings:2024-01-01-00:00");
Console.WriteLine(res5); // >>> 1
// Tests for 'bitcount' step.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
// Bitwise operations are not supported in NRedisStack.
}
}
<?php
require 'vendor/autoload.php';
use Predis\Client as PredisClient;
class DtBitmapTest
{
public function testDtBitmap() {
$r = new PredisClient([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'database' => 0,
]);
$res1 = $r->setbit('pings:2024-01-01-00:00', 123, 1);
echo $res1 . PHP_EOL;
// >>> 0
$res2 = $r->getbit('pings:2024-01-01-00:00', 123);
echo $res2 . PHP_EOL;
// >>> 1
$res3 = $r->getbit('pings:2024-01-01-00:00', 456);
echo $res3 . PHP_EOL;
// >>> 0
// Ensure the bit is set
$r->setbit('pings:2024-01-01-00:00', 123, 1);
$res4 = $r->bitcount('pings:2024-01-01-00:00');
echo $res4 . PHP_EOL;
// >>> 1
$r->setbit('A', 0, 1);
$r->setbit('A', 1, 1);
$r->setbit('A', 3, 1);
$r->setbit('A', 4, 1);
$res5 = $r->get('A');
echo str_pad(decbin(ord($res5)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11011000
$r->setbit('B', 3, 1);
$r->setbit('B', 4, 1);
$r->setbit('B', 7, 1);
$res6 = $r->get('B');
echo str_pad(decbin(ord($res6)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00011001
$r->setbit('C', 1, 1);
$r->setbit('C', 2, 1);
$r->setbit('C', 4, 1);
$r->setbit('C', 5, 1);
$res7 = $r->get('C');
echo str_pad(decbin(ord($res7)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01101100
$r->bitop('AND', 'R', 'A', 'B', 'C');
$res8 = $r->get('R');
echo str_pad(decbin(ord($res8)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00001000
$r->bitop('OR', 'R', 'A', 'B', 'C');
$res9 = $r->get('R');
echo str_pad(decbin(ord($res9)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11111101
$r->bitop('XOR', 'R', 'A', 'B');
$res10 = $r->get('R');
echo str_pad(decbin(ord($res10)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 11000001
$r->bitop('NOT', 'R', 'A');
$res11 = $r->get('R');
echo str_pad(decbin(ord($res11)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100111
$r->bitop('DIFF', 'R', 'A', 'B', 'C');
$res12 = $r->get('R');
echo str_pad(decbin(ord($res12)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10000000
$r->bitop('DIFF1', 'R', 'A', 'B', 'C');
$res13 = $r->get('R');
echo str_pad(decbin(ord($res13)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 00100101
$r->bitop('ANDOR', 'R', 'A', 'B', 'C');
$res14 = $r->get('R');
echo str_pad(decbin(ord($res14)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 01011000
$r->bitop('ONE', 'R', 'A', 'B', 'C');
$res15 = $r->get('R');
echo str_pad(decbin(ord($res15)), 8, '0', STR_PAD_LEFT) . PHP_EOL;
// >>> 10100101
}
}
Split bitmaps into multiple keys
Bitmaps are trivial to split into multiple keys, for example for
the sake of sharding the data set and because in general it is better to
avoid working with huge keys. To split a bitmap across different keys
instead of setting all the bits into a key, a trivial strategy is just
to store M bits per key and obtain the key name with bit-number/M
and
the Nth bit to address inside the key with bit-number MOD M
.
Performance
SETBIT
and GETBIT
are O(1).
BITOP
is O(n), where n is the length of the longest string in the comparison.
Learn more
- Redis Bitmaps Explained teaches you how to use bitmaps for map exploration in an online game.
- Redis University's RU101 covers Redis bitmaps in detail.