From aee55387d60e875abc5d2507497f506daad965d7 Mon Sep 17 00:00:00 2001 From: Kenny Helsens Date: Thu, 28 Feb 2013 22:00:30 +0100 Subject: [PATCH] added support for SETBIT, GETBIT, BITCOUNT and BITOP commands --- R/bitops.R | 48 +++++++++++++++++++++++++++++++++++++++++++++++ test/bitopTest.R | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 R/bitops.R create mode 100644 test/bitopTest.R diff --git a/R/bitops.R b/R/bitops.R new file mode 100644 index 0000000..cb9b793 --- /dev/null +++ b/R/bitops.R @@ -0,0 +1,48 @@ +#' @title Redis BITSET - set binary value +#' @description Sets or clears the bit at offset in the string value stored at key. +#' @param key redis key +#' @param offset integer index to be updated +#' @param bit binary number to be set +#' @return bit binary number with previous value, or '0' if it had not been set before. +#' @detail Official redis documentation: http://redis.io/commands/setbit +redisSetBit <- function(key, offset, bit) +{ + .redisCmd(.raw('SETBIT'), .raw(key), .raw(as.character(offset)), .raw(as.character(bit))) +} + + +#' @title Redis BITSET gets - get binary value +#' @description Returns the bit value at offset in the string value stored at key. +#' @param key redis key +#' @param offset integer index +#' @return bit binary integer +#' @detail Official redis documentation: http://redis.io/commands/getbit +redisGetBit <- function(key, offset) +{ + .redisCmd(.raw('GETBIT'), .raw(key), .raw(as.character(offset))) +} + + +#' @title Redis BITCOUNT - count all bits in key +#' @description Count the number of set bits (population counting) in a string. +#' @param key redis key +#' @return the counted bits as an integer value +#' @detail Official redis documentation: http://redis.io/commands/bitcount +redisBitCount <- function(key) +{ + .redisCmd(.raw('BITCOUNT'), .raw(key)) +} + + +#' @title Redis BITOP - execute bitoperations on multiple bitsets +#' @description Perform a bitwise operation between multiple keys (containing string values) and store the result in the destination key +#' @param operation bit operation as character: 'AND', 'OR', 'XOR', 'NOT' +#' @param destkey destination key where the resulting bit operation will be stored +#' @param sourcekeys one or more source keys subject to the bit operations +#' @return the counted bits as an integer value +#' @detail Official redis documentation: http://redis.io/commands/bitop +redisBitOp <- function(operation, destkey, sourcekeys) +{ + sets <- c(as.list(sourcekeys)) + do.call('.redisCmd',lapply(c(list('BITOP'),operation, destkey, sets),charToRaw)) +} diff --git a/test/bitopTest.R b/test/bitopTest.R new file mode 100644 index 0000000..e3720f8 --- /dev/null +++ b/test/bitopTest.R @@ -0,0 +1,49 @@ +test01_connect <- function() { + redisConnect() + if(!is.null(redisKeys("bitmapr_test*"))){ + redisDelete(redisKeys("bitmapr_test*")) + } +} + +test02_getsetbit <- function() { + redisSetBit('bitmapr_test02', 10, 1) + checkEquals(1, redisGetBit('bitmapr_test02', 10)) +} + + +test03_bitcount <- function() { + redisSetBit('bitmapr_test03', 1, 1) + redisSetBit('bitmapr_test03', 10, 1) + redisSetBit('bitmapr_test03', 100, 1) + checkEquals(3, redisBitCount('bitmapr_test03')) +} + +test04_bitops <- function() { + + sourcekeys <- c('bitmapr_test04_src_1', 'bitmapr_test04_src_2','bitmapr_test04_src_3') + + redisSetBit(sourcekeys[1], 1, 1) + redisSetBit(sourcekeys[1], 2, 1) + redisSetBit(sourcekeys[1], 3, 1) + redisSetBit(sourcekeys[1], 100, 1) + + redisSetBit(sourcekeys[2], 1, 1) + redisSetBit(sourcekeys[2], 4, 1) + redisSetBit(sourcekeys[2], 5, 1) + redisSetBit(sourcekeys[2], 100, 1) + + redisSetBit(sourcekeys[3], 1, 1) + redisSetBit(sourcekeys[3], 6, 1) + redisSetBit(sourcekeys[3], 7, 1) + redisSetBit(sourcekeys[3], 100, 1) + + # id 1 and 100 are present in all keys. + operation <- 'AND' + destkey <- 'bitmapr_test04_dest' + + redisBitOp(operation, destkey, sourcekeys) + checkEquals(2, redisBitCount(destkey)) + checkEquals(0, redisGetBit(destkey, 5)) + checkEquals(1, redisGetBit(destkey, 1)) + +}