├── .Rbuildignore ├── NAMESPACE ├── vignettes ├── rredis.pdf └── rredis.Rnw ├── tests ├── 00prototype.R ├── script.R ├── hyperloglogTest.R ├── hash.R ├── list.R ├── zsetTest.R ├── setTest.R ├── bitopTest.R ├── pubsub.R ├── misc.R └── basicTest.R ├── DESCRIPTION ├── man ├── redisDiscard.Rd ├── redisBitCount.Rd ├── redisUnwatch.Rd ├── redisSave.Rd ├── redisZScore.Rd ├── redisBgSave.Rd ├── redisGetBit.Rd ├── redisMulti.Rd ├── redisExec.Rd ├── redisSetBit.Rd ├── redisShutdown.Rd ├── redisFlushDB.Rd ├── redisFlushAll.Rd ├── redisZAdd.Rd ├── redisZRem.Rd ├── redisWatch.Rd ├── redisZCard.Rd ├── redisInfo.Rd ├── redisDBSize.Rd ├── redisZIncrBy.Rd ├── redisHDel.Rd ├── redisAuth.Rd ├── redisHExists.Rd ├── redisSCard.Rd ├── redisSIsMember.Rd ├── redisRandomKey.Rd ├── redisSMove.Rd ├── redisDelete.Rd ├── redisHLen.Rd ├── redisSMembers.Rd ├── redisZRank.Rd ├── redisExists.Rd ├── redisBitOp.Rd ├── redisSRandMember.Rd ├── redisLLen.Rd ├── redisKeys.Rd ├── redisSelect.Rd ├── redisHKeys.Rd ├── redisSRem.Rd ├── redisHVals.Rd ├── redisLSet.Rd ├── redisSPop.Rd ├── redisHFields.Rd ├── redisCmd.Rd ├── redisPersist.Rd ├── redisZCount.Rd ├── redisZRemRangeByRank.Rd ├── redisZRemRangeByScore.Rd ├── redisMSet.Rd ├── redisClose.Rd ├── redisHGetAll.Rd ├── redisMGet.Rd ├── redisHMSet.Rd ├── redisRPop.Rd ├── redisRename.Rd ├── redisHGet.Rd ├── redisBgRewriteAOF.Rd ├── redisTTL.Rd ├── redisSAdd.Rd ├── redisMove.Rd ├── redisHMGet.Rd ├── redisLPush.Rd ├── redisLPop.Rd ├── redisLIndex.Rd ├── redisLTrim.Rd ├── redisExpireAt.Rd ├── redisEval.Rd ├── redisExpire.Rd ├── redisSUnion.Rd ├── redisSDiff.Rd ├── redisLRange.Rd ├── redisSUnionStore.Rd ├── redisSDiffStore.Rd ├── redisSInterStore.Rd ├── redisSInter.Rd ├── rredis-package.Rd ├── redisHIncrBy.Rd ├── redisZUnionStore.Rd ├── redisZInterStore.Rd ├── redisType.Rd ├── redisLRem.Rd ├── redisBLPop.Rd ├── redisBRPop.Rd ├── redisSetPipeline.Rd ├── redisZRangeByScore.Rd ├── redisGet.Rd ├── redisSlaveOf.Rd ├── redisSet.Rd ├── redisGetSet.Rd ├── redisHSet.Rd ├── redisSort.Rd ├── redisZRange.Rd ├── incr.Rd ├── redisRPopLPush.Rd ├── redisPublish.Rd ├── redisSetContext.Rd ├── redisBRPopLPush.Rd ├── redisGetResponse.Rd ├── redisConnect.Rd ├── redisSubscribe.Rd ├── redisUnsubscribe.Rd ├── redisMonitorChannels.Rd └── hyperloglog.Rd ├── R ├── scriptCMD.R ├── hyperloglog.R ├── bitops.R ├── pubsub.R ├── strValCMD.R ├── hashCMD.R ├── setVal.R ├── allValCMD.R ├── listCMD.R ├── controlCMD.R ├── zsetVal.R └── redis-internal.R ├── NEWS └── README.md /.Rbuildignore: -------------------------------------------------------------------------------- 1 | .travis.yml 2 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | exportPattern("^[[:alpha:]]+") 2 | -------------------------------------------------------------------------------- /vignettes/rredis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bwlewis/rredis/HEAD/vignettes/rredis.pdf -------------------------------------------------------------------------------- /tests/00prototype.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | # Put tests here 10 | redisFlushAll() 11 | } 12 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rredis 2 | Type: Package 3 | Title: "Redis" Key/Value Database Client 4 | Version: 1.7.2 5 | Date: 2022-1-3 6 | Author: B. W. Lewis 7 | Maintainer: B. W. Lewis 8 | Description: R client interface to the "Redis" key-value database. 9 | License: Apache License (>= 2.0) 10 | LazyLoad: yes 11 | -------------------------------------------------------------------------------- /tests/script.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | checkEquals("OK", redisEval("return redis.call('set','foo','bar')")) 10 | redisFlushAll() 11 | } 12 | -------------------------------------------------------------------------------- /man/redisDiscard.Rd: -------------------------------------------------------------------------------- 1 | \name{redisDiscard} 2 | \alias{redisDiscard} 3 | \title{redisDiscard} 4 | \description{Discard the current transaction block.} 5 | \usage{ 6 | redisDiscard() 7 | } 8 | \details{Discard the current transaction block. 9 | } 10 | \value{"OK"} 11 | \references{ 12 | http://redis.io/commands 13 | } 14 | \author{ 15 | B. W. Lewis 16 | } 17 | -------------------------------------------------------------------------------- /R/scriptCMD.R: -------------------------------------------------------------------------------- 1 | # Run a Redis Lua script 2 | redisEval <- function(script, keys=vector("list",0), SHA=FALSE, ...) 3 | { 4 | if(!is.list(keys)) keys = list(keys) 5 | numkeys = length(keys) 6 | if(numkeys>0) keys = as.character(keys) 7 | CMD = ifelse(SHA,"EVALSHA","EVAL") 8 | do.call("redisCmd", args=c(list(CMD, script, as.character(numkeys)),keys,list(...))) 9 | } 10 | -------------------------------------------------------------------------------- /man/redisBitCount.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBitCount} 2 | \alias{redisBitCount} 3 | \title{Redis BITCOUNT - count all bits in key} 4 | \usage{ 5 | redisBitCount(key) 6 | } 7 | \arguments{ 8 | \item{key}{redis key} 9 | } 10 | \value{ 11 | the counted bits as an integer value 12 | } 13 | \description{ 14 | Count the number of set bits (population counting) in a 15 | string. 16 | } 17 | 18 | -------------------------------------------------------------------------------- /man/redisUnwatch.Rd: -------------------------------------------------------------------------------- 1 | \name{redisUnwatch} 2 | \alias{redisUnwatch} 3 | \title{redisUnwatch} 4 | \description{Stop watching for keys to change.} 5 | \usage{ 6 | redisUnwatch() 7 | } 8 | \details{ 9 | Stop watching all watched keys. See \code{\link{redisWatch}} for details. 10 | } 11 | \value{"OK"} 12 | \references{ 13 | http://redis.io/commands 14 | } 15 | \author{ 16 | B. W. Lewis 17 | } 18 | -------------------------------------------------------------------------------- /man/redisSave.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSave} 2 | \alias{redisSave} 3 | \title{redisSave} 4 | \description{Synchronously save that database to disk. 5 | } 6 | \usage{ 7 | redisSave() 8 | } 9 | \details{Force Redis to save the database(s) to disk. 10 | } 11 | \value{Nothing is returned. Check the UNIX time of the last completed 12 | save operation with the redisLastsave function. 13 | } 14 | \references{ 15 | http://redis.io/commands 16 | } 17 | \author{ 18 | B. W. Lewis 19 | } 20 | -------------------------------------------------------------------------------- /man/redisZScore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZScore} 2 | \alias{redisZScore} 3 | \title{ 4 | redisZScore 5 | } 6 | \description{ 7 | Return the score of an ordered set element. 8 | } 9 | \usage{ 10 | redisZScore(key, element) 11 | } 12 | \arguments{ 13 | \item{key}{ 14 | The set name. 15 | } 16 | \item{element}{ 17 | The set element. 18 | } 19 | } 20 | \value{ 21 | The numeric score. 22 | } 23 | \references{ 24 | http://redis.io/commands 25 | } 26 | \author{ 27 | B. W. Lewis 28 | } 29 | -------------------------------------------------------------------------------- /man/redisBgSave.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBgSave} 2 | \alias{redisBgSave} 3 | \title{redisBgSave} 4 | \description{Asynchronously save that database to disk. 5 | } 6 | \usage{ 7 | redisBgSave() 8 | } 9 | \details{Force Redis to save the database(s) to disk in the background. 10 | } 11 | \value{Nothing is returned. Check the UNIX time of the last completed 12 | save operation with the redisLastsave function. 13 | } 14 | \references{ 15 | http://redis.io/commands 16 | } 17 | \author{ 18 | B. W. Lewis 19 | } 20 | -------------------------------------------------------------------------------- /R/hyperloglog.R: -------------------------------------------------------------------------------- 1 | # Redis Hyperloglog functions 2 | 3 | redisPfadd <- function(key, elements) 4 | { 5 | do.call(.redisCmd, lapply(c(list('PFADD'), as.list(key), as.list(elements)), charToRaw)) 6 | } 7 | 8 | redisPfcount <- function(keys) 9 | { 10 | do.call(.redisCmd, lapply(c(list('PFCOUNT'), as.list(keys)), charToRaw)) 11 | } 12 | 13 | redisPfmerge <- function(destkey, sourcekeys) 14 | { 15 | do.call(.redisCmd, lapply(c(list('PFMERGE'), as.list(destkey), as.list(sourcekeys)), charToRaw)) 16 | } 17 | -------------------------------------------------------------------------------- /man/redisGetBit.Rd: -------------------------------------------------------------------------------- 1 | \name{redisGetBit} 2 | \alias{redisGetBit} 3 | \title{Redis BITSET gets - get binary value} 4 | \usage{ 5 | redisGetBit(key, offset, ...) 6 | } 7 | \arguments{ 8 | \item{key}{redis key} 9 | \item{offset}{integer index} 10 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 11 | } 12 | \value{ 13 | bit binary integer 14 | } 15 | \description{ 16 | Returns the bit value at offset in the string value 17 | stored at key. 18 | } 19 | -------------------------------------------------------------------------------- /man/redisMulti.Rd: -------------------------------------------------------------------------------- 1 | \name{redisMulti} 2 | \alias{redisMulti} 3 | \title{redisMulti} 4 | \description{Start a transaction block.} 5 | \usage{ 6 | redisMulti() 7 | } 8 | \details{Begin a transaction block. All Redis statements issued after 9 | \code{redisMulti} will be queued locally and then sent to the Redis 10 | server en masse once the \code{redisExec} function is issued. 11 | } 12 | \value{"OK" indicates the transaction has begun.} 13 | \references{ 14 | http://redis.io/commands 15 | } 16 | \author{ 17 | B. W. Lewis 18 | } 19 | -------------------------------------------------------------------------------- /man/redisExec.Rd: -------------------------------------------------------------------------------- 1 | \name{redisExec} 2 | \alias{redisExec} 3 | \title{redisExec} 4 | \description{End a transaction block.} 5 | \usage{ 6 | redisExec() 7 | } 8 | \details{End a transaction block. All Redis statements issued after 9 | \code{redisMulti} will be queued locally and then sent to the Redis 10 | server en masse once the \code{redisExec} function is issued. 11 | } 12 | \value{The results of all queued functions are returned in a list.} 13 | \references{ 14 | http://redis.io/commands 15 | } 16 | \author{ 17 | B. W. Lewis 18 | } 19 | -------------------------------------------------------------------------------- /man/redisSetBit.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSetBit} 2 | \alias{redisSetBit} 3 | \title{Redis BITSET - set binary value} 4 | \usage{ 5 | redisSetBit(key, offset, bit) 6 | } 7 | \arguments{ 8 | \item{key}{redis key} 9 | 10 | \item{offset}{integer index to be updated} 11 | 12 | \item{bit}{binary number to be set} 13 | } 14 | \value{ 15 | bit binary number with previous value, or '0' if it had 16 | not been set before. 17 | } 18 | \description{ 19 | Sets or clears the bit at offset in the string value 20 | stored at key. 21 | } 22 | 23 | -------------------------------------------------------------------------------- /man/redisShutdown.Rd: -------------------------------------------------------------------------------- 1 | \name{redisShutdown} 2 | \alias{redisShutdown} 3 | \title{redisShutdown} 4 | \description{ 5 | Request the currently currently connected Redis server to shutdown, then 6 | close the connection. 7 | } 8 | \usage{ 9 | redisShutdown() 10 | } 11 | \details{ 12 | This will terminate the connected Redis server process in an orderly way. 13 | } 14 | \value{ 15 | Nothing is returned. An error is thrown if no server is connected. 16 | } 17 | \references{ 18 | http://redis.io/commands 19 | } 20 | \author{ 21 | B. W. Lewis 22 | } 23 | -------------------------------------------------------------------------------- /man/redisFlushDB.Rd: -------------------------------------------------------------------------------- 1 | \name{redisFlushDB} 2 | \alias{redisFlushDB} 3 | \title{Delete all keys and values from the current database.} 4 | \description{ 5 | Delete all keys and values from the currently selected database.} 6 | \usage{ 7 | redisFlushDB() 8 | } 9 | \value{Returns TRUE if successful, FALSE otherwise. 10 | } 11 | \references{ 12 | http://redis.io/commands 13 | } 14 | \author{ 15 | B. W. Lewis 16 | } 17 | \seealso{ 18 | \code{\link{redisFlushAll}} 19 | } 20 | \examples{ 21 | \dontrun{ 22 | redisConnect() 23 | redisFlushDB() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /man/redisFlushAll.Rd: -------------------------------------------------------------------------------- 1 | \name{redisFlushAll} 2 | \alias{redisFlushAll} 3 | \title{Delete all keys and values from all databases.} 4 | \description{ 5 | Delete all keys and values from all databases, not just the currently selected 6 | one.} 7 | \usage{ 8 | redisFlushAll() 9 | } 10 | \value{Returns TRUE if successful, FALSE otherwise. 11 | } 12 | \references{ 13 | http://redis.io/commands 14 | } 15 | \author{ 16 | B. W. Lewis 17 | } 18 | \seealso{ 19 | \code{\link{redisFlushDB}} 20 | } 21 | \examples{ 22 | \dontrun{ 23 | redisConnect() 24 | redisFlushAll() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /man/redisZAdd.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZAdd} 2 | \alias{redisZAdd} 3 | \title{ 4 | redisZAdd 5 | } 6 | \description{ 7 | Add an element to a Redis sorted set. Sorted sets order their elements 8 | by numeric weights. 9 | } 10 | \usage{ 11 | redisZAdd(key, score, member) 12 | } 13 | \arguments{ 14 | \item{key}{ 15 | The set name. 16 | } 17 | \item{score}{ 18 | The numeric score associated with the new element (member). 19 | } 20 | \item{member}{ 21 | The new object to add to the set. 22 | } 23 | } 24 | \references{ 25 | http://redis.io/commands 26 | } 27 | \author{ 28 | B. W. Lewis 29 | } 30 | -------------------------------------------------------------------------------- /man/redisZRem.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRem} 2 | \alias{redisZRem} 3 | \title{ 4 | redisZRem 5 | } 6 | \description{ 7 | Delete an element from an ordered set. 8 | } 9 | \usage{ 10 | redisZRem(key, member) 11 | } 12 | \arguments{ 13 | \item{key}{ 14 | The set name. 15 | } 16 | \item{member}{ 17 | The element to delete. 18 | } 19 | } 20 | \details{ 21 | See the Redis documentation for details. 22 | } 23 | \value{ 24 | 0 or 1: 0 indicates that the element could not be removed, 1 that it was removed. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | -------------------------------------------------------------------------------- /man/redisWatch.Rd: -------------------------------------------------------------------------------- 1 | \name{redisWatch} 2 | \alias{redisWatch} 3 | \title{redisWatch} 4 | \description{Condition a transaction block on value changes.} 5 | \usage{ 6 | redisWatch(keys) 7 | } 8 | \arguments{ 9 | \item{keys}{A character vector or list of key names to watch for changes.} 10 | } 11 | \details{ 12 | Watch the specified keys for changed values. If any of the values change 13 | for the watched keys, discard the current transaction block and unwatch 14 | all watched keys. 15 | } 16 | \value{"OK"} 17 | \references{ 18 | http://redis.io/commands 19 | } 20 | \author{ 21 | B. W. Lewis 22 | } 23 | -------------------------------------------------------------------------------- /man/redisZCard.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZCard} 2 | \alias{redisZCard} 3 | \title{ 4 | redisZCard.Rd 5 | } 6 | \description{ 7 | Report the number of elements in a sorted set. 8 | } 9 | \usage{ 10 | redisZCard(key) 11 | } 12 | \arguments{ 13 | \item{key}{ 14 | The name of the set. 15 | } 16 | } 17 | \details{ 18 | See the Redis documentation for details. 19 | } 20 | \value{ 21 | The number of elements in the set or zero if the set does not exist. 22 | An error is thrown if the key name exists but is not a set. 23 | } 24 | \references{ 25 | http://redis.io/commands 26 | } 27 | \author{ 28 | B. W. Lewis 29 | } 30 | -------------------------------------------------------------------------------- /R/bitops.R: -------------------------------------------------------------------------------- 1 | redisSetBit <- function(key, offset, bit) 2 | { 3 | .redisCmd(.raw('SETBIT'), .raw(key), .raw(as.character(offset)), .raw(as.character(bit))) 4 | } 5 | 6 | redisGetBit <- function(key, offset, ...) 7 | { 8 | .redisCmd(.raw('GETBIT'), .raw(key), .raw(as.character(offset)),...) 9 | } 10 | 11 | redisBitCount <- function(key) 12 | { 13 | .redisCmd(.raw('BITCOUNT'), .raw(key)) 14 | } 15 | 16 | redisBitOp <- function(operation, destkey, sourcekeys, ...) 17 | { 18 | sets <- c(as.list(sourcekeys)) 19 | do.call('.redisCmd',c(lapply(c(list('BITOP'),operation, destkey, sets),charToRaw),...)) 20 | } 21 | -------------------------------------------------------------------------------- /man/redisInfo.Rd: -------------------------------------------------------------------------------- 1 | \name{redisInfo} 2 | \alias{redisInfo} 3 | \title{redisInfo} 4 | \description{Return system information about Redis. 5 | } 6 | \usage{ 7 | redisInfo() 8 | } 9 | \value{ 10 | A list of various Redis system parameters is returned, including at least: 11 | the Redis version, 12 | connected clients, 13 | connected slaves, 14 | used memory, 15 | changes since last save, 16 | last save time (UNIX time), 17 | total connections received, 18 | total commands processed, 19 | uptime in seconds, 20 | uptime in days. 21 | } 22 | \references{ 23 | http://redis.io/commands 24 | } 25 | \author{ 26 | B. W. Lewis 27 | } 28 | -------------------------------------------------------------------------------- /tests/hyperloglogTest.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisPfadd("testcounter", letters[1:10]) 10 | redisPfadd("testcounter", letters[1:20]) 11 | redisPfcount("testcounter") 12 | redisPfadd("testcounter_2", "z") 13 | redisPfmerge("testcounter", "testcounter_2") 14 | x = as.integer(redisPfcount("testcounter")) 15 | # Note! HyperLogLog is only an approximate count! 16 | checkEquals(TRUE, x > 10 && x < 30) 17 | 18 | redisFlushAll() 19 | } 20 | -------------------------------------------------------------------------------- /man/redisDBSize.Rd: -------------------------------------------------------------------------------- 1 | \name{redisDBSize} 2 | \alias{redisDBSize} 3 | \title{Return the number of keys in the current Redis database.} 4 | \description{ 5 | Return the number of keys in the current Redis database. 6 | } 7 | \usage{ 8 | redisDBSize() 9 | } 10 | \details{ 11 | Use \code{redisSelect} to choose a current database from 12 | among the available Redis databases. 13 | } 14 | \value{ 15 | The number of keys in the current database. 16 | } 17 | \references{ 18 | http://redis.io/commands 19 | } 20 | \author{ 21 | B. W. Lewis 22 | } 23 | \seealso{ 24 | \code{\link{redisSelect}} 25 | } 26 | \examples{ 27 | \dontrun{ 28 | redisDBSize() 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /man/redisZIncrBy.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZIncrBy} 2 | \alias{redisZIncrBy} 3 | \title{ 4 | redisZIncrBy 5 | } 6 | \description{ 7 | Increment the weight associated with an ordered set element. 8 | } 9 | \usage{ 10 | redisZIncrBy(key, member, increment) 11 | } 12 | \arguments{ 13 | \item{key}{ 14 | The set name. 15 | } 16 | \item{member}{ 17 | The set element. 18 | } 19 | \item{increment}{ 20 | The numeric value by which to increase the weight associated with the element. 21 | } 22 | } 23 | \details{ 24 | See the Redis documentation for details. 25 | } 26 | \value{ 27 | The new weight associated with the element. 28 | } 29 | \references{ 30 | http://redis.io/commands 31 | } 32 | \author{ 33 | B. W. Lewis 34 | } 35 | -------------------------------------------------------------------------------- /man/redisHDel.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHDel} 2 | \alias{redisHDel} 3 | \title{Delete a hash value.} 4 | \description{ 5 | Delete the value associated with the given key/field combination. 6 | } 7 | \usage{ 8 | redisHDel(key, field) 9 | } 10 | \arguments{ 11 | \item{key}{ A key name. } 12 | \item{field}{ A field name. } 13 | } 14 | \value{ 15 | Nothing is returned if the key/value pair is successfully deleted. 16 | A warning is thrown if the they key could not be found. 17 | } 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | \seealso{ 25 | \code{\link{redisHSet}} 26 | } 27 | \examples{ 28 | \dontrun{ 29 | redisHMSet('A',list(x=1,y=2,z=3)) 30 | redisHDel('A','x') 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /man/redisAuth.Rd: -------------------------------------------------------------------------------- 1 | \name{redisAuth} 2 | \alias{redisAuth} 3 | \title{Redis authentication.} 4 | \description{Redis supports a trivially simple and insecure authentication 5 | method. This function implements it. 6 | } 7 | \usage{ 8 | redisAuth(pwd) 9 | } 10 | \arguments{ 11 | \item{pwd}{ 12 | The (required) password. 13 | } 14 | } 15 | \details{ 16 | If you use this function, it's probably a good idea to encrypt network 17 | traffic between Redis and its client with a program like stunnel. 18 | Otherwise, passwords are transmitted over the network in clear text. 19 | } 20 | \value{ 21 | TRUE if sueccessful, FALSE otherwise. 22 | } 23 | \references{ 24 | http://redis.io/commands 25 | } 26 | \author{ 27 | B. W. Lewis 28 | } 29 | -------------------------------------------------------------------------------- /man/redisHExists.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHExists} 2 | \alias{redisHExists} 3 | \title{Test the existence of a hash.} 4 | \description{ 5 | Test the existence of a hash combination in the Redis database. 6 | } 7 | \usage{ 8 | redisHExists(key, field) 9 | } 10 | \arguments{ 11 | \item{key}{ A key name. } 12 | \item{field}{ A field name. } 13 | } 14 | \value{ 15 | Returns FALSE if no matching key/field combination, 16 | TRUE if matching entry exists, and NULL if an error occured. 17 | } 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | \seealso{ 25 | \code{\link{redisHSet}} 26 | } 27 | \examples{ 28 | \dontrun{ 29 | redisHSet('A','x',runif(5)) 30 | redisHExists('A','x') 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /man/redisSCard.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSCard} 2 | \alias{redisSCard} 3 | \title{Set cardinality} 4 | \description{ 5 | Return the number of elements contained in the specified set. 6 | } 7 | \usage{ 8 | redisSCard(set) 9 | } 10 | \arguments{ 11 | \item{set}{ 12 | A string set identifier. 13 | } 14 | } 15 | \value{ 16 | The function returns an integer corresponding to the number of elements 17 | in the set. Zero is returned if the set is empty or if the set does not exist. 18 | } 19 | \references{ 20 | http://redis.io/commands 21 | } 22 | \author{ 23 | B. W. Lewis 24 | } 25 | \seealso{ 26 | \code{\link{redisSAdd}} 27 | } 28 | \examples{ 29 | \dontrun{ 30 | redisConnect() 31 | redisSAdd("set",5) 32 | redisSCard("set") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /man/redisSIsMember.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSIsMember} 2 | \alias{redisSIsMember} 3 | \title{Test for set membership} 4 | \description{ 5 | Test if an element belongs to a set. 6 | } 7 | \usage{ 8 | redisSIsMember(set, element) 9 | } 10 | \arguments{ 11 | \item{set}{ 12 | A string set identifier. 13 | } 14 | \item{element}{ 15 | The element whose membership is to be tested. 16 | } 17 | } 18 | \value{ 19 | TRUE if the element is a member of the set, FALSE otherwise. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | \seealso{ 28 | \code{\link{redisSAdd}} 29 | } 30 | \examples{ 31 | \dontrun{ 32 | redisConnect() 33 | redisSAdd("set",5) 34 | redisSIsMember("set",5) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisRandomKey.Rd: -------------------------------------------------------------------------------- 1 | \name{redisRandomKey} 2 | \alias{redisRandomKey} 3 | \title{ 4 | Return a randomly selected key from the currently selected database. 5 | } 6 | \description{ 7 | Return a randomly selected key from the currently selected database. 8 | } 9 | \usage{ 10 | redisRandomKey() 11 | } 12 | \details{ 13 | Note that this function returns key names, not values. 14 | } 15 | \value{ 16 | A character string corresponding to a randomly-selected key from the currently 17 | selected database, or a zero-length string if no keys are defined. 18 | } 19 | \references{ 20 | http://redis.io/commands 21 | } 22 | \author{ 23 | B. W. Lewis 24 | } 25 | \examples{ 26 | \dontrun{ 27 | redisConnect() 28 | redisRandomKey() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /man/redisSMove.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSMove} 2 | \alias{redisSMove} 3 | \title{Move a set element.} 4 | \description{ 5 | Move the specified element from one set to another. 6 | } 7 | \usage{ 8 | redisSMove(setA, setB, element) 9 | } 10 | \arguments{ 11 | \item{setA}{The set to move from (character identifier).} 12 | \item{setB}{The set to move to (character identifier).} 13 | \item{element}{The element to move.} 14 | } 15 | \details{Note that the set element is specified as the actual set 16 | element object (aka set member), not as an index value. 17 | } 18 | \value{TRUE if successful, FALSE otherwise. 19 | } 20 | \references{ 21 | http://redis.io/commands 22 | } 23 | \author{ 24 | B. W. Lewis 25 | } 26 | \seealso{ 27 | \code{\link{redisSAdd}} 28 | } 29 | -------------------------------------------------------------------------------- /man/redisDelete.Rd: -------------------------------------------------------------------------------- 1 | \name{redisDelete} 2 | \alias{redisDelete} 3 | \title{Delete a key and associated value from Redis.} 4 | \description{ 5 | Delete a key and associated value from Redis. 6 | } 7 | \usage{ 8 | redisDelete(key) 9 | } 10 | \arguments{ 11 | \item{key}{ 12 | The (required) character identifier to be looked up. 13 | } 14 | } 15 | \details{ 16 | The key must not contain spaces or newline characters (otherwise an error will be thrown). 17 | } 18 | \value{ 19 | Integer number of keys successfully deleted. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | 28 | \seealso{ 29 | \code{\link{redisSet}} 30 | } 31 | \examples{ 32 | \dontrun{ 33 | redisSet('x',runif(5)) 34 | redisDelete('x') 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisHLen.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHLen} 2 | \alias{redisHLen} 3 | \title{Redis hash length.} 4 | \description{Return the number of fields associated with the given key.} 5 | \usage{ 6 | redisHLen(key) 7 | } 8 | \arguments{ 9 | \item{key}{The key to look up.} 10 | } 11 | \details{Returns the number of fields in the Redis hash 12 | associated with \code{key}. 13 | If the key is not found, or if the hash is empty, 0 is returned. If the 14 | key is associated with a value of type other than 'hash,' an error is 15 | thrown. 16 | } 17 | \value{The number of fields defined for the given key. } 18 | \references{ http://redis.io/commands} 19 | \author{ B. W. Lewis } 20 | \seealso{ \code{\link{redisHSet}} } 21 | \examples{ 22 | \dontrun{ 23 | redisHMSet('A',list(x=1,y=2,z=3)) 24 | redisHLen('A') 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /man/redisSMembers.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSMembers} 2 | \alias{redisSMembers} 3 | \title{List elements of a set.} 4 | \description{Return a list containing all the members (elements) 5 | of the specified set. 6 | } 7 | \usage{ 8 | redisSMembers(set, ...) 9 | } 10 | \arguments{ 11 | \item{set}{The set key name (character).} 12 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 13 | } 14 | \value{ 15 | A list containing the set elements. An error is thrown if the set does 16 | not exist. 17 | } 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | \seealso{ 25 | \code{\link{redisSAdd}} 26 | } 27 | \examples{ 28 | \dontrun{ 29 | redisConnect() 30 | redisSAdd('set',runif(5)) 31 | redisSMembers('set') 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/redisZRank.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRank} 2 | \alias{redisZRank} 3 | \title{ 4 | redisZRank 5 | } 6 | \description{ 7 | Return the rank of an element of an ordered set. 8 | } 9 | \usage{ 10 | redisZRank(key, member, decreasing = FALSE) 11 | } 12 | \arguments{ 13 | \item{key}{ 14 | The set name. 15 | } 16 | \item{member}{ 17 | The set element. 18 | } 19 | \item{decreasing}{ 20 | Set to TRUE to rank in reverse order of score. 21 | } 22 | } 23 | \details{ 24 | Returns the rank of the member in the sorted set, with scores ordered from 25 | low to high by default, or from high to low if decreasing = TRUE. 26 | The returned rank (or index) of the member is 0-based. 27 | } 28 | \value{ 29 | The numeric rank of the set element. 30 | } 31 | \references{ 32 | http://redis.io/commands 33 | } 34 | \author{ 35 | B. W. Lewis 36 | } 37 | -------------------------------------------------------------------------------- /man/redisExists.Rd: -------------------------------------------------------------------------------- 1 | \name{redisExists} 2 | \alias{redisExists} 3 | \title{Test the existence of a key in the Redis database.} 4 | \description{ 5 | Test the existence of a key in the Redis database. 6 | } 7 | \usage{ 8 | redisExists(key) 9 | } 10 | \arguments{ 11 | \item{key}{ 12 | The (required) character identifier to be looked up. 13 | } 14 | } 15 | \details{ 16 | The key must not contain spaces or newline characters (otherwise an error will be thrown). 17 | } 18 | \value{ 19 | Returns FALSE if no matching key, TRUE if matching key exists, and NULL 20 | if an error occured. 21 | } 22 | \references{ 23 | http://redis.io/commands 24 | } 25 | \author{ 26 | B. W. Lewis 27 | } 28 | 29 | \seealso{ 30 | \code{\link{redisSet}} 31 | } 32 | \examples{ 33 | \dontrun{ 34 | redisSet('x',runif(5)) 35 | redisExists('x') 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /man/redisBitOp.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBitOp} 2 | \alias{redisBitOp} 3 | \title{Redis BITOP - execute bitoperations on multiple bitsets} 4 | \usage{ 5 | redisBitOp(operation, destkey, sourcekeys, ...) 6 | } 7 | \arguments{ 8 | \item{operation}{bit operation as character: 'AND', 'OR', 9 | 'XOR', 'NOT'} 10 | 11 | \item{destkey}{destination key where the resulting bit 12 | operation will be stored} 13 | 14 | \item{sourcekeys}{one or more source keys subject to the 15 | bit operations} 16 | 17 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 18 | } 19 | \value{ 20 | the counted bits as an integer value 21 | } 22 | \description{ 23 | Perform a bitwise operation between multiple keys 24 | (containing string values) and store the result in the 25 | destination key 26 | } 27 | -------------------------------------------------------------------------------- /man/redisSRandMember.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSRandMember} 2 | \alias{redisSRandMember} 3 | \title{Choose a random element from a set} 4 | \description{ 5 | Select and return an element of a set at random. 6 | } 7 | \usage{ 8 | redisSRandMember(set, ...) 9 | } 10 | \arguments{ 11 | \item{set}{The set key name (character).} 12 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 13 | } 14 | \value{ 15 | An element from the set selected randomly. An error is thrown if the set does 16 | not exist. 17 | } 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | \seealso{ 25 | \code{\link{redisSAdd}} 26 | } 27 | \examples{ 28 | \dontrun{ 29 | redisConnect() 30 | redisSAdd('set',1) 31 | redisSAdd('set',2) 32 | redisSAdd('set',3) 33 | redisSRandMember('set') 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/redisLLen.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLLen} 2 | \alias{redisLLen} 3 | \title{Redis list length.} 4 | \description{Return the length of the Redis list associated with the 5 | specified key.} 6 | \usage{ 7 | redisLLen(key) 8 | } 9 | \arguments{ 10 | \item{key}{The key to look up.} 11 | } 12 | \details{Returns the length of the Redis list associated with \code{key}. 13 | If the key is not found, or if the list is empty, 0 is returned. If the 14 | key is associated with a value of type other than 'list,' an error is 15 | thrown. 16 | } 17 | \value{The length if the list. 18 | } 19 | \references{ 20 | http://redis.io/commands 21 | } 22 | \author{ 23 | B. W. Lewis 24 | } 25 | \seealso{ 26 | \code{redisBRpop} 27 | } 28 | \examples{ 29 | \dontrun{ 30 | redisConnect() 31 | redisLPush('list',1) 32 | redisLPush('list',2) 33 | redisLPush('list',3) 34 | redisLLen('list') 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisKeys.Rd: -------------------------------------------------------------------------------- 1 | \name{redisKeys} 2 | \alias{redisKeys} 3 | \title{Return a list of all keys in the active Redis database.} 4 | \description{ 5 | Return a list of all keys in the active Redis database that match 6 | the specified pattern. 7 | } 8 | \usage{ 9 | redisKeys(pattern = "*") 10 | } 11 | \arguments{ 12 | \item{pattern}{The character string pattern used to match keys.} 13 | } 14 | \details{Basic string-matching wildcards are supported. Use '?' to match 15 | any single character and '*' to match zero or more characters. 16 | } 17 | \value{A space-delimited character string containing all keys that match 18 | the patern in the active Redis database. 19 | } 20 | \references{ 21 | http://redis.io/commands 22 | } 23 | \author{ 24 | B. W. Lewis 25 | } 26 | \seealso{ 27 | \code{\link{redisSelect}} 28 | } 29 | \examples{ 30 | \dontrun{ 31 | redisKeys() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /man/redisSelect.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSelect} 2 | \alias{redisSelect} 3 | \title{Select a redis database.} 4 | \description{Select a database by numeric index value.} 5 | \usage{ 6 | redisSelect(index) 7 | } 8 | %- maybe also 'usage' for other objects documented here. 9 | \arguments{ 10 | \item{index}{The nonnegative integer value of the database to select.} 11 | } 12 | \details{Redis supports multiple databases indexed by nonnegative integers. 13 | The number of supported databases is configurable via the redis server 14 | configuration file. New connections are assigned to database 0 by default. 15 | } 16 | \value{A character string status code. An error is thrown if the index 17 | value is invalid.} 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | \examples{ 25 | \dontrun{ 26 | redisConnect() 27 | redisSelect(1) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/hash.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | x <- runif(5) 10 | redisHSet("A", "x", x) 11 | checkEquals(TRUE, redisHExists("A", "x")) 12 | checkEquals(x, redisHGet("A", "x")) 13 | 14 | redisHSet("A", "y", "1") 15 | checkEquals("2", redisHIncrBy("A", "y", "1")) 16 | checkEquals("3", redisHIncrByFloat("A", "y", "1")) 17 | 18 | redisHDel("A", "y") 19 | checkEquals(x, redisHGetAll("A")$x) 20 | checkEquals(x, redisHVals("A")[[1]]) 21 | 22 | checkEquals("x", redisHFields("A")[[1]]) 23 | checkEquals("1", redisHLen("A")) 24 | 25 | redisHMSet("A", list(y=pi, z=letters)) 26 | checkEquals(list(x=x, z=letters), redisHMGet("A", c("x", "z"))) 27 | 28 | redisFlushAll() 29 | } 30 | -------------------------------------------------------------------------------- /man/redisHKeys.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHKeys} 2 | \alias{redisHKeys} 3 | \title{Redis hash fields.} 4 | \description{Return the fields associated with the given key.} 5 | \usage{ 6 | redisHKeys(key, ...) 7 | } 8 | \arguments{ 9 | \item{key}{The key to look up.} 10 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 11 | } 12 | \details{Returns the fields in the Redis hash 13 | associated with \code{key}. 14 | If the key is not found, or if the hash is empty, NULL is returned. If the 15 | key is associated with a value of type other than 'hash,' an error is 16 | thrown. 17 | } 18 | \value{A list of fields defined for the given key. } 19 | \references{ http://redis.io/commands} 20 | \author{ B. W. Lewis } 21 | \seealso{ \code{\link{redisHSet}} } 22 | \examples{ 23 | \dontrun{ 24 | redisHMSet('A',list(x=1,y=2,z=3)) 25 | redisHKeys('A') 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /man/redisSRem.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSRem} 2 | \alias{redisSRem} 3 | \title{Remove an element from a set.} 4 | \description{ 5 | Remove an element from a set. 6 | } 7 | \usage{ 8 | redisSRem(set, element) 9 | } 10 | \arguments{ 11 | \item{set}{The set name (character) from which to remove the element.} 12 | \item{element}{The element to remove (not and index, but the actual element 13 | value).} 14 | } 15 | \details{ 16 | The set element matching the specified element will be removed from the set. 17 | } 18 | \value{ 19 | TRUE upon successful removal, FALSE otherwise. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | \seealso{ 28 | \code{\link{redisSAdd}} 29 | } 30 | \examples{ 31 | \dontrun{ 32 | redisConnect() 33 | redisSAdd('set', 5) 34 | redisSAdd('set', 7) 35 | redisSMembers('set') 36 | redisSRem('set',5) 37 | redisSMembers('set') 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /man/redisHVals.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHVals} 2 | \alias{redisHVals} 3 | \title{Redis hash values.} 4 | \description{Return all the values associated with the given hash key.} 5 | \usage{ 6 | redisHVals(key,...) 7 | } 8 | \arguments{ 9 | \item{key}{The key to look up.} 10 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 11 | } 12 | \details{Returns the values in the Redis hash 13 | associated with \code{key}. 14 | If the key is not found, or if the list is empty, NULL is returned. If the 15 | key is associated with a value of type other than 'hash,' an error is 16 | thrown. 17 | } 18 | \value{A list of values defined for the given key. } 19 | \references{ http://redis.io/commands} 20 | \author{ B. W. Lewis } 21 | \seealso{ \code{\link{redisHSet}} } 22 | \examples{ 23 | \dontrun{ 24 | redisHMSet('A',list(x=1,y=2,z=3)) 25 | redisHVals('A') 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /man/redisLSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLSet} 2 | \alias{redisLSet} 3 | \title{Set a value within a list.} 4 | \description{Set the value of an element at the given index in a 5 | list corresponding to the specified key. 6 | } 7 | \usage{ 8 | redisLSet(key, index, value) 9 | } 10 | \arguments{ 11 | \item{key}{A key corresponding to a Redis list. 12 | } 13 | \item{index}{The index within the list of the element to write to. 14 | } 15 | \item{value}{The value to set. 16 | } 17 | } 18 | \details{ 19 | Indices begin at zero. Out of range indices throw an error. 20 | } 21 | \value{ 22 | TRUE if successful, FALSE otherwise. 23 | } 24 | \references{ 25 | http://redis.io/commands 26 | } 27 | \author{ 28 | B. W. Lewis 29 | } 30 | \seealso{ 31 | \code{\link{redisLPush}} 32 | } 33 | \examples{ 34 | \dontrun{ 35 | redisConnect() 36 | redisLPush('list',pi) 37 | redisLSet('list',0,5) 38 | redisLIndex('list',0) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /man/redisSPop.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSPop} 2 | \alias{redisSPop} 3 | \title{Remove and return an element from a set.} 4 | \description{ 5 | Remove and return an element, chosen at random, from the specified set. 6 | } 7 | \usage{ 8 | redisSPop(set, ...) 9 | } 10 | \arguments{ 11 | \item{set}{The set name (character).} 12 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 13 | } 14 | \value{A random element of the set, or NULL if the set is empty or does 15 | not exist.} 16 | \references{ 17 | http://redis.io/commands 18 | } 19 | \author{ 20 | B. W. Lewis 21 | } 22 | \seealso{ 23 | \code{\link{redisSAdd}} 24 | } 25 | \examples{ 26 | \dontrun{ 27 | redisConnect() 28 | redisSAdd('set',runif(2)) 29 | redisSAdd('set',runif(3)) 30 | redisSAdd('set',runif(4)) 31 | redisSPop('set') 32 | redisSPop('set') 33 | redisSPop('set') 34 | redisSPop('set') 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisHFields.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHFields} 2 | \alias{redisHFields} 3 | \title{Redis hash fields.} 4 | \description{Return the fields associated with the given key.} 5 | \usage{ 6 | redisHFields(key, ...) 7 | } 8 | \arguments{ 9 | \item{key}{The key to look up.} 10 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 11 | } 12 | \details{Returns the fields in the Redis hash 13 | associated with \code{key}. 14 | If the key is not found, or if the hash is empty, NULL is returned. If the 15 | key is associated with a value of type other than 'hash,' an error is 16 | thrown. 17 | } 18 | \value{A list of fields defined for the given key. } 19 | \references{ http://redis.io/commands} 20 | \author{ B. W. Lewis } 21 | \seealso{ \code{\link{redisHSet}} } 22 | \examples{ 23 | \dontrun{ 24 | redisHMSet('A',list(x=1,y=2,z=3)) 25 | redisHFields('A') 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /man/redisCmd.Rd: -------------------------------------------------------------------------------- 1 | \name{redisCmd} 2 | \alias{redisCmd} 3 | \title{General Redis Interface Function} 4 | \description{Perform any Redis command.} 5 | \usage{ 6 | redisCmd(CMD, ..., raw = FALSE) 7 | } 8 | \arguments{ 9 | \item{CMD}{ 10 | The (required) Redis command (character string). 11 | } 12 | \item{...}{ 13 | Redis command arguments. 14 | } 15 | \item{raw}{If TRUE, return results in raw byte form.} 16 | } 17 | \details{ 18 | Use this low-level function to perform any Redis operation. 19 | The ... argument(s) not already in raw format will be 20 | converted to raw byte format, and non-character values 21 | will be serialized. 22 | } 23 | \value{ 24 | Output from the Redis command--varies depending on command. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | \examples{ 33 | \dontrun{ 34 | redisCmd('set','x',runif(5)) 35 | redisCmd('get','x') 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /man/redisPersist.Rd: -------------------------------------------------------------------------------- 1 | \name{redisPersist} 2 | \alias{redisPersist} 3 | \title{Clear expiration flags for a key} 4 | \description{Clear expiration flags for a key.} 5 | \usage{ 6 | redisPersist(key) 7 | } 8 | \arguments{ 9 | \item{key}{ 10 | The (required) character identifier for the value to be looked up. 11 | } 12 | } 13 | \details{ 14 | Remove the existing timeout on key, turning the key from volatile (a key with 15 | an expire set) to persistent (a key that will never expire as no timeout is 16 | associated). 17 | } 18 | \value{ 19 | 1 if the timeout was removed, 0 if the key does not exists or does not have 20 | a timeout set. 21 | } 22 | \references{ 23 | http://redis.io/commands 24 | } 25 | \author{ 26 | B. W. Lewis 27 | } 28 | 29 | \seealso{ 30 | \code{\link{redisTTL}}, \code{\link{redisExpire}} 31 | } 32 | \examples{ 33 | \dontrun{ 34 | redisSet('x',runif(5)) 35 | redisExpire('x',10) 36 | redisPersist('x') 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/redisZCount.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZCount} 2 | \alias{redisZCount} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{ 5 | redisZCount 6 | } 7 | \description{ 8 | Returns the number of elements in the sorted set at key with a score between min and max. 9 | The min and max arguments have the same semantic as described for \code{redisZRangeByScore}. 10 | } 11 | \usage{ 12 | redisZCount(key, min, max) 13 | } 14 | %- maybe also 'usage' for other objects documented here. 15 | \arguments{ 16 | \item{key}{ 17 | The set name. 18 | } 19 | \item{min}{ 20 | Minimum score. 21 | } 22 | \item{max}{ 23 | Maximum score. 24 | } 25 | } 26 | \value{ 27 | See the Redis documentation for more information. 28 | %% If it is a LIST, use 29 | %% \item{comp1 }{Description of 'comp1'} 30 | %% \item{comp2 }{Description of 'comp2'} 31 | %% ... 32 | } 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | -------------------------------------------------------------------------------- /man/redisZRemRangeByRank.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRemRangeByRank} 2 | \alias{redisZRemRangeByRank} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{ 5 | redisZRemRangeByRank.Rd 6 | } 7 | \description{ 8 | redisZRemRangeByRank.Rd 9 | } 10 | \usage{ 11 | redisZRemRangeByRank(key, start, end) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{key}{ 16 | %% ~~Describe \code{key} here~~ 17 | } 18 | \item{start}{ 19 | %% ~~Describe \code{start} here~~ 20 | } 21 | \item{end}{ 22 | %% ~~Describe \code{end} here~~ 23 | } 24 | } 25 | \details{ 26 | See the Redis documentation for details. 27 | } 28 | \value{ 29 | See the Redis documentation for more information. 30 | %% If it is a LIST, use 31 | %% \item{comp1 }{Description of 'comp1'} 32 | %% \item{comp2 }{Description of 'comp2'} 33 | %% ... 34 | } 35 | \references{ 36 | http://redis.io/commands 37 | } 38 | \author{ 39 | B. W. Lewis 40 | } 41 | -------------------------------------------------------------------------------- /man/redisZRemRangeByScore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRemRangeByScore} 2 | \alias{redisZRemRangeByScore} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{ 5 | redisZRemRangeByScore.Rd 6 | } 7 | \description{ 8 | redisZRemRangeByScore.Rd 9 | } 10 | \usage{ 11 | redisZRemRangeByScore(key, min, max) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{key}{ 16 | %% ~~Describe \code{key} here~~ 17 | } 18 | \item{min}{ 19 | %% ~~Describe \code{min} here~~ 20 | } 21 | \item{max}{ 22 | %% ~~Describe \code{max} here~~ 23 | } 24 | } 25 | \details{ 26 | See the Redis documentation for details. 27 | } 28 | \value{ 29 | See the Redis documentation for more information. 30 | %% If it is a LIST, use 31 | %% \item{comp1 }{Description of 'comp1'} 32 | %% \item{comp2 }{Description of 'comp2'} 33 | %% ... 34 | } 35 | \references{ 36 | http://redis.io/commands 37 | } 38 | \author{ 39 | B. W. Lewis 40 | } 41 | -------------------------------------------------------------------------------- /man/redisMSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisMSet} 2 | \alias{redisMSet} 3 | \title{Set one or more key/value pairs in the Redis database.} 4 | \description{Set one or more key/value pairs in the Redis database.} 5 | \usage{ 6 | redisMSet(keyvalues, NX = FALSE, ...) 7 | } 8 | \arguments{ 9 | \item{keyvalues}{A list of values to set of the form 10 | list(key1=value1, key2=value2, ...)} 11 | \item{NX}{ If NX = TRUE, existing values will not be replaced, otherwise they will be. } 12 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 13 | } 14 | \details{ 15 | Set one or more key/value pairs in the Redis database. Existing 16 | values will be replaced. 17 | } 18 | \value{ 19 | ``OK'' upon success. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | 28 | \seealso{ 29 | \code{\link{redisGet}} 30 | } 31 | \examples{ 32 | \dontrun{ 33 | redisMSet(list(x=5, y=6)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/redisClose.Rd: -------------------------------------------------------------------------------- 1 | \name{redisClose} 2 | \alias{redisClose} 3 | \title{Close an open connection to a Redis server.} 4 | \description{The redisClose function closes any open connection to a Redis 5 | server.} 6 | \usage{ 7 | redisClose(e) 8 | } 9 | \arguments{ 10 | \item{e}{(Optional) Redis context. The current context is used if e is not supplied.} 11 | } 12 | \details{A running instance of a Redis server is required. } 13 | \value{Nothing is returned. Errors are displayed if the function fails to 14 | close the connection to the Redis server, or if the connection is invalid. 15 | } 16 | \references{ 17 | http://redis.io/commands 18 | } 19 | \author{ 20 | B. W. Lewis 21 | } 22 | 23 | %% ~Make other sections like Warning with \section{Warning }{....} ~ 24 | 25 | \seealso{ 26 | \code{\link{redisConnect}} 27 | \code{\link{redisGetContext}} 28 | } 29 | \examples{ 30 | \dontrun{ 31 | redisConnect() 32 | redisSet('x',runif(5)) 33 | redisGet('x') 34 | redisClose() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisHGetAll.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHGetAll} 2 | \alias{redisHGetAll} 3 | \title{Redis hash fields and values.} 4 | \description{Return all fields and values associated with the given key.} 5 | \usage{ 6 | redisHGetAll(key, ...) 7 | } 8 | \arguments{ 9 | \item{key}{The key to look up.} 10 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 11 | } 12 | \details{Returns all the fields and their values in the Redis hash 13 | associated with \code{key}. 14 | If the key is not found, or if the hash is empty, NULL is returned. If the 15 | key is associated with a value of type other than 'hash,' an error is 16 | thrown. 17 | } 18 | \value{A list of values defined for the given key, named by the field names.} 19 | \references{ http://redis.io/commands} 20 | \author{ B. W. Lewis } 21 | \seealso{ \code{\link{redisHSet}} } 22 | \examples{ 23 | \dontrun{ 24 | redisHMSet('A',list(x=1,y=2,z=3)) 25 | redisHGetAll('A') 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/list.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisLPush("x", 1) 10 | redisRPush("x", 2) 11 | checkEquals("2", redisLLen("x")) 12 | checkEquals(list(1,2), redisLRange("x", 0, 2)) 13 | redisLSet("x", 0, pi) 14 | checkEquals(pi, redisLPop("x")) 15 | redisRPush("x", 2) 16 | redisLTrim("x", 0, 0) 17 | checkEquals("1", redisLLen("x")) 18 | checkEquals(2, redisLIndex("x", 0)) 19 | redisLRem("x", 1, 2) 20 | checkEquals("0", redisLLen("x")) 21 | 22 | redisLPush("x", 1) 23 | redisRPush("x", 2) 24 | checkEquals(list(1,2), redisLRange("x", 0, 2)) 25 | redisBRPopLPush('x','x') 26 | checkEquals(list(2,1), redisLRange("x", 0, 2)) 27 | redisRPopLPush('x','x') 28 | redisBLPop("x") 29 | redisBRPop("x") 30 | checkEquals("0", redisLLen("x")) 31 | 32 | redisFlushAll() 33 | } 34 | -------------------------------------------------------------------------------- /man/redisMGet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisMGet} 2 | \alias{redisMGet} 3 | \title{Retrieve one or more values from Redis.} 4 | \description{Retrieve values corresponding to the specified list of keys. 5 | } 6 | \usage{ 7 | redisMGet(keys, ...) 8 | } 9 | \arguments{ 10 | \item{keys}{A vector or list of character strings corresponding to 11 | keys to retrieve.} 12 | \item{...}{Optional arguments. Specify \code{raw=TRUE} to skip de-serialization of the returned values. } 13 | } 14 | \value{ 15 | A list of retrieved key/value pairs. Missing values return NULL. 16 | } 17 | \details{ 18 | Values are returned in a list with names corresponding to keys. The \code{raw} 19 | argument is used to retrieve binary data from other languages. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | \seealso{ 28 | \code{\link{redisMSet}} 29 | } 30 | \examples{ 31 | \dontrun{ 32 | redisSet('x',runif(5)) 33 | redisSet('y',runif(5)) 34 | redisMGet(c('x','y')) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /man/redisHMSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHMSet} 2 | \alias{redisHMSet} 3 | \title{Store a list of hash values.} 4 | \description{Store a list of hash values at once. 5 | } 6 | \usage{ 7 | redisHMSet(key, values) 8 | } 9 | \arguments{ 10 | \item{key}{ 11 | The (required) character identifier for the key name. 12 | } 13 | \item{values}{ 14 | An R list of values to be stored. The list names are used as field names and 15 | must be nonempty. 16 | } 17 | } 18 | \details{ 19 | Redis hash values store values in one or more fields associated with a single 20 | key name. The redisHMSet function stores several fields associated with one 21 | key at once. Values already occupying any specified field slots are replaced. 22 | } 23 | \value{ 24 | TRUE is returned on success. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | 33 | \seealso{ 34 | \code{\link{redisHGet}} 35 | } 36 | \examples{ 37 | \dontrun{ 38 | redisHMSet('A', list(x=1,y=2,z=3)) 39 | redisHGet('A','y') 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /man/redisRPop.Rd: -------------------------------------------------------------------------------- 1 | \name{redisRPop} 2 | \alias{redisRPop} 3 | \title{Remove the last element from a list.} 4 | \description{ 5 | Atomically return and remove the last element of the list associated with 6 | the specified key. 7 | For example if the list contains the elements "a","b","c" 8 | \code{redisRPop} will return "c" and the list will become "a","b". 9 | } 10 | \usage{ 11 | redisRPop(key, ...) 12 | } 13 | \arguments{ 14 | \item{key}{The desired key associated with a list.} 15 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 16 | } 17 | \value{The first element of the list associated with the specified key, 18 | or NULL if the list is empty. 19 | } 20 | \references{ 21 | http://redis.io/commands 22 | } 23 | \author{ 24 | B. W. Lewis 25 | } 26 | \seealso{ 27 | \code{\link{redisLPop}}, \code{\link{redisLPush}} 28 | } 29 | \examples{ 30 | \dontrun{ 31 | redisConnect() 32 | redisLPush('a',1) 33 | redisLPush('a',2) 34 | redisLPush('a',3) 35 | redisRPop('a') 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /man/redisRename.Rd: -------------------------------------------------------------------------------- 1 | \name{redisRename} 2 | \alias{redisRename} 3 | \title{ 4 | Rename a key. 5 | } 6 | \description{ 7 | Atomically rename a key. 8 | } 9 | \usage{ 10 | redisRename(old, new, NX = FALSE) 11 | } 12 | %- maybe also 'usage' for other objects documented here. 13 | \arguments{ 14 | \item{old}{Original key name.} 15 | \item{new}{New key name.} 16 | \item{NX}{Set NX = TRUE to prevent overwriting a key that already exists. 17 | } 18 | } 19 | \details{ 20 | If the source and destination name are the same an error is returned. If newkey already exists it is overwritten unless NX = TRUE, in which case the 21 | operation fails. 22 | } 23 | \value{ 24 | Returns the Redis status "OK" unless \code{NX = TRUE}. When 25 | \code{NX = TRUE}, returns 1 if successful, 0 otherwise. 26 | } 27 | \references{ 28 | http://redis.io 29 | } 30 | \author{ 31 | B. W. Lewis 32 | } 33 | \seealso{ 34 | \code{\link{redisKeys}} 35 | } 36 | \examples{ 37 | \dontrun{ 38 | redisConnect() 39 | redisSet('x',5) 40 | redisRename('x','y') 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /man/redisHGet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHGet} 2 | \alias{redisHGet} 3 | \title{Retrieve a hased value from Redis.} 4 | \description{Retrieve a value identified by a key and field 5 | from the Redis database. 6 | } 7 | \usage{ 8 | redisHGet(key, field, ...) 9 | } 10 | \arguments{ 11 | \item{key}{ 12 | A key name. 13 | } 14 | \item{field}{ 15 | A field name. 16 | } 17 | \item{...}{ 18 | Optional additional agruments. 19 | Specify \code{raw=TRUE} to skip de-serialization of the data. 20 | } 21 | } 22 | \details{ 23 | Redis hash values store values in one or more fields associated with a single 24 | key name. 25 | } 26 | \value{ 27 | The value corresponding to the specified key/field, 28 | or NULL if the matching key/field hash contained no value 29 | or if no matching key or field was found. 30 | } 31 | \references{ 32 | http://redis.io/commands 33 | } 34 | \author{ 35 | B. W. Lewis 36 | } 37 | 38 | \seealso{ 39 | \code{\link{redisHSet}} 40 | } 41 | \examples{ 42 | \dontrun{ 43 | redisHSet('A','x',runif(5)) 44 | redisHGet('A','x') 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /man/redisBgRewriteAOF.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBgRewriteAOF} 2 | \alias{redisBgRewriteAOF} 3 | \title{redisBgRewriteAOF} 4 | \description{ 5 | Re-write the Redis append-only file in the background. 6 | } 7 | \usage{ 8 | redisBgRewriteAOF() 9 | } 10 | \details{ 11 | BGREWRITEAOF rewrites the Append Only File in the background when it gets too 12 | big. The Redis Append Only File is a Journal, so every operation modifying the 13 | dataset is logged in the Append Only File (and replayed at startup). This means 14 | that the Append Only File always grows. In order to rebuild its content the 15 | BGREWRITEAOF creates a new version of the append only file starting directly 16 | form the dataset in memory in order to guarantee the generation of the minimal 17 | number of commands needed to rebuild the database. 18 | (These details are copied verbatim from the Redis master documentation, see the 19 | references below.) 20 | } 21 | \value{ 22 | Nothing is returned. 23 | } 24 | \references{ 25 | http://redis.io/commands 26 | } 27 | \author{ 28 | B. W. Lewis 29 | } 30 | -------------------------------------------------------------------------------- /man/redisTTL.Rd: -------------------------------------------------------------------------------- 1 | \name{redisTTL} 2 | \alias{redisTTL} 3 | \alias{redisPTTL} 4 | \title{Return the time to live for a key set to expire.} 5 | \description{She the time left to live in seconds (redisTTL) or 6 | milliseconds (redisPTTL) for the specified key.} 7 | \usage{ 8 | redisTTL(key) 9 | redisPTTL(key) 10 | } 11 | \arguments{ 12 | \item{key}{The key to look up.} 13 | } 14 | \details{Redis keys may be set to exipre at or after a given time with 15 | the \code{redisExpire} and \code{redisExpireAt} functions. This function 16 | shows the time left before exipraton in seconds for such a key. 17 | } 18 | \value{A Redis string value representtion of the integer time left to live or -1 if the key is not set to expire or 19 | -2 if not found. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | \seealso{ 28 | \code{\link{redisExpire}}, \code{\link{redisExpireAt}} 29 | } 30 | \examples{ 31 | \dontrun{ 32 | redisConnect() 33 | redisSet('x',5) 34 | redisExpire('x',100) 35 | redisTTL('x') 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /man/redisSAdd.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSAdd} 2 | \alias{redisSAdd} 3 | \title{ 4 | Add an element to a set. 5 | } 6 | \description{ 7 | Add the element to the specified set. 8 | } 9 | \usage{ 10 | redisSAdd(set, element) 11 | } 12 | %- maybe also 'usage' for other objects documented here. 13 | \arguments{ 14 | \item{set}{ 15 | The string set identifier. 16 | } 17 | \item{element}{ 18 | The object to add to the set. 19 | } 20 | } 21 | \details{ 22 | If member is already a member of the set no operation is performed. If key 23 | does not exist a new set with the specified member as sole member is created. 24 | If the key exists but does not hold a set value an error is returned. 25 | } 26 | \value{ 27 | TRUE if the element was successfully added, FALSE otherwise (including cases in 28 | which the element already belonged to the set). 29 | } 30 | \references{ 31 | http://redis.io/commands 32 | } 33 | \author{ 34 | B. W. Lewis 35 | } 36 | \seealso{ 37 | \code{\link{redisSRem}} 38 | } 39 | \examples{ 40 | \dontrun{ 41 | redisConnect() 42 | redisSAdd("set", 5) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /man/redisMove.Rd: -------------------------------------------------------------------------------- 1 | \name{redisMove} 2 | \alias{redisMove} 3 | \title{ 4 | Move the specified key/value pair to another database. 5 | } 6 | \description{ 7 | Move the specified key/value pair in the currently selected database to 8 | another database. 9 | } 10 | \usage{ 11 | redisMove(key, dbindex) 12 | } 13 | \arguments{ 14 | \item{key}{The key to move.} 15 | \item{dbindex}{The destination database index number.} 16 | } 17 | \details{ 18 | This command returns TRUE only if the key was successfully moved, 19 | and FALSE if the target key was already there or if the source key was 20 | not found at all. It is possible to use \code{redisMove} as 21 | a locking primitive. 22 | } 23 | \value{ 24 | Returns TRUE if the key/value pair was moved, or FALSE otherwise. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | \seealso{ 33 | \code{\link{redisSelect}} 34 | } 35 | \examples{ 36 | \dontrun{ 37 | redisConnect() 38 | redisSelect(1) 39 | redisSet('x',5) 40 | redisMove('x',2) 41 | redisSelect(2) 42 | redisGet('x') 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /man/redisHMGet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHMGet} 2 | \alias{redisHMGet} 3 | \title{Retrieve a list of hash values.} 4 | \description{Retrieve a list of hash values from specified key/field pairs at once.} 5 | \usage{ 6 | redisHMGet(key, fields, ...) 7 | } 8 | \arguments{ 9 | \item{key}{ 10 | The (required) character identifier for the key name. 11 | } 12 | \item{fields}{ 13 | An R string vector of hash fields to retrieve. 14 | } 15 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 16 | } 17 | \details{ 18 | Redis hash values store values in one or more fields associated with a single 19 | key name. The redisHMGet function retrieves several fields associated with one 20 | key at once. Fields not present return NULL. 21 | } 22 | \value{ A named list of retrieved values. } 23 | \references{ http://redis.io/commands } 24 | \author{ B. W. Lewis } 25 | 26 | \seealso{ 27 | \code{\link{redisHSet},\link{redisHMSet}} 28 | } 29 | \examples{ 30 | \dontrun{ 31 | redisHMSet('A', list(x=1,y=2,z=3)) 32 | redisHMGet('A',c('y','z')) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /man/redisLPush.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLPush} 2 | \alias{redisLPush} 3 | \alias{redisRPush} 4 | \title{Add a value to the head tail of a list. 5 | } 6 | \description{ 7 | Add values to the tail (LPush) or head (RPush) of a list 8 | corresponding to the specified key. 9 | } 10 | \usage{ 11 | redisLPush(key, value, ...) 12 | } 13 | \arguments{ 14 | \item{key}{The desired key corresponding to a list.} 15 | \item{value}{The element to add to the list.} 16 | \item{...}{Optional additional values to add to the list.} 17 | } 18 | \details{ 19 | If the key does not exist an empty list is created just before the 20 | append operation. If the key exists but is not a list an error is returned. 21 | } 22 | \value{ 23 | The length of the list after the push operation. 24 | } 25 | \references{ 26 | http://redis.io/commands 27 | } 28 | \author{ 29 | B. W. Lewis 30 | } 31 | \seealso{ 32 | \code{\link{redisRPush}} 33 | } 34 | \examples{ 35 | \dontrun{ 36 | redisConnect() 37 | redisLPush('x',1) 38 | redisLPush('x',2) 39 | redisLPush('x',3) 40 | redisRPush('x',11) 41 | redisRPush('x',21) 42 | redisRPush('x',31) 43 | redisLLen('x') 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /man/redisLPop.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLPop} 2 | \alias{redisLPop} 3 | \title{Remove the first element from a list.} 4 | \description{ 5 | Atomically return and remove the first element of the list. 6 | For example if the list contains the elements "a","b","c" 7 | \code{redisLPop} will return "a" and the list will become "b","c". 8 | } 9 | %% ~~ A concise (1-5 lines) description of what the function does. ~~ 10 | \usage{ 11 | redisLPop(key, ...) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{key}{The desired key associated with a list.} 16 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 17 | } 18 | \value{The first element of the list associated with the specified key, 19 | or NULL if the list is empty. 20 | } 21 | \references{ 22 | http://redis.io/commands 23 | } 24 | \author{ 25 | B. W. Lewis 26 | } 27 | \seealso{ 28 | \code{\link{redisRPop}}, \code{\link{redisLPush}} 29 | } 30 | \examples{ 31 | \dontrun{ 32 | redisConnect() 33 | redisLPush('a',1) 34 | redisLPush('a',2) 35 | redisLPush('a',3) 36 | redisLPop('a') 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/redisLIndex.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLIndex} 2 | \alias{redisLIndex} 3 | \title{Retrieve a value from a Redis 'list.'} 4 | \description{ 5 | Retrieve a value from a Redis 'list' at the specified index without 6 | removing it from the list. 7 | } 8 | \usage{ 9 | redisLIndex(key, index, ...) 10 | } 11 | \arguments{ 12 | \item{key}{The key (whose value is of the type 'list').} 13 | \item{index}{The list index to retrieve.} 14 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 15 | } 16 | \details{ 17 | List indices begin at 0. 18 | Negative indexes are supported, for example -1 is the last element, 19 | -2 the penultimate and so on. 20 | If the value stored at key is not of the 'list' type an error is returned. 21 | If the index is out of range an empty string is returned. 22 | } 23 | \value{ 24 | The corresponding value or an empty string if the index is out of bounds. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | \seealso{ 33 | \code{\link{redisLPop}} 34 | } 35 | \examples{ 36 | \dontrun{ 37 | redisConnect() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /man/redisLTrim.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLTrim} 2 | \alias{redisLTrim} 3 | \title{Trim a list.} 4 | \description{ 5 | Trim an existing list so that it will contain only the specified range of 6 | elements specified. 7 | } 8 | \usage{ 9 | redisLTrim(key, start, end) 10 | } 11 | %- maybe also 'usage' for other objects documented here. 12 | \arguments{ 13 | \item{key}{A key corresponding to a Redis list object. 14 | } 15 | \item{start}{The starting list index at which to trim. 16 | } 17 | \item{end}{The ending list index at which to trim. 18 | } 19 | } 20 | \details{ 21 | Start and end are zero-based indexes. 0 is the first 22 | element of the list (the list head), 1 the next element and so on. 23 | } 24 | \value{ 25 | TRUE if successful. An error is thrown if the key does not exist or 26 | correspond to a list value. 27 | } 28 | \references{ 29 | http://redis.io/commands 30 | } 31 | \author{ 32 | B. W. Lewis 33 | } 34 | \seealso{ 35 | \code{\link{redisLPush}} 36 | } 37 | \examples{ 38 | \dontrun{ 39 | redisConnect() 40 | redisLPush('x',1) 41 | redisLPush('x',2) 42 | redisLPush('x',3) 43 | redisLTrim('x',0,1) 44 | redisLRange('x',0,99) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /man/redisExpireAt.Rd: -------------------------------------------------------------------------------- 1 | \name{redisExpireAt} 2 | \alias{redisExpireAt} 3 | \alias{redisPexpireAt} 4 | \title{Set a timeout on the specified key.} 5 | \description{ 6 | Set a timeout on the specified key, after which time the key and 7 | corresponding value will be deleted. 8 | } 9 | \usage{ 10 | redisExpireAt(key, time) 11 | redisPexpireAt(key, time) 12 | } 13 | \arguments{ 14 | \item{key}{The character key on which to set the timeout.} 15 | \item{time}{The UNIX time of expiration in seconds or milliseconds.} 16 | } 17 | \details{Operations that modify value(s) corresponding to a key subsequent 18 | to the \code{redisExpireAt} function clear the timeout, removing the expiration. 19 | The \code{redisExpireAt} function can't set a new timeout value once a timeout 20 | has been set on a key. 21 | } 22 | \value{ 23 | Boolean TRUE if the timeout command was successful, FALSE otherwise. 24 | } 25 | \references{ 26 | http://redis.io/commands 27 | } 28 | \author{ 29 | B. W. Lewis 30 | } 31 | \seealso{ 32 | \code{\link{redisExpire}} 33 | } 34 | \examples{ 35 | \dontrun{ 36 | redisConnect() 37 | redisLPush('x',runif(5)) 38 | redisExpireAt('x', 1266209144) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /man/redisEval.Rd: -------------------------------------------------------------------------------- 1 | \name{redisEval} 2 | \alias{redisEval} 3 | \title{Evaluate a Lua script in the Redis server.} 4 | \description{Evaluate a Lua script in the Redis server.} 5 | \usage{ 6 | redisEval(script, keys = vector("list",0), SHA = FALSE, ...) 7 | } 8 | \arguments{ 9 | \item{script}{A Redis server-side Lua script (character).} 10 | \item{keys}{An optional list of script key arguments.} 11 | \item{SHA}{If TRUE, the script is a SHA1-encoded string, otherwise plan text.} 12 | \item{...}{Optional list of script arguments.} 13 | } 14 | 15 | \value{"OK" is returned on success. 16 | Errors are displayed if the script fails. 17 | } 18 | \references{ 19 | http://redis.io/commands 20 | } 21 | \author{ 22 | B. W. Lewis 23 | } 24 | 25 | %% ~Make other sections like Warning with \section{Warning }{....} ~ 26 | 27 | \examples{ 28 | \dontrun{ 29 | redisConnect() 30 | redisEval("return redis.call('set','foo','bar')") 31 | 32 | # Supply a key argument to the script 33 | redisEval("return redis.call('set',KEYS[1],'bar')", "foo") 34 | 35 | # Supply a key and other arguments to the script 36 | redisEval("return redis.call('set',KEYS[1],ARGV[1])", "foo", pi) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/redisExpire.Rd: -------------------------------------------------------------------------------- 1 | \name{redisExpire} 2 | \alias{redisExpire} 3 | \alias{redisPexpire} 4 | \title{Set a timeout on the specified key.} 5 | \description{ 6 | Set a timeout on the specified key, after which the key and 7 | corresponding value will be deleted. 8 | } 9 | \usage{ 10 | redisExpire(key, seconds) 11 | redisPexpire(key, milliseconds) 12 | } 13 | \arguments{ 14 | \item{key}{The character key on which to set the timeout.} 15 | \item{seconds}{The integer timeout in seconds.} 16 | \item{milliseconds}{The integer timeout in milliseconds.} 17 | } 18 | \details{Operations that modify value(s) corresponding to a key subsequent 19 | to the \code{redisExpire} function clear the timeout, removing the expiration. 20 | The \code{redisExpire} function can't set a new timeout value once a timeout 21 | has been set on a key. 22 | } 23 | \value{ 24 | Boolean TRUE if the timeout command was successful, FALSE otherwise. 25 | } 26 | \references{ 27 | http://redis.io/commands 28 | } 29 | \author{ 30 | B. W. Lewis 31 | } 32 | \seealso{ 33 | \code{\link{redisExpireAt}} 34 | } 35 | \examples{ 36 | \dontrun{ 37 | redisConnect() 38 | redisLPush('x',runif(5)) 39 | redisExpire('x', 3) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /man/redisSUnion.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSUnion} 2 | \alias{redisSUnion} 3 | \title{ 4 | Return the union of two or more sets. 5 | } 6 | \description{ 7 | Return the union of two or more sets. 8 | } 9 | \usage{ 10 | redisSUnion(keys, ...) 11 | } 12 | \arguments{ 13 | \item{keys}{ 14 | A vector or list of keys corresponding to sets. May also be a single 15 | key. 16 | } 17 | \item{...}{ 18 | Additional keys corresponding to sets. See the examples below. 19 | } 20 | } 21 | \details{ 22 | The first argument may be a vector of set names, a list of set names, 23 | or a single set name. If only a single set name is specified, specify 24 | more sets as additional function arguments as shown in the examples. 25 | } 26 | \value{ 27 | A list of elements in the union of the specified sets, or 28 | NULL if the intersection is the empty set. 29 | } 30 | \references{ 31 | http://redis.io/commands 32 | } 33 | \author{ 34 | B. W. Lewis 35 | } 36 | \seealso{ 37 | \code{\link{redisSInter}} 38 | } 39 | \examples{ 40 | \dontrun{ 41 | redisConnect() 42 | redisSAdd('A',1) 43 | redisSAdd('A',2) 44 | redisSAdd('B',4) 45 | redisSUnion('A','B') 46 | redisSUnion(c('A','B')) 47 | redisSUnion(list('A','B')) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/redisSDiff.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSDiff} 2 | \alias{redisSDiff} 3 | \title{ 4 | Return the difference of two or more sets. 5 | } 6 | \description{ 7 | Return the (set) difference of two or more sets. 8 | } 9 | \usage{ 10 | redisSDiff(keys, ...) 11 | } 12 | \arguments{ 13 | \item{keys}{ 14 | A vector or list of keys corresponding to sets. May also be a single 15 | key. 16 | } 17 | \item{...}{ 18 | Additional keys corresponding to sets. See the examples below. 19 | } 20 | } 21 | \details{ 22 | The first argument may be a vector of set names, a list of set names, 23 | or a single set name. If only a single set name is specified, specify 24 | more sets as additional function arguments as shown in the examples. 25 | } 26 | \value{ 27 | A list of elements in the difference of the specified sets, or 28 | NULL if the intersection is the empty set. 29 | } 30 | \references{ 31 | http://redis.io/commands 32 | } 33 | \author{ 34 | B. W. Lewis 35 | } 36 | \seealso{ 37 | \code{\link{redisSDiff}} 38 | } 39 | \examples{ 40 | \dontrun{ 41 | redisConnect() 42 | redisSAdd('A',1) 43 | redisSAdd('A',2) 44 | redisSAdd('B',4) 45 | redisSDiff('A','B') 46 | redisSDiff(c('A','B')) 47 | redisSDiff(list('A','B')) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/redisLRange.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLRange} 2 | \alias{redisLRange} 3 | \title{Copy values from a list.} 4 | \description{Return the elements of a list between the start and end 5 | indices, inclusively. 6 | } 7 | \usage{ 8 | redisLRange(key, start, end, ...) 9 | } 10 | \arguments{ 11 | \item{key}{A key corresponding to a list. } 12 | \item{start}{The beginning index from which to read list elements. } 13 | \item{end}{The ending index.} 14 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 15 | } 16 | \details{ 17 | List indices begin with 0. If the start or end indices are beyond the bounds 18 | of the list, return the list elements up to the index bounds. 19 | } 20 | \value{An indexed list containing the returned values. An error will be 21 | thrown if the specified key does not correspond to a list or if the key 22 | can't be found. 23 | } 24 | \references{ 25 | http://redis.io/commands 26 | } 27 | \author{ 28 | B. W. Lewis 29 | } 30 | \seealso{ 31 | \code{\link{redisLPop}} 32 | } 33 | \examples{ 34 | \dontrun{ 35 | redisConnect() 36 | redisLPush('x',1) 37 | redisLPush('x',2) 38 | redisLPush('x',3) 39 | redisLRange('x',0,2) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /man/redisSUnionStore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSUnionStore} 2 | \alias{redisSUnionStore} 3 | \title{ 4 | Store the union of two or more sets. 5 | } 6 | \description{ 7 | Store the union of two or more sets in the specified set. 8 | } 9 | \usage{ 10 | redisSUnionStore(dest, keys, ...) 11 | } 12 | \arguments{ 13 | \item{dest}{ 14 | The destination set in which to store the result. 15 | } 16 | \item{keys}{ 17 | A vector or list of keys corresponding to sets. May also be a single 18 | key. 19 | } 20 | \item{...}{ 21 | Additional keys corresponding to sets. See the examples below. 22 | } 23 | } 24 | \details{ 25 | The \code{keys} argument may be a vector of set names, a list of set names, 26 | or a single set name. If only a single set name is specified, specify 27 | more sets as additional function arguments as shown in the examples. 28 | } 29 | \value{ 30 | A redis status code. 31 | } 32 | \references{ 33 | http://redis.io/commands 34 | } 35 | \author{ 36 | B. W. Lewis 37 | } 38 | \seealso{ 39 | \code{\link{redisSInterStore}} 40 | } 41 | \examples{ 42 | \dontrun{ 43 | redisConnect() 44 | redisSAdd('A',1) 45 | redisSAdd('A',2) 46 | redisSAdd('A',3) 47 | redisSAdd('B',2) 48 | redisSUnionStore('C','A','B') 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /man/redisSDiffStore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSDiffStore} 2 | \alias{redisSDiffStore} 3 | \title{ 4 | Store the difference of two or more sets. 5 | } 6 | \description{ 7 | Store the (set) difference of two or more sets in the specified set. 8 | } 9 | \usage{ 10 | redisSDiffStore(dest, keys, ...) 11 | } 12 | \arguments{ 13 | \item{dest}{ 14 | The destination set in which to store the result. 15 | } 16 | \item{keys}{ 17 | A vector or list of keys corresponding to sets. May also be a single 18 | key. 19 | } 20 | \item{...}{ 21 | Additional keys corresponding to sets. See the examples below. 22 | } 23 | } 24 | \details{ 25 | The \code{keys} argument may be a vector of set names, a list of set names, 26 | or a single set name. If only a single set name is specified, specify 27 | more sets as additional function arguments as shown in the examples. 28 | } 29 | \value{ 30 | A redis status code. 31 | } 32 | \references{ 33 | http://redis.io/commands 34 | } 35 | \author{ 36 | B. W. Lewis 37 | } 38 | \seealso{ 39 | \code{\link{redisSDiff}} 40 | } 41 | \examples{ 42 | \dontrun{ 43 | redisConnect() 44 | redisSAdd('A',1) 45 | redisSAdd('A',2) 46 | redisSAdd('A',3) 47 | redisSAdd('B',2) 48 | redisSDiffStore('C','A','B') 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/zsetTest.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisZAdd("A", 1, "w") 10 | redisZAdd("A", 1, "x") 11 | redisZAdd("A", 2, "y") 12 | checkEquals("1", redisZAdd("A", 3, "z")) 13 | 14 | checkEquals("4", redisZCard("A")) 15 | 16 | checkEquals("1", redisZRem("A", "w")) 17 | 18 | checkEquals(2, as.integer(redisZIncrBy("A","x",1))) 19 | 20 | checkEquals("2", redisZRank("A", "z")) 21 | 22 | checkEquals(TRUE,all(c('y','z') == unlist(redisZRange("A",1,2)))) 23 | 24 | checkEquals(TRUE,all(c('x','y') == redisZRangeByScore("A",min=0,max=2))) 25 | 26 | checkEquals("3", redisZUnionStore("B",c("A","A"))) 27 | 28 | checkEquals("2",redisZRemRangeByScore("B",min=0,max=4)) 29 | 30 | checkEquals("1", redisZInterStore("C",c("A","B"))) 31 | 32 | checkEquals("1", redisZRemRangeByRank("B",0,1)) 33 | 34 | checkEquals(TRUE, all(c("x","y","z") == unlist(redisSort("A",alpha=TRUE,decreasing=FALSE)))) 35 | checkEquals(TRUE, all(c("z","y","x") == unlist(redisSort("A",alpha=TRUE,decreasing=TRUE)))) 36 | 37 | redisFlushAll() 38 | } 39 | -------------------------------------------------------------------------------- /man/redisSInterStore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSInterStore} 2 | \alias{redisSInterStore} 3 | \title{ 4 | Store intersection of two or more sets. 5 | } 6 | \description{ 7 | Find the intersection of two or more sets, storing the result in the 8 | specified set. 9 | } 10 | \usage{ 11 | redisSInterStore(dest, keys, ...) 12 | } 13 | \arguments{ 14 | \item{dest}{ 15 | The destination set in which to store the result. 16 | } 17 | \item{keys}{ 18 | A vector or list of keys corresponding to sets. May also be a single 19 | key. 20 | } 21 | \item{...}{ 22 | Additional keys corresponding to sets. See the examples below. 23 | } 24 | } 25 | \details{ 26 | The \code{keys} argument may be a vector of set names, a list of set names, 27 | or a single set name. If only a single set name is specified, specify 28 | more sets as additional function arguments as shown in the examples. 29 | } 30 | \value{ 31 | A redis status code. 32 | } 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisSUnionStore}} 41 | } 42 | \examples{ 43 | \dontrun{ 44 | redisConnect() 45 | redisSAdd('A',1) 46 | redisSAdd('A',2) 47 | redisSAdd('A',3) 48 | redisSAdd('B',2) 49 | redisSInterStore('C','A','B') 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /man/redisSInter.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSInter} 2 | \alias{redisSInter} 3 | \title{ 4 | Find and return the intersection of two or more sets. 5 | } 6 | \description{ 7 | Find and return the intersection of two or more sets. 8 | } 9 | \usage{ 10 | redisSInter(keys, ...) 11 | } 12 | \arguments{ 13 | \item{keys}{ 14 | A vector or list of keys corresponding to sets. May also be a single 15 | key. 16 | } 17 | \item{...}{ 18 | Additional keys corresponding to sets. See the examples below. 19 | } 20 | } 21 | \details{ 22 | The first argument may be a vector of set names, a list of set names, 23 | or a single set name. If only a single set name is specified, specify 24 | more sets as additional function arguments as shown in the examples. 25 | } 26 | \value{ 27 | A list of elements in the intersection of the specified sets, or 28 | NULL if the intersection is the empty set. 29 | } 30 | \references{ 31 | http://redis.io/commands 32 | } 33 | \author{ 34 | B. W. Lewis 35 | } 36 | \seealso{ 37 | \code{\link{redisSUnion}} 38 | } 39 | \examples{ 40 | \dontrun{ 41 | redisConnect() 42 | redisSAdd('A',1) 43 | redisSAdd('A',2) 44 | redisSAdd('A',3) 45 | redisSAdd('B',2) 46 | redisSInter('A','B') 47 | redisSInter(c('A','B')) 48 | redisSInter(list('A','B')) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /man/rredis-package.Rd: -------------------------------------------------------------------------------- 1 | \name{rredis-package} 2 | \alias{rredis} 3 | \docType{package} 4 | \title{ Redis interface package. } 5 | \description{ 6 | 7 | The \code{rredis} package provides a native R interface to Redis. Redis is an 8 | in memory key/value database with many innovative features, see 9 | http://redis.io for details. It supports data persistence, networked 10 | client/server operation, command pipelining, structured value types, data 11 | expiration, multicast-like publish/subscribe, and it's very fast. 12 | 13 | } 14 | \details{ 15 | Package options: 16 | \itemize{ 17 | \item \code{options('redis:num'=TRUE)} Set this option to TRUE to return 18 | Redis \code{:} messages as numeric values. This was the default behavior 19 | of the rredis package for all versions prior to 1.6.9. For versions 20 | of the R package later than that, redis \code{:} messages are returned 21 | as raw Redis string values to correspond to the data types stored in Redis. 22 | Set this option to revert to the old behavior. 23 | 24 | Redis commands affected by this option importantly include the increment 25 | and decrement operations. 26 | } 27 | } 28 | \author{ 29 | B. W. Lewis 30 | 31 | Maintainer: B. W. Lewis 32 | } 33 | \keyword{ package } 34 | -------------------------------------------------------------------------------- /man/redisHIncrBy.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHIncrBy} 2 | \alias{redisHIncrBy} 3 | \alias{redisHIncrByFloat} 4 | \title{Increment a value.} 5 | \description{Increment the value corresponding to the given key/field 6 | combination by the specified value. 7 | } 8 | \usage{ 9 | redisHIncrBy(key, field, value, ...) 10 | } 11 | \arguments{ 12 | \item{key}{A key name.} 13 | \item{field}{A field name.} 14 | \item{value}{The value to increment by (integer, numeric, or character).} 15 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 16 | } 17 | \details{ 18 | The value should be an integer 19 | (\code{redisHIncrBy}) or a numeric value (\code{redisHIncrByFloat}). 20 | If the key/field value does not exist or contains a 21 | value of a wrong type, set the 22 | key to the value of "0" before to perform the operation. 23 | } 24 | \value{ 25 | The new value of key after the increment, returned as a character 26 | string. 27 | } 28 | \references{ 29 | http://redis.io/commands 30 | } 31 | \author{ 32 | B. W. Lewis 33 | } 34 | 35 | \seealso{ 36 | \code{\link{redisHSet}} 37 | } 38 | \examples{ 39 | \dontrun{ 40 | # Note initial value must be a raw character string! 41 | redisHSet('A','x',charToRaw('5')) 42 | redisHIncrBy('A','x',3) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /man/redisZUnionStore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZUnionStore} 2 | \alias{redisZUnionStore} 3 | \title{ 4 | redisZUnionStore 5 | } 6 | \description{ 7 | Store the union of two sorted sets into another sorted set. 8 | } 9 | \usage{ 10 | redisZUnionStore(dstkey, keys, weights = c(), aggregate = NULL, ...) 11 | } 12 | \arguments{ 13 | \item{dstkey}{ 14 | The destination set name. 15 | } 16 | \item{keys}{ 17 | A vector or list of sorted set names. 18 | } 19 | \item{weights}{ 20 | A set of weights equal in length to the \code{keys} argument, or NULL (default). If specified, the weights associated with the members of each set will be multiplied by the specified weight values. 21 | } 22 | \item{aggregate}{ 23 | A character value of either "SUM" "MIN" or "MAX" indicating how the resulting weights should be aggregated. 24 | } 25 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 26 | } 27 | \details{ 28 | See the Redis documentation for details. 29 | } 30 | \value{ 31 | The number of elements stored in the destination set. 32 | %% If it is a LIST, use 33 | %% \item{comp1 }{Description of 'comp1'} 34 | %% \item{comp2 }{Description of 'comp2'} 35 | %% ... 36 | } 37 | \references{ 38 | http://redis.io/commands 39 | } 40 | \author{ 41 | B. W. Lewis 42 | } 43 | -------------------------------------------------------------------------------- /man/redisZInterStore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZInterStore} 2 | \alias{redisZInterStore} 3 | \title{ 4 | redisZInterStore 5 | } 6 | \description{ 7 | Store the intersection of two sorted sets into another sorted set. 8 | } 9 | \usage{ 10 | redisZInterStore(dstkey, keys, weights = c(), aggregate = NULL, ...) 11 | } 12 | \arguments{ 13 | \item{dstkey}{ 14 | The destination set name. 15 | } 16 | \item{keys}{ 17 | A vector or list of sorted set names. 18 | } 19 | \item{weights}{ 20 | A set of weights equal in length to the \code{keys} argument, or NULL (default). If specified, the weights associated with the members of each set will be multiplied by the specified weight values. 21 | } 22 | \item{aggregate}{ 23 | A character value of either "SUM" "MIN" or "MAX" indicating how the resulting weights should be aggregated. 24 | } 25 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 26 | } 27 | \details{ 28 | See the Redis documentation for details. 29 | } 30 | \value{ 31 | The number of elements stored in the destination set. 32 | %% If it is a LIST, use 33 | %% \item{comp1 }{Description of 'comp1'} 34 | %% \item{comp2 }{Description of 'comp2'} 35 | %% ... 36 | } 37 | \references{ 38 | http://redis.io/commands 39 | } 40 | \author{ 41 | B. W. Lewis 42 | } 43 | -------------------------------------------------------------------------------- /man/redisType.Rd: -------------------------------------------------------------------------------- 1 | \name{redisType} 2 | \alias{redisType} 3 | \title{Query a Redis value type.} 4 | \description{Return a description of the type of the value 5 | corresponding to the specified key. 6 | } 7 | \usage{ 8 | redisType(key) 9 | } 10 | \arguments{ 11 | \item{key}{The key to look up.} 12 | } 13 | \details{ 14 | The Redis database differentiates three types of values. The value 15 | types determine how Redis operates on the key/value pairs, not what 16 | kind of data may be contained within. Each value type 17 | may store generic R objects, binary blobs, or character strings. 18 | The Redis value types are: 19 | 20 | string: A single value is associated with the key 21 | 22 | list: A stack of values is associated with the key 23 | 24 | set: A set of values is associated with the key. 25 | 26 | Values of "list" and "set" types have available to them special stack and 27 | set operations, respectively. 28 | } 29 | \value{ 30 | A descriptive character string that may be one of 31 | "none", "string", "list", or "set". 32 | "none" is returned if the key does not exist. 33 | } 34 | \references{ 35 | http://redis.io/commands 36 | } 37 | \author{ 38 | B. W. Lewis 39 | } 40 | \seealso{ 41 | \code{\link{redisKeys}} 42 | } 43 | \examples{ 44 | \dontrun{ 45 | redisConnect() 46 | redisSet('x',5) 47 | redisLPush('y',6) 48 | redisType('x') 49 | redisType('y') 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /man/redisLRem.Rd: -------------------------------------------------------------------------------- 1 | \name{redisLRem} 2 | \alias{redisLRem} 3 | \title{Remove elements from a list.} 4 | \description{Remove the fist \code{count} occurences of the given value 5 | from a list corresponding to the specified key. 6 | } 7 | \usage{ 8 | redisLRem(key, count, value) 9 | } 10 | \arguments{ 11 | \item{key}{The desired key corresponding to a list. 12 | } 13 | \item{count}{ 14 | The maximum number of occurences to remove. 15 | } 16 | \item{value}{ 17 | Remove elements matching this value from the list. 18 | } 19 | } 20 | \details{ 21 | Remove the first \code{count} occurrences of the \code{value} element from the 22 | list. If \code{count} is zero all the elements are removed. If count is 23 | negative elements are removed from tail to head, instead of the default removal 24 | behavior from head to tail. So for example \code{redisLRem} with count -2 and 25 | value "hello" applied to the list (a,b,c,hello,x,hello,hello) will 26 | yield the list (a,b,c,hello,x). The number of removed elements is returned as 27 | an integer upon success. Note that 28 | non-existing keys are considered as empty lists. 29 | } 30 | \value{ 31 | The number of occurrences removed. 32 | } 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisLPush}} 41 | } 42 | \examples{ 43 | \dontrun{ 44 | redisConnect() 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/setTest.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisSAdd("A",1) 10 | redisSAdd("A",2) 11 | redisSAdd("A",3) 12 | checkEquals("3", redisSCard("A")) 13 | 14 | redisSAdd("B",2) 15 | checkEquals(2, redisSInter("A","B")[[1]]) 16 | 17 | redisSInterStore("C", c("A", "B")) 18 | checkEquals(TRUE, all(2 %in% redisSMembers("C"))) 19 | 20 | checkEquals(TRUE, redisSIsMember("A", 3)) 21 | checkEquals(2, redisSRandMember("B")) 22 | 23 | checkEquals(TRUE, all(list(1, 2, 3) %in% redisSUnion("A", "B"))) 24 | redisSUnionStore("C", "A", "B") 25 | checkEquals(TRUE, all(list(1, 2, 3) %in% redisSMembers("C"))) 26 | 27 | redisSUnionStore("C", c("A", "B")) # Alternate form 28 | checkEquals(TRUE, all(list(1, 2, 3) %in% redisSMembers("C"))) 29 | 30 | checkEquals(TRUE, all(list(1, 3) %in% redisSDiff("A","B"))) 31 | redisSDiffStore("C", "A", "B") 32 | checkEquals(TRUE, all(list(1, 3) %in% redisSMembers("C"))) 33 | 34 | redisSRem("A", 1) 35 | checkEquals("2", redisSCard("A")) 36 | 37 | redisSPop("A") 38 | checkEquals("1", redisSCard("A")) 39 | 40 | x <- redisSMembers("A")[[1]] 41 | redisSMove("A", "B", x) 42 | checkEquals(TRUE, all(x %in% redisSMembers("B"))) 43 | 44 | redisFlushAll() 45 | } 46 | -------------------------------------------------------------------------------- /man/redisBLPop.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBLPop} 2 | \alias{redisBLPop} 3 | \title{Blocking List Pop} 4 | \description{Pop the first available value from a key or list of keys, 5 | blocking until a value is available.} 6 | \usage{ 7 | redisBLPop(keys, timeout = 0, ...) 8 | } 9 | %- maybe also 'usage' for other objects documented here. 10 | \arguments{ 11 | \item{keys}{A character key value or vector of key values to monitor.} 12 | \item{timeout}{ 13 | A timeout in seconds after which, if no value is available, the function 14 | returns NULL. A value of zero indicates block indefinitely. 15 | } 16 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 17 | } 18 | \details{ 19 | redisBLPop blocks until at least one of the keys exists and contains a 20 | non-empty value, or until the specified timeout period is reached, whichever 21 | comes first. Keys are scanned in the order that they are specified. 22 | } 23 | \value{ 24 | redisBLPop returns NULL after the timeout period, or a list containing: 25 | \item{key}{The first key encountered with an available value,} 26 | \item{value}{The corresponding value.} 27 | } 28 | \references{ 29 | http://redis.io/commands 30 | } 31 | \author{ 32 | B. W. Lewis 33 | } 34 | \seealso{ 35 | \code{redisBRpop} 36 | } 37 | \examples{ 38 | \dontrun{ 39 | redisConnect() 40 | redisBLpop('x', 5) 41 | redisLPush('x',runif(5)) 42 | redisBLPop('x') 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /man/redisBRPop.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBRPop} 2 | \alias{redisBRPop} 3 | \title{Blocking List Pop} 4 | \description{Pop the first available value from a key or list of keys, 5 | blocking until a value is available.} 6 | \usage{ 7 | redisBRPop(keys, timeout = 0, ...) 8 | } 9 | %- maybe also 'usage' for other objects documented here. 10 | \arguments{ 11 | \item{keys}{A character key value or vector of key values to monitor.} 12 | \item{timeout}{ 13 | A timeout in seconds after which, if no value is available, the function 14 | returns NULL. A value of zero indicates block indefinitely. 15 | } 16 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 17 | } 18 | \details{ 19 | redisBRPop blocks until at least one of the keys exists and contains a 20 | non-empty value, or until the specified timeout period is reached, whichever 21 | comes first. Keys are scanned in the order that they are specified. 22 | } 23 | \value{ 24 | redisBRPop returns NULL after the timeout period, or a list containing: 25 | \item{key}{The first key encountered with an available value,} 26 | \item{value}{The corresponding value.} 27 | } 28 | \references{ 29 | http://redis.io/commands 30 | } 31 | \author{ 32 | B. W. Lewis 33 | } 34 | \seealso{ 35 | \code{redisBLpop} 36 | } 37 | \examples{ 38 | \dontrun{ 39 | redisConnect() 40 | redisBLpop('x', 5) 41 | redisLPush('x',runif(5)) 42 | redisBRPop('x') 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/bitopTest.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisSetBit("bitmapr_test02", 10, 1) 10 | checkEquals("1", redisGetBit("bitmapr_test02", 10)) 11 | 12 | 13 | redisSetBit("bitmapr_test03", 1, 1) 14 | redisSetBit("bitmapr_test03", 10, 1) 15 | redisSetBit("bitmapr_test03", 100, 1) 16 | checkEquals("3", redisBitCount("bitmapr_test03")) 17 | 18 | sourcekeys <- c("bitmapr_test04_src_1", "bitmapr_test04_src_2","bitmapr_test04_src_3") 19 | 20 | redisSetBit(sourcekeys[1], 1, 1) 21 | redisSetBit(sourcekeys[1], 2, 1) 22 | redisSetBit(sourcekeys[1], 3, 1) 23 | redisSetBit(sourcekeys[1], 100, 1) 24 | 25 | redisSetBit(sourcekeys[2], 1, 1) 26 | redisSetBit(sourcekeys[2], 4, 1) 27 | redisSetBit(sourcekeys[2], 5, 1) 28 | redisSetBit(sourcekeys[2], 100, 1) 29 | 30 | redisSetBit(sourcekeys[3], 1, 1) 31 | redisSetBit(sourcekeys[3], 6, 1) 32 | redisSetBit(sourcekeys[3], 7, 1) 33 | redisSetBit(sourcekeys[3], 100, 1) 34 | 35 | operation <- "AND" 36 | destkey <- "bitmapr_test04_dest" 37 | 38 | redisBitOp(operation, destkey, sourcekeys) 39 | checkEquals("2", redisBitCount(destkey)) 40 | checkEquals("0", redisGetBit(destkey, 5)) 41 | checkEquals("1", redisGetBit(destkey, 1)) 42 | 43 | redisFlushAll() 44 | } 45 | -------------------------------------------------------------------------------- /R/pubsub.R: -------------------------------------------------------------------------------- 1 | `redisSubscribe` <- function(channels, pattern=FALSE) 2 | { 3 | cmd <- 'SUBSCRIBE' 4 | channels <- as.list(channels) 5 | channels <- lapply(channels, charToRaw) 6 | if(pattern) { 7 | cmd <- 'PSUBSCRIBE' 8 | if(length(channels)>1) 9 | warning("Pattern subscription with multiple arguments") 10 | } 11 | x <- do.call('.redisCmd', c(list(.raw(cmd)),channels)) 12 | len <- length(channels) - 1L 13 | if(len > 0L) 14 | x <- c(x, replicate(len, .getResponse(), simplify=FALSE)) 15 | x 16 | } 17 | 18 | `redisUnsubscribe` <- function(channels, pattern=FALSE) 19 | { 20 | cmd <- 'UNSUBSCRIBE' 21 | channels <- as.list(channels) 22 | channels <- lapply(channels, charToRaw) 23 | if(pattern){ 24 | cmd <- 'PUNSUBSCRIBE' 25 | if(length(channels)>1) warning("Pattern subscription with multiple arguments") 26 | } 27 | x <- do.call('.redisCmd', c(list(.raw(cmd)),channels)) 28 | len <- length(channels) - 1L 29 | if(len > 0L) 30 | x <- c(x, replicate(len, .getResponse(), simplify=FALSE)) 31 | x 32 | } 33 | 34 | `redisPublish` <- function(channel, message) 35 | { 36 | do.call('.redisCmd', list(.raw('PUBLISH'),.raw(channel),message)) 37 | } 38 | 39 | # Callback handler 40 | `redisMonitorChannels` <- function() 41 | { 42 | x <- .getResponse() 43 | if(length(x)!=3 && x[[1]] != "message") return(x) 44 | if(exists(x[[2]],mode="function")) { 45 | return(do.call(x[[2]],as.list(x[[3]]))) 46 | } 47 | x 48 | } 49 | -------------------------------------------------------------------------------- /man/redisSetPipeline.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSetPipeline} 2 | \alias{redisSetPipeline} 3 | \title{Set the Redis message blocking state.} 4 | \description{ 5 | Use \code{redisSetPipeline} to set the rredis client to blocking (default) 6 | or non-blocking Redis communication mode. 7 | } 8 | \usage{ 9 | redisSetPipeline( value = FALSE ) 10 | } 11 | \arguments{ 12 | \item{value}{TRUE indicates Redis pipelined mode, FALSE non-pipelined mode.} 13 | } 14 | \details{ 15 | The rredis client blocks for a response from a connected Redis server 16 | after each transaction in non-pipelined mode (the default). 17 | When in pipelined mode, transactions are issued without 18 | servicing Redis server responses, and server responses must be manually 19 | serviced with the \code{redisGetResponse} function. 20 | 21 | Pipelined mode can improve performance in some circumstances like 22 | lots of repeated \code{redisSet} operations. When using pipelined 23 | mode, don't forget to periodically service responses from the Redis 24 | server (results are cached on the server until requested). 25 | 26 | Note that use of commands like \code{redisMSet} can sometimes obviate the 27 | need to use non-blocking mode. 28 | } 29 | \value{ 30 | The new pipeline mode (TRUE/FALSE) is invisibly returned. 31 | } 32 | \author{ 33 | B. W. Lewis 34 | } 35 | 36 | \seealso{ 37 | \code{\link{redisGetResponse}} 38 | } 39 | \examples{ 40 | \dontrun{ 41 | redisConnect() 42 | redisSetPipeline(TRUE) 43 | redisLPush('x',pi) 44 | redisLPush('x',exp(1)) 45 | redisGetResponse() 46 | redisSetPipeline(FALSE) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /man/redisZRangeByScore.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRangeByScore} 2 | \alias{redisZRangeByScore} 3 | %- Also NEED an '\alias' for EACH other topic documented here. 4 | \title{ 5 | redisZRangeByScore 6 | } 7 | \description{ 8 | Return the all the elements in the sorted set at key with a score between 9 | \code{min} and \code{max} (including elements with score equal to 10 | \code{min} or \code{max}). 11 | } 12 | \usage{ 13 | redisZRangeByScore(key, min, max, offset = NULL, count = NULL, 14 | withscores = FALSE, ...) 15 | } 16 | %- maybe also 'usage' for other objects documented here. 17 | \arguments{ 18 | \item{key}{ 19 | The set name. 20 | } 21 | \item{min}{ 22 | Minimum score. 23 | } 24 | \item{max}{ 25 | Maximum score. 26 | } 27 | \item{offset}{ 28 | Limit the results by excluding the first \code{offset} items. Requires 29 | also the use of \code{count}. 30 | } 31 | \item{count}{ 32 | Limit the results to the first \code{count} items. Requires also the use 33 | of \code{offset}. 34 | } 35 | \item{withscores}{ 36 | Also return the scores. 37 | } 38 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 39 | } 40 | \details{ 41 | The \code{offset} and \code{count} arguments must both be specified if used. 42 | } 43 | \value{ 44 | See the Redis documentation for more information. 45 | %% If it is a LIST, use 46 | %% \item{comp1 }{Description of 'comp1'} 47 | %% \item{comp2 }{Description of 'comp2'} 48 | %% ... 49 | } 50 | \references{ 51 | http://redis.io/commands 52 | } 53 | \author{ 54 | B. W. Lewis 55 | } 56 | -------------------------------------------------------------------------------- /man/redisGet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisGet} 2 | \alias{redisGet} 3 | \title{Retrieve a value from Redis.} 4 | \description{Retrieve a value identified by a key 5 | from the Redis database. 6 | } 7 | \usage{ 8 | redisGet(key, ...) 9 | } 10 | \arguments{ 11 | \item{key}{ 12 | The (required) character identifier for the value to be looked up. 13 | } 14 | \item{...}{ Optional additional arguments passed to \code{redisCmd}. 15 | Specify \code{raw=TRUE} to skip de-serialization of the data.} 16 | } 17 | \details{ 18 | The key must not contain spaces or newline characters (otherwise an error will 19 | be thrown). The \code{raw} option is used to retrieve binary data from other 20 | languages. 21 | } 22 | \value{ 23 | The value corresponding to the specified key, or NULL if the matching key 24 | contained no value or if no matching key was found. 25 | 26 | Use the \code{raw=TRUE} option to return Redis values in raw binary form, which 27 | can optionally later be converted to character using the \code{rawToChar} 28 | function. 29 | 30 | A Redis value that does not represent a serialized R value is returned as a 31 | \code{character} R value with an attribute named "redis string value." Subsequent 32 | uploads of that value to Redis will send the character-valued data in raw form 33 | (not as a serialized R value), preserving the original nature of the data in 34 | Redis. 35 | } 36 | \references{ 37 | http://redis.io/commands 38 | } 39 | \author{ 40 | B. W. Lewis 41 | } 42 | 43 | \seealso{ 44 | \code{\link{redisSet}} 45 | } 46 | \examples{ 47 | \dontrun{ 48 | redisSet('x',runif(5)) 49 | redisGet('x') 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/pubsub.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | # redusMonitorChannels blocks forever until a message is received. We 5 | # use a background R process to send us some test messages. 6 | publisher <- function() 7 | 8 | { 9 | Rbin <- paste(R.home(component="bin"), "R", sep="/") 10 | cmd <- "require(rredis);redisConnect();Sys.sleep(2);redisPublish('channel1', charToRaw('1'));redisPublish('channel2', charToRaw('2'))" 11 | args <- c("--slave", "-e", paste("\"", cmd, "\"", sep="")) 12 | system(paste(c(Rbin, args), collapse=" "), intern=FALSE, wait=FALSE) 13 | } 14 | 15 | if(Sys.getenv("RunRRedisTests") == "yes") 16 | { 17 | redisConnect() 18 | redisFlushAll() 19 | redisPublish("channel1", charToRaw("A raw charachter data message example")) 20 | redisPublish("channel2", charToRaw("A raw charachter data message example")) 21 | 22 | # Define a callback function to process messages from channel 1: 23 | channel1 <- function(x) { 24 | cat("Message received from channel 1: ",x,"\n") 25 | checkEquals("1", x); 26 | } 27 | # Define a callback function to process messages from channel 2: 28 | channel2 <- function(x) { 29 | cat("Message received from channel 2: ",x,"\n") 30 | checkEquals("2", x); 31 | } 32 | redisSubscribe(c('channel1','channel2')) 33 | # Monitor channels for a few seconds until the background R process sends us 34 | # some messages... 35 | publisher() 36 | redisMonitorChannels() 37 | redisMonitorChannels() 38 | redisUnsubscribe(c('channel1','channel2')) 39 | 40 | redisFlushAll() 41 | } 42 | -------------------------------------------------------------------------------- /man/redisSlaveOf.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSlaveOf} 2 | \alias{redisSlaveOf} 3 | \title{redisSlaveOf} 4 | \description{ 5 | Change Redis replication settings. 6 | } 7 | \usage{ 8 | redisSlaveOf(host, port) 9 | } 10 | \arguments{ 11 | \item{host}{The host name of a master Redis server.} 12 | \item{port}{The port of a master Redis server.} 13 | } 14 | \details{ 15 | (The following details are adapted from the Redis Wiki manual 16 | referenced below.) 17 | 18 | The redisSlaveOf command can change the replication settings of a slave on the 19 | fly. If a Redis server is arleady acting as slave, the function 20 | redisSlaveOf(host="no",port="one") 21 | will turn off the replicaiton turning the Redis server into a MASTER. In 22 | the proper form redisSlaveOf(hostname,port) will make the server a slave of the 23 | specific server listening at the specified hostname and port. 24 | 25 | If a server is already a slave of some master, redisSlaveOf(hostname,port )will 26 | stop the replication against the old server and start the synchrnonization 27 | against the new one discarding the old dataset. 28 | 29 | The form redisSlaveOf(host="no",port="one") will stop replication, 30 | turning the server into a 31 | MASTER but will not discard the replication. So if the old master stop working 32 | it is possible to turn the slave into a master and set the application to use 33 | the new master in read/write. Later when the other Redis server will be fixed 34 | it can be configured in order to work as slave. 35 | } 36 | \value{ 37 | A Redis status message is returned. 38 | } 39 | \references{ 40 | http://redis.io/commands 41 | } 42 | \author{ 43 | B. W. Lewis 44 | } 45 | -------------------------------------------------------------------------------- /man/redisSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSet} 2 | \alias{redisSet} 3 | \title{Store a value in Redis.} 4 | \description{Store a value identified by a character key name 5 | in the Redis database. Any existing value with the same key will be replaced 6 | by the new value unless NX is set to TRUE. 7 | } 8 | \usage{ 9 | redisSet(key, value, NX = FALSE) 10 | } 11 | \arguments{ 12 | \item{key}{ 13 | The (required) character identifier for the value to be stored. 14 | } 15 | \item{value}{ 16 | The (required) object to associate with the key. 17 | } 18 | \item{NX}{ 19 | If NX = TRUE, existing values will not be replaced. 20 | } 21 | } 22 | \details{ 23 | The value is copied to the Redis server. The value to be stored can be any 24 | serializable R object up to the Redis maximum object size (excluding, for 25 | example, external pointer references). References to other R objects or 26 | environments inside the value are not guaranteed to be preserved. 27 | 28 | In order to store strings that can easily be read by other clients, first 29 | convert the character object using the 30 | \code{\link{charToRaw}} function as shown in the 31 | examples. 32 | } 33 | \value{ 34 | The value ``OK'' is returned upon success (conforming to the usual 35 | Redis behavior). 36 | } 37 | \references{ 38 | http://redis.io/commands 39 | } 40 | \author{ 41 | B. W. Lewis 42 | } 43 | 44 | \seealso{ 45 | \code{\link{redisGet}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | # Store an R object with the key 'x': 50 | redisSet('x',runif(5)) 51 | } 52 | \dontrun{ 53 | # Store a string that can be easily read by other clients: 54 | redisSet('x',charToRaw('Hello Redis clients')) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /man/redisGetSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisGetSet} 2 | \alias{redisGetSet} 3 | \title{Store a value in Redis, returning the previously defined value.} 4 | \description{Store a value identified by a character key name 5 | in the Redis database, returning the previously defined value or NULL if 6 | the key was not already associated with a value. 7 | } 8 | \usage{ 9 | redisGetSet(key, value, ...) 10 | } 11 | \arguments{ 12 | \item{key}{ 13 | The (required) character identifier for the value to be stored. 14 | } 15 | \item{value}{ The (required) object to associate with the key. } 16 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 17 | } 18 | \details{ 19 | The key must not contain spaces or newline characters (otherwise an error will be thrown). 20 | 21 | The value object is copied to the Redis server. 22 | The value to be stored may can be any 23 | serializable R object up to the Redis maximum object size 24 | (excluding, for example, external pointer references). 25 | References to other R objects or environments inside the value are not 26 | guaranteed to be preserved. 27 | 28 | In order to store strings that can easily be read by other clients, first 29 | convert the character object using the 30 | \code{\link{charToRaw}} function as shown in the 31 | examples. 32 | } 33 | \value{ 34 | The previous value associated with key or NULL if no previous 35 | association exists. 36 | } 37 | \references{ 38 | http://redis.io/commands 39 | } 40 | \author{ 41 | B. W. Lewis 42 | } 43 | 44 | \seealso{ 45 | \code{\link{redisGet}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | # Store an R object with the key 'x': 50 | redisGetSet('x',runif(5)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /man/redisHSet.Rd: -------------------------------------------------------------------------------- 1 | \name{redisHSet} 2 | \alias{redisHSet} 3 | \title{Store a hash value in Redis.} 4 | \description{Store a value identified by a character key name and field 5 | in the Redis database. Any existing value with the same key/field 6 | will be replaced by the new value unless NX is set to TRUE. 7 | } 8 | \usage{ 9 | redisHSet(key, field, value, NX = FALSE) 10 | } 11 | \arguments{ 12 | \item{key}{ 13 | The (required) character identifier for the key name. 14 | } 15 | \item{field}{ 16 | The (required) character identifier for the field name. 17 | } 18 | \item{value}{ 19 | The (required) object to associate with the key/field. 20 | } 21 | \item{NX}{ 22 | If NX = TRUE, existing values will not be replaced. 23 | } 24 | } 25 | \details{ 26 | Redis hash values store values in one or more fields associated with a single 27 | key name. 28 | 29 | The value to be stored can be any 30 | serializable R object up to the Redis maximum object size 31 | (excluding, for example, external pointer references). 32 | References to other R objects or environments inside the value are not 33 | guaranteed to be preserved. 34 | 35 | In order to store strings that can easily be read by other clients, first 36 | convert the character object using the 37 | \code{\link{charToRaw}} function as shown in the 38 | examples. 39 | } 40 | \value{ 41 | TRUE is returned on success. 42 | If NX = FALSE and a value already exists, the value will not be replaced 43 | and FALSE will be returned. 44 | } 45 | \references{ 46 | http://redis.io/commands 47 | } 48 | \author{ 49 | B. W. Lewis 50 | } 51 | 52 | \seealso{ 53 | \code{\link{redisHGet}} 54 | } 55 | \examples{ 56 | \dontrun{ 57 | redisHSet('A', 'x',runif(5)) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/misc.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | 9 | redisSetPipeline(TRUE) 10 | redisMulti() 11 | redisSet("x", pi) 12 | redisExec() 13 | redisSetPipeline(FALSE) 14 | redisGetResponse() 15 | checkEquals(pi, redisGet("x")) 16 | 17 | checkEquals("x", redisKeys()) 18 | checkEquals("x", redisRandomKey()) 19 | 20 | redisPexpire("x", 1000) 21 | redisPTTL("x") 22 | redisPersist("x") 23 | 24 | redisPexpireAt("x", 1000*(as.numeric(format(Sys.time(), "%s")) + 10)) 25 | redisPersist("x") 26 | redisExpireAt("x", as.numeric(format(Sys.time(), "%s")) + 10) 27 | redisTTL("x") 28 | redisPersist("x") 29 | redisExpire("x", 1) 30 | 31 | # Need to trap this as it depends on external Redis configuration and could 32 | # fail simply due to that 33 | tryCatch({ 34 | redisSet("y", pi) 35 | redisMove("y", 1) 36 | }, error=invisible) 37 | 38 | redisSave() 39 | redisBgSave() 40 | redisBgRewriteAOF() 41 | 42 | redisInfo() 43 | redisDBSize() 44 | redisFlushDB() 45 | 46 | e <- redisGetContext() 47 | redisSetContext(e) 48 | redisSet("x", 1) 49 | 50 | f <- redisConnect(returnRef=TRUE, closeExisting=FALSE) 51 | redisSet("x", 1) 52 | redisSetContext(e) 53 | 54 | checkEquals(1, redisGet("x")) 55 | 56 | redisClose(e) 57 | redisClose(f) 58 | 59 | redisConnect() 60 | redisFlushAll() 61 | 62 | 63 | redisWatch("x") 64 | redisMulti() 65 | redisSet("x", 1) 66 | checkEquals("OK", redisDiscard()) 67 | 68 | redisUnwatch() 69 | checkEquals(FALSE, redisExists("x")) 70 | 71 | } 72 | -------------------------------------------------------------------------------- /man/redisSort.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSort} 2 | \alias{redisSort} 3 | \title{ 4 | redisSort 5 | } 6 | \description{ 7 | Sort a list, set or sorted set (zset). 8 | } 9 | \usage{ 10 | redisSort(key, decreasing = FALSE, alpha = FALSE, by = NULL, 11 | start = NULL, count = NULL, get = NULL, store = NULL, ...) 12 | } 13 | %- maybe also 'usage' for other objects documented here. 14 | \arguments{ 15 | \item{key}{ 16 | The key name of the list, set or zset to be sorted. 17 | } 18 | \item{decreasing}{ 19 | Set the direction of the sort. 20 | } 21 | \item{alpha}{ 22 | Lexicographically sort if true, otherwise try numeric sorting. 23 | } 24 | \item{by}{ 25 | The BY option takes a pattern that is used in order 26 | to generate the key names of the weights used for sorting. Weight key names are 27 | obtained substituting the first occurrence of * with the actual value of the 28 | elements on the list. See the Redis documentation for examples. 29 | } 30 | \item{start}{ 31 | Starting index of the sort. 32 | } 33 | \item{count}{ 34 | Number of entries past start to use for the sort. 35 | } 36 | \item{get}{ 37 | Retrieve external keys. See the Redis documentation. 38 | } 39 | \item{store}{ 40 | Store the results in the specified key. 41 | } 42 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 43 | } 44 | \details{ 45 | Sort the elements contained in the List, Set, or Sorted Set value at key. By 46 | default sorting is numeric with elements being compared as double precision 47 | floating point numbers. 48 | } 49 | \value{ 50 | A list of sorted values, unless \code{store} is specified in which case 51 | the results are stored in the specified key and TRUE is returned. 52 | } 53 | \references{ 54 | http://redis.io/commands 55 | } 56 | \author{ 57 | B. W. Lewis 58 | } 59 | -------------------------------------------------------------------------------- /man/redisZRange.Rd: -------------------------------------------------------------------------------- 1 | \name{redisZRange} 2 | \alias{redisZRange} 3 | \title{ 4 | redisZRange 5 | } 6 | \description{ 7 | Return a subset of an ordered set. 8 | } 9 | \usage{ 10 | redisZRange(key, start = 0, end = -1, decreasing = FALSE, 11 | withscores = FALSE, ...) 12 | } 13 | \arguments{ 14 | \item{key}{ 15 | The set name. 16 | } 17 | \item{start}{ 18 | Starting index value. 19 | } 20 | \item{end}{ 21 | Ending index value. 22 | } 23 | \item{decreasing}{ 24 | Set TRUE to sort in decreasing order of scores. 25 | } 26 | \item{withscores}{ 27 | If TRUE, also return set element scores. 28 | } 29 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 30 | } 31 | \details{ 32 | Return the specified elements of the sorted set at the specified key. The 33 | elements are considered sorted from the lowerest to the highest score 34 | if decreasing = FALSE, and from highest to lowest score 35 | if decreasing = TRUE. Start and end are 36 | zero-based indexes. 0 is the first element of the sorted set (the one with the 37 | lowerest score), 1 the next element by score and so on. 38 | start and end can also be negative numbers indicating offsets from the end of 39 | the sorted set. For example -1 is the last element of the sorted set, -2 the 40 | penultimate element and so on. 41 | 42 | Indexes out of range will not produce an error: 43 | if start is over the end of the sorted set, or start is greater than end, 44 | an empty list is 45 | returned. If end is over the end of the sorted set Redis will threat it just 46 | like the last element of the sorted set. 47 | } 48 | \value{ 49 | A list of returned set elements. If withscores = TRUE, two lists called 50 | 'elements' and 'scores' are returned. 51 | } 52 | \references{ 53 | http://redis.io/commands 54 | } 55 | \author{ 56 | B. W. Lewis 57 | } 58 | -------------------------------------------------------------------------------- /R/strValCMD.R: -------------------------------------------------------------------------------- 1 | # This file contains functions that operate on Redis 'string' values. 2 | 3 | redisGet <- function(key, ...) 4 | { 5 | .redisCmd(.raw('GET'), .raw(key), ...) 6 | } 7 | 8 | redisSet <- function(key, value, NX=FALSE) 9 | { 10 | value <- .cerealize(value) 11 | cmd <- 'SET' 12 | if(NX) cmd <- 'SETNX' 13 | .redisCmd(.raw(cmd), .raw(key), value) 14 | } 15 | 16 | redisGetSet <- function(key, value, ...) 17 | { 18 | .redisCmd(.raw('GETSET'),.raw(key),value, ...) 19 | } 20 | 21 | redisMGet <- function(keys, ...) 22 | { 23 | keylist <- as.list(keys) 24 | x <- do.call('.redisCmd',c(lapply(c(list('MGET'),keylist),charToRaw),...)) 25 | # The following may not occur, for example within a transaction block: 26 | if(length(x) == length(keylist)) names(x) <- keylist 27 | x 28 | } 29 | 30 | redisMSet <- function(keyvalues, NX=FALSE, ...) 31 | { 32 | # Includes a significant performance improvement contributed 33 | # by William Pleasant. 34 | if (0L == length(keyvalues)) 35 | return(NULL) 36 | if (NX) cmd <- 'MSETNX' else cmd <- 'MSET' 37 | a <- list(.raw(cmd)) 38 | j <- 2L * seq_along(keyvalues) 39 | a[j + 1L] <- keyvalues # extends a 40 | a[j] <- lapply(names(keyvalues), charToRaw) 41 | a <- c(a, ...) 42 | do.call('.redisCmd', a) 43 | } 44 | 45 | redisIncr <- function(key) 46 | { 47 | .redisCmd(.raw('INCR'),.raw(key)) 48 | } 49 | 50 | redisIncrBy <- function(key, value) 51 | { 52 | .redisCmd(.raw('INCRBY'),.raw(key),.raw(as.character(value))) 53 | } 54 | 55 | redisIncrByFloat <- function(key, value) 56 | { 57 | .redisCmd(.raw('INCRBYFLOAT'),.raw(key),.raw(as.character(value))) 58 | } 59 | 60 | redisDecrBy <- function(key, value) 61 | { 62 | .redisCmd(.raw('DECRBY'),.raw(key),.raw(as.character(value))) 63 | } 64 | 65 | redisDecr <- function(key) 66 | { 67 | .redisCmd(.raw('DECR'),.raw(key)) 68 | } 69 | -------------------------------------------------------------------------------- /man/incr.Rd: -------------------------------------------------------------------------------- 1 | \name{Increment, Decrement functions} 2 | \alias{redisIncr} 3 | \alias{redisIncrBy} 4 | \alias{redisIncrByFloat} 5 | \alias{redisDecr} 6 | \alias{redisDecrBy} 7 | \title{Increment or decrement Redis values.} 8 | \description{ 9 | \code{redisIncr} increments the Redis string value corresponding to the 10 | specified key by one. 11 | 12 | \code{redisDecr} decrements the Redis string value corresponding to the 13 | specified key by one. 14 | 15 | The various *By functions increment or decrement values by a specified 16 | integer or numeric value. 17 | } 18 | \usage{ 19 | redisIncr(key) 20 | redisIncrBy(key, value) 21 | redisIncrByFloat(key, value) 22 | redisDecr(key) 23 | redisDecrBy(key, value) 24 | } 25 | \arguments{ 26 | \item{key}{A key corresponding to the value to increment.} 27 | \item{value}{The value to increment by (integer, numeric, or character).} 28 | } 29 | \details{ 30 | Note that they initial value must be a raw character value (a plain Redis 31 | string value), not a serialized R value. See the examples below. 32 | 33 | The increment value may be an integer (\code{redisIncrBy}) or a numeric value 34 | (\code{redisIncrByFloat}), or a raw character representation of an integer or 35 | numeric value. If the key does not exist or contains a value of a wrong type, 36 | set the key to the value of "0" or similar string representation of an integer 37 | before running the function. 38 | 39 | } 40 | \value{ 41 | The new value of key after the increment. Note that the value is returned as 42 | a raw Redis string value. 43 | } 44 | \references{ 45 | http://redis.io/commands 46 | } 47 | \author{ 48 | B. W. Lewis 49 | } 50 | 51 | \seealso{ 52 | \code{\link{redisDecr}} 53 | } 54 | \examples{ 55 | \dontrun{ 56 | redisSet('x',charToRaw('5')) # Note the value must be a raw string! 57 | redisIncr('x') 58 | redisIncrBy('x','3') 59 | redisIncrBy('x',3) # also works 60 | redisIncrByFloat('x',pi) 61 | redisDecr('x') 62 | redisDecrBy('x',3) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /man/redisRPopLPush.Rd: -------------------------------------------------------------------------------- 1 | \name{redisRPopLPush} 2 | \alias{redisRPopLPush} 3 | \title{Remove the tail from a list, pushing to another. 4 | } 5 | \description{ 6 | Atomically return and remove the last (tail) element of the src list, and 7 | push the element as the first (head) element of the dst list. 8 | } 9 | \usage{ 10 | redisRPopLPush(src, dest, ...) 11 | } 12 | \arguments{ 13 | \item{src}{A key corresponding to the source list.} 14 | \item{dest}{A key corresponding to the destination list.} 15 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 16 | } 17 | \details{ 18 | Atomically return and remove the last (tail) element of the src list, and 19 | push the element as the first (head) element of the dst list. For example if 20 | the source list contains the elements "a","b","c" and the destination list 21 | contains the elements "foo","bar" after a \code{redisRPopLPush} 22 | command the content of the 23 | two lists will be "a","b" and "c","foo","bar". 24 | 25 | If the key does not exist or the list is already empty the special value NULL 26 | is returned. If the srckey and dstkey are the same the operation is equivalent 27 | to removing the last element from the list and pusing it as first element of 28 | the list, so it's a "list rotation" command. 29 | 30 | See the Redis reference below for programming examples and discussion. 31 | } 32 | \value{ 33 | The value moved or rotated across lists, or NULL if the source key does 34 | not exist or corresponds to an empty list. An error is thrown if either 35 | of the keys does not correspond to a value of 'list' type. 36 | } 37 | \references{ 38 | http://redis.io/commands 39 | } 40 | \author{ 41 | B. W. Lewis 42 | } 43 | \seealso{ 44 | \code{\link{redisLPush}} 45 | } 46 | \examples{ 47 | \dontrun{ 48 | redisConnect() 49 | redisLPush('x',1) 50 | redisLPush('x',2) 51 | redisLPush('x',3) 52 | redisRPopLPush('x','x') 53 | redisRPopLPush('x','x') 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /man/redisPublish.Rd: -------------------------------------------------------------------------------- 1 | \name{redisPublish} 2 | \alias{redisPublish} 3 | \title{redisPublish} 4 | \description{Publish data to a Redis message channel.} 5 | \usage{ 6 | redisPublish(channel, message) 7 | } 8 | \arguments{ 9 | \item{channel}{The channel name (character).} 10 | \item{message}{The message (any type, use RAW type for communication with 11 | non-R subscribers.} 12 | } 13 | \details{(From the Redis.io documentation): 14 | \code{redisSubscribe}, \code{redisUnsubscribe} and \code{redisPublish} 15 | implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) 16 | senders (publishers) are not programmed to send their messages to specific 17 | receivers (subscribers). Rather, published messages are characterized into 18 | channels, without knowledge of what (if any) subscribers there may be. 19 | Subscribers express interest in one or more channels, and only receive messages 20 | that are of interest, without knowledge of what (if any) publishers there are. 21 | 22 | Use the Redis function \code{redisUnsubscribe} to unsubscribe from one or 23 | more channels. Service incoming messanges on the channels with either 24 | \code{redisGetResponse} or \code{redisMonitorChannels}. 25 | 26 | Use of any other Redis after \code{redisSubscribe} prior to calling 27 | \code{redisUnsubscribe} will result in an error. 28 | } 29 | \value{A list conforming to the Redis subscribe response message. 30 | Each subscribed channel corresponds to three list elements, the header 31 | 'subscribe' followed by the channel name and a count indicating the total 32 | number of subscriptions.} 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisSubscribe}} 41 | \code{\link{redisUnsubscribe}} 42 | \code{\link{redisPublish}} 43 | \code{\link{redisGetResponse}} 44 | 45 | \code{\link{redisMonitorChannels}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | redisConnect() 50 | redisPublish('channel1', charToRaw('A raw charachter data message example')) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /man/redisSetContext.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSetContext} 2 | \alias{redisSetContext} 3 | \alias{redisGetContext} 4 | \title{redisSetContext} 5 | \description{Get or set the current active Redis connection environment.} 6 | \usage{ 7 | redisSetContext( e = NULL) 8 | redisGetContext() 9 | } 10 | \arguments{ 11 | \item{e}{ 12 | An environment representing the new Redis server connection context 13 | returned by \code{rediscConnect(returnRef=TRUE)}. The default value of NULL 14 | sets the context to the most recently established connection. 15 | } 16 | } 17 | \details{ 18 | The rredis package stores information associated with a connection to 19 | a Redis server in an environment. The \code{redisSetContext} and 20 | \code{redisSetContext} functions help manage simultaneous 21 | connection to multiple Redis servers. 22 | 23 | The \code{redisSetContext} function returns an environment representing 24 | the current active Redis connection. If there is no current active Redis 25 | connection, an environment is still returned, but without connection 26 | information. 27 | 28 | The \code{redisSetContext} function replaces the current active environment. 29 | Any number of simultaneous connections to multiple Redis servers may be managed 30 | in this manner. 31 | } 32 | \value{ 33 | NULL is invisibly returned. 34 | } 35 | \author{ 36 | B. W. Lewis 37 | } 38 | \seealso{ 39 | \code{\link{redisGetContext}} 40 | \code{\link{redisConnect}} 41 | } 42 | \examples{ 43 | \dontrun{ 44 | # Open a connection to a Redis server on HOST1 and store its context: 45 | HOST1 <- redisConnect(host='HOST1', returnRef=TRUE) 46 | print(redisInfo()) 47 | 48 | # Initiate a new Redis context: 49 | HOST2 <- redisConnect(host='HOST2', returnRef=TRUE) 50 | # The connection to HOST2 is now active: 51 | print(redisInfo()) 52 | 53 | # We may now switch back and forth between the two active connections: 54 | redisSetContext(HOST1) 55 | print(redisInfo()) 56 | redisSetContext(HOST2) 57 | print(redisInfo()) 58 | redisClose() 59 | redisSetContext(HOST1) 60 | redisClose() 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /man/redisBRPopLPush.Rd: -------------------------------------------------------------------------------- 1 | \name{redisBRPopLPush} 2 | \alias{redisBRPopLPush} 3 | \title{Remove the tail from a list, blocking if it does not exist, pushing to another.} 4 | \description{ 5 | Atomically return and remove the last (tail) element of the src list, blocking 6 | if the element does not exist, and 7 | push the element as the first (head) element of the dst list. 8 | } 9 | \usage{ 10 | redisBRPopLPush(src, dest, timeout = 0, ...) 11 | } 12 | \arguments{ 13 | \item{src}{A key corresponding to the source list.} 14 | \item{dest}{A key corresponding to the destination list.} 15 | \item{timeout}{Block for at most timeout seconds. Set to zero to block indefinitely.} 16 | \item{...}{ Optional additional arguments. Specify \code{raw=TRUE} to skip de-serialization of the data.} 17 | } 18 | \details{ 19 | Atomically return and remove the last (tail) element of the src list, blocking 20 | until the element exists, and 21 | push the element as the first (head) element of the dst list. For example if 22 | the source list contains the elements "a","b","c" and the destination list 23 | contains the elements "foo","bar" after a \code{redisRPopLPush} 24 | command the content of the 25 | two lists will be "a","b" and "c","foo","bar". 26 | 27 | If the key does not exist or the list is already empty the special value NULL 28 | is returned. If the srckey and dstkey are the same the operation is equivalent 29 | to removing the last element from the list and pusing it as first element of 30 | the list, so it's a "list rotation" command. 31 | 32 | See the Redis reference below for programming examples and discussion. 33 | } 34 | \value{ 35 | The value moved or rotated across lists, or NULL if the source key does 36 | not exist or corresponds to an empty list. An error is thrown if either 37 | of the keys does not correspond to a value of 'list' type. 38 | } 39 | \references{ 40 | http://redis.io/commands 41 | } 42 | \author{ 43 | B. W. Lewis 44 | } 45 | \seealso{ 46 | \code{\link{redisRPopLPush}} 47 | } 48 | \examples{ 49 | \dontrun{ 50 | redisConnect() 51 | redisLPush('x',1) 52 | redisBRPopLPush('x','x') 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /R/hashCMD.R: -------------------------------------------------------------------------------- 1 | # This file contains functions that operate on Redis 'hash' values. 2 | 3 | redisHGet <- function(key, field, ...) 4 | { 5 | .redisCmd(.raw('HGET'), .raw(key), .raw(field),...) 6 | } 7 | 8 | redisHSet <- function(key, field, value, NX=FALSE) 9 | { 10 | value <- .raw(value) 11 | cmd <- 'HSET' 12 | if(NX) cmd <- 'HSETNX' 13 | .redisCmd(.raw(cmd), .raw(key), .raw(field), value) 14 | } 15 | 16 | redisHIncrBy <- function(key, field, value, ...) 17 | { 18 | .redisCmd(.raw('HINCRBY'),.raw(key),.raw(field),.raw(as.character(value)),...) 19 | } 20 | 21 | redisHIncrByFloat <- function(key, field, value, ...) 22 | { 23 | .redisCmd(.raw('HINCRBY'),.raw(key),.raw(field),.raw(as.character(value)),...) 24 | } 25 | 26 | redisHExists <- function(key, field) 27 | { 28 | .redisCmd(.raw('HEXISTS'), .raw(key), .raw(field)) == 1 29 | } 30 | 31 | redisHDel <- function(key, field) 32 | { 33 | .redisCmd(.raw('HDEL'), .raw(key), .raw(field)) 34 | } 35 | 36 | redisHLen <- function(key) 37 | { 38 | .redisCmd(.raw('HLEN'), .raw(key)) 39 | } 40 | 41 | redisHFields <- function(key,...) 42 | { 43 | .redisCmd(.raw('HKEYS'), .raw(key),...) 44 | } 45 | 46 | redisHKeys <- function(key,...) 47 | { 48 | redisHFields(key,...) 49 | } 50 | 51 | redisHVals <- function(key,...) 52 | { 53 | .redisCmd(.raw('HVALS'), .raw(key),...) 54 | } 55 | 56 | redisHGetAll <- function(key,...) 57 | { 58 | retval <- NULL 59 | all <- .redisCmd(.raw('HGETALL'), .raw(key),...) 60 | if(!is.null(all) && length(all)>1) { 61 | retval <- all[seq(2,length(all),by=2)] 62 | names(retval) <- all[seq(1,length(all),by=2)] 63 | } 64 | retval 65 | } 66 | 67 | redisHMGet <- function(key, fields, ...) { 68 | a <- c(alist(),list(.raw('HMGET')),...) 69 | a <- c(a, lapply(c(key,fields), charToRaw)) 70 | retval <- do.call('.redisCmd', a) 71 | if(length(retval) == length(fields)) names(retval) <- fields 72 | retval 73 | } 74 | 75 | redisHMSet <- function(key, values) { 76 | a <- c(alist(),list(.raw('HMSET')),list(.raw(key))) 77 | fieldnames <- lapply(names(values), charToRaw) 78 | for(j in 1:length(values)) { 79 | a <- c(a, fieldnames[j]) 80 | a <- c(a,list(.raw(values[[j]]))) 81 | } 82 | do.call('.redisCmd', a) 83 | } 84 | -------------------------------------------------------------------------------- /R/setVal.R: -------------------------------------------------------------------------------- 1 | # A utility function that strips a named argument 'raw' from the list. 2 | # This function returns a list with two items: 3 | # 1. The stripped list without the raw=whatever entry 4 | # 2. The value of the named raw=whatever entry 5 | # 6 | # Use this with functions that have variable length arument lists. 7 | .redisStripRawArg <- function(List) 8 | { 9 | ir <- which(names(List) %in% "raw") 10 | raw <- c() 11 | if(length(ir)>0) 12 | { 13 | raw <- List[[ir]] 14 | List <- List[-ir] 15 | } 16 | list(List=List, raw=raw) 17 | } 18 | 19 | # Generic set operation 20 | .redisSetOp <- function(cmd, keys, ...) 21 | { 22 | L <- .redisStripRawArg(list(...)) 23 | sets <- c(as.list(keys), L$List) 24 | call <- lapply(c(list(cmd), sets), charToRaw) 25 | if(!is.null(L$raw)) call <- c(call, raw=L$raw) 26 | do.call(".redisCmd", call) 27 | } 28 | 29 | redisSInter <- function(keys, ...) 30 | { 31 | .redisSetOp("SINTER", keys, ...) 32 | } 33 | 34 | redisSUnion <- function(keys, ...) 35 | { 36 | .redisSetOp("SUNION", keys, ...) 37 | } 38 | 39 | redisSUnionStore <- function(dest, keys, ...) 40 | { 41 | .redisSetOp("SUNIONSTORE", c(dest, keys), ...) 42 | } 43 | 44 | redisSInterStore <- function(dest, keys, ...) 45 | { 46 | .redisSetOp("SINTERSTORE", c(dest, keys), ...) 47 | } 48 | 49 | redisSDiff <- function(keys, ...) 50 | { 51 | .redisSetOp("SDIFF", keys, ...) 52 | } 53 | 54 | redisSDiffStore <- function(dest, keys, ...) 55 | { 56 | .redisSetOp("SDIFFSTORE", c(dest, keys), ...) 57 | } 58 | 59 | redisSIsMember <- function(set, element) 60 | { 61 | set <- as.character(set) 62 | 1 == .redisCmd(.raw('SISMEMBER'), .raw(set), .raw(element)) 63 | } 64 | 65 | redisSRandMember <- function(set, ...) 66 | { 67 | .redisCmd(.raw('SRANDMEMBER'), .raw(set),...) 68 | } 69 | 70 | redisSAdd <- function(set, element) 71 | { 72 | .redisCmd(.raw('SADD'), .raw(set), element) 73 | } 74 | 75 | redisSPop <- function(set, ...) 76 | { 77 | .redisCmd(.raw('SPOP'), .raw(set), ...) 78 | } 79 | 80 | redisSMembers <- function(set, ...) 81 | { 82 | .redisCmd(.raw('SMEMBERS'), .raw(set), ...) 83 | } 84 | 85 | redisSRem <- function(set, element) 86 | { 87 | .redisCmd(.raw('SREM'), .raw(set), element) 88 | } 89 | 90 | redisSCard <- function(set) 91 | { 92 | .redisCmd(.raw('SCARD'), .raw(set)) 93 | } 94 | 95 | redisSMove <- function(setA, setB, element) 96 | { 97 | .redisCmd(.raw('SMOVE'), .raw(setA), .raw(setB), .raw(element)) 98 | } 99 | -------------------------------------------------------------------------------- /R/allValCMD.R: -------------------------------------------------------------------------------- 1 | # This file contains functions that operate on all kinds of Redis values. 2 | 3 | redisMulti <- function() 4 | { 5 | .redisCmd(.raw('MULTI')) 6 | } 7 | 8 | redisExec <- function() 9 | { 10 | .redisCmd(.raw('EXEC')) 11 | } 12 | 13 | redisDiscard <- function() 14 | { 15 | .redisCmd(.raw('DISCARD')) 16 | } 17 | 18 | redisWatch <- function(keys) 19 | { 20 | cmd <- 'WATCH' 21 | keys <- as.list(keys) 22 | keys <- lapply(keys, charToRaw) 23 | do.call('.redisCmd', c(list(.raw(cmd)),keys)) 24 | } 25 | 26 | redisUnwatch <- function() 27 | { 28 | cmd <- 'UNWATCH' 29 | do.call('.redisCmd', list(.raw(cmd))) 30 | } 31 | 32 | redisExists <- function(key) 33 | { 34 | .redisCmd(.raw('EXISTS'), .raw(key)) == '1' 35 | } 36 | 37 | redisDelete <- function(key) 38 | { 39 | keylist <- as.list(key) 40 | nkeys <- length(keylist) 41 | as.numeric(do.call('.redisCmd',lapply(c(list('DEL'),keylist),charToRaw))) 42 | } 43 | 44 | redisType <- function(key) 45 | { 46 | .redisCmd(.raw('TYPE'), .raw(key)) 47 | } 48 | 49 | redisKeys <- function(pattern="*") 50 | { 51 | res <- .redisCmd(.raw('KEYS'), .raw(pattern)) 52 | unlist(res) 53 | } 54 | 55 | redisRandomKey <- function() 56 | { 57 | .redisCmd(.raw('RANDOMKEY')) 58 | } 59 | 60 | redisRename <- function(old, new, NX=FALSE) 61 | { 62 | if (NX) cmd <- 'RENAMENX' else cmd <- 'RENAME' 63 | .redisCmd(.raw(cmd),.raw(old),.raw(new)) 64 | } 65 | 66 | redisPexpire <- function(key, milliseconds) 67 | { 68 | .redisCmd(.raw('PEXPIRE'),.raw(key),.raw(as.character(milliseconds))) 69 | } 70 | 71 | redisPexpireAt <- function(key, time) 72 | { 73 | .redisCmd(.raw('PEXPIREAT'),.raw(key),.raw(as.character(time))) 74 | } 75 | 76 | redisPTTL <- function(key) 77 | { 78 | .redisCmd(.raw('PTTL'),.raw(key)) 79 | } 80 | 81 | redisPersist <- function(key) 82 | { 83 | .redisCmd(.raw('PERSIST'),.raw(key)) 84 | } 85 | 86 | redisExpire <- function(key, seconds) 87 | { 88 | .redisCmd(.raw('EXPIRE'),.raw(key),.raw(as.character(seconds))) 89 | } 90 | 91 | redisExpireAt <- function(key, time) 92 | { 93 | .redisCmd(.raw('EXPIREAT'),.raw(key),.raw(as.character(time))) 94 | } 95 | 96 | redisTTL <- function(key) 97 | { 98 | .redisCmd(.raw('TTL'),.raw(key)) 99 | } 100 | 101 | redisMove <- function(key, dbindex) 102 | { 103 | .redisCmd(.raw('MOVE'),.raw(key),.raw(as.character(dbindex))) 104 | } 105 | -------------------------------------------------------------------------------- /man/redisGetResponse.Rd: -------------------------------------------------------------------------------- 1 | \name{redisGetResponse} 2 | \alias{redisGetResponse} 3 | \title{redisGetResponse} 4 | \description{Service messages from all subscribed Redis message channels.} 5 | \usage{ 6 | redisGetResponse(all=TRUE) 7 | } 8 | \arguments{ 9 | \item{all}{The all argument is ignored. It's left there for backwards 10 | compatibility with code based on older package versions.} 11 | } 12 | \details{(From the Redis.io documentation): 13 | \code{redisSubscribe}, \code{redisUnsubscribe} and \code{redisPublish} 14 | implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) 15 | senders (publishers) are not programmed to send their messages to specific 16 | receivers (subscribers). Rather, published messages are characterized into 17 | channels, without knowledge of what (if any) subscribers there may be. 18 | Subscribers express interest in one or more channels, and only receive messages 19 | that are of interest, without knowledge of what (if any) publishers there are. 20 | 21 | The \code{redisGetResponse} function may be called 22 | to service messages on all subscribed channels. When a message 23 | is received the a list of three elements is returned containing: 24 | the character string 'message', the name of receiving channel, and 25 | the message content. 26 | 27 | WARNING: The \code{redisGetResponse} function blocks indefinitely until a 28 | message is received. 29 | } 30 | \value{A list containing the string 'message', the channel name from which 31 | the message was received, and the message data.} 32 | \references{ 33 | http://redis.io/commands 34 | } 35 | \author{ 36 | B. W. Lewis 37 | } 38 | \seealso{ 39 | \code{\link{redisSubscribe}} 40 | \code{\link{redisPublish}} 41 | \code{\link{redisUnsubscribe}} 42 | \code{\link{redisMonitorChannels}} 43 | } 44 | \examples{ 45 | \dontrun{ 46 | redisConnect() 47 | # Define a callback function to process messages from channel 1: 48 | channel1 <- function(x) { 49 | cat("Message received from channel 1: ",x,"\n") 50 | } 51 | # Define a callback function to process messages from channel 2: 52 | channel2 <- function(x) { 53 | cat("Message received from channel 2: ",x,"\n") 54 | } 55 | redisSubscribe(c('channel1','channel2')) 56 | # Monitor channels for at least one minute (and indefinitely until 57 | # a message is received): 58 | t1 <- proc.time()[[3]] 59 | while(proc.time()[[3]] - t1 < 60) 60 | { 61 | print(redisGetResponse()) 62 | } 63 | redisUnsubscribe(c('channel1','channel2')) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /R/listCMD.R: -------------------------------------------------------------------------------- 1 | # This file contains functions that operate on Redis lists. 2 | 3 | redisRPush <- function(key, value, ...) 4 | { 5 | .redisCmd(.raw('RPUSH'), .raw(key),value, ...) 6 | } 7 | 8 | redisLPush <- function(key, value, ...) 9 | { 10 | .redisCmd(.raw('LPUSH'), .raw(key), value, ...) 11 | } 12 | 13 | redisRPop <- function(key, ...) 14 | { 15 | .redisCmd(.raw('RPOP'), .raw(key), ...) 16 | } 17 | 18 | redisLPop <- function(key, ...) 19 | { 20 | .redisCmd(.raw('LPOP'), .raw(key), ...) 21 | } 22 | 23 | redisLLen <- function(key) 24 | { 25 | .redisCmd(.raw('LLEN'), .raw(key)) 26 | } 27 | 28 | redisLRange <- function(key, start, end, ...) 29 | { 30 | start <- charToRaw(as.character(start)) 31 | end <- charToRaw(as.character(end)) 32 | .redisCmd(.raw('LRANGE'), .raw(key), start, end, ...) 33 | } 34 | 35 | redisLTrim <- function(key, start, end) 36 | { 37 | start <- charToRaw(as.character(start)) 38 | end <- charToRaw(as.character(end)) 39 | .redisCmd(.raw('LTRIM'), .raw(key), start, end) 40 | } 41 | 42 | redisLIndex <- function(key, index, ...) 43 | { 44 | .redisCmd(.raw('LINDEX'), .raw(key), .raw(as.character(index)), ...) 45 | } 46 | 47 | redisLSet <- function(key, index, value) 48 | { 49 | key <- charToRaw(as.character(key)) 50 | index <- charToRaw(as.character(index)) 51 | .redisCmd(.raw('LSET'), key, index, value) 52 | } 53 | 54 | redisLRem <- function(key, count, value) 55 | { 56 | .redisCmd(.raw('LREM'), .raw(key), .raw(as.character(count)), value) 57 | } 58 | 59 | redisRPopLPush <- function(src, dest, ...) 60 | { 61 | .redisCmd(.raw('RPOPLPUSH'), .raw(src), .raw(dest), ...) 62 | } 63 | 64 | redisBRPop <- function(keys, timeout=0, ...) 65 | { 66 | keylist <- as.list(keys) 67 | tout <- as.character(timeout) 68 | x <- do.call('.redisCmd',c(lapply(c(list('BRPOP'),keylist,tout),charToRaw),...)) 69 | if(length(x)>1) { 70 | n <- x[[1]] 71 | x <- list(x[[2]]) 72 | names(x) <- n 73 | } 74 | x 75 | } 76 | 77 | redisBLPop <- function(keys, timeout=0, ...) 78 | { 79 | keylist <- as.list(keys) 80 | tout <- as.character(timeout) 81 | x <- do.call('.redisCmd',c(lapply(c(list('BLPOP'),keylist,tout),charToRaw),...)) 82 | if(length(x)>1) { 83 | n <- x[[1]] 84 | x <- list(x[[2]]) 85 | names(x) <- n 86 | } 87 | x 88 | } 89 | 90 | redisBRPopLPush <- function(src, dest, timeout=0, ...) 91 | { 92 | tout <- as.character(timeout) 93 | .redisCmd(.raw('BRPOPLPUSH'), .raw(src), .raw(dest), .raw(tout), ...) 94 | } 95 | -------------------------------------------------------------------------------- /man/redisConnect.Rd: -------------------------------------------------------------------------------- 1 | \name{redisConnect} 2 | \alias{redisConnect} 3 | \title{Connect to a Redis server.} 4 | \description{Connect to an available Redis server on the specified port.} 5 | \usage{ 6 | redisConnect(host = "localhost", port = 6379, password = NULL, 7 | returnRef = FALSE, nodelay=TRUE, timeout=86400L, closeExisting=TRUE) 8 | } 9 | \arguments{ 10 | \item{host}{The Redis server host name or inet address (optional, character). The default value is "localhost".} 11 | \item{port}{The Redis port number (optional, numeric or integer). The default value is 6379L.} 12 | \item{password}{Redis authentication password.} 13 | \item{returnRef}{Set \code{returnRef=TRUE} to return the environment that contains the Redis connection state (see details). The default value is FALSE.} 14 | \item{nodelay}{No longer used, always TRUE.} 15 | \item{timeout}{Set the R connection timeout (in seconds). 16 | Beware that some OSes may treat very large 17 | values as zero: however the POSIX standard requires values up 18 | to 31 days to be supported.} 19 | \item{closeExisting}{Set to \code{FALSE} to keep any existing Redis connection open (for use with \code{setContext}).} 20 | } 21 | \details{ 22 | A running instance of a Redis server is required. Use \code{returnRef} to return 23 | the Redis connection state in an environment. Then use the \code{redisSetContext} 24 | function to switch environment state and manage multiple open Redis 25 | connections. 26 | 27 | Note that Redis pipelining can increase performance: 28 | \code{redisSetPipeline(TRUE)} (q.v.). 29 | 30 | } 31 | 32 | \value{Nothing is returned by default. 33 | Errors are displayed if the function fails to 34 | connect to the specified Redis server. Disconnect from a connected server 35 | with redisClose. 36 | 37 | If returnRef is set to TRUE and no error occurs, a list describing the 38 | Redis connection will be returned. A future version of the package will 39 | use this feature to support multiple Redis connections with 40 | the \code{attachRedis} function. 41 | } 42 | \references{ 43 | http://redis.io/commands 44 | } 45 | \author{ 46 | B. W. Lewis 47 | } 48 | 49 | \seealso{ 50 | \code{\link{redisClose}} 51 | \code{\link{redisGetContext}} 52 | \code{\link{redisSetContext}} 53 | \code{\link{redisSetPipeline}} 54 | \code{\link{redisGetResponse}} 55 | } 56 | \examples{ 57 | \dontrun{ 58 | redisConnect() 59 | redisSet('x',runif(5)) 60 | redisGet('x') 61 | redisClose() 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /man/redisSubscribe.Rd: -------------------------------------------------------------------------------- 1 | \name{redisSubscribe} 2 | \alias{redisSubscribe} 3 | \title{redisSubscribe} 4 | \description{Subscribe to one or more Redis message channels.} 5 | \usage{ 6 | redisSubscribe(channels, pattern=FALSE) 7 | } 8 | \arguments{ 9 | \item{channels}{A character vector or list of channel names to subscribe to.} 10 | \item{pattern}{If TRUE, allow wildcard pattern matching in channel names, 11 | otherwise names indicate full channel names.} 12 | } 13 | \details{(From the Redis.io documentation): 14 | \code{redisSubscribe}, \code{redisUnsubscribe} and \code{redisPublish} 15 | implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) 16 | senders (publishers) are not programmed to send their messages to specific 17 | receivers (subscribers). Rather, published messages are characterized into 18 | channels, without knowledge of what (if any) subscribers there may be. 19 | Subscribers express interest in one or more channels, and only receive messages 20 | that are of interest, without knowledge of what (if any) publishers there are. 21 | 22 | Use the Redis function \code{redisUnsubscribe} to unsubscribe from one or 23 | more channels. Service incoming messanges on the channels with either 24 | \code{redisGetResponse} or \code{redisMonitorChannels}. 25 | 26 | Use of any other Redis after \code{redisSubscribe} prior to calling 27 | \code{redisUnsubscribe} will result in an error. 28 | } 29 | \value{A list conforming to the Redis subscribe response message. 30 | Each subscribed channel corresponds to three list elements, the header 31 | 'subscribe' followed by the channel name and a count indicating the total 32 | number of subscriptions.} 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisSubscribe}} 41 | \code{\link{redisPublish}} 42 | \code{\link{redisUnsubscribe}} 43 | \code{\link{redisGetResponse}} 44 | 45 | \code{\link{redisMonitorChannels}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | redisConnect() 50 | # Define a callback function to process messages from channel 1: 51 | channel1 <- function(x) { 52 | cat("Message received from channel 1: ",x,"\n") 53 | } 54 | # Define a callback function to process messages from channel 2: 55 | channel2 <- function(x) { 56 | cat("Message received from channel 2: ",x,"\n") 57 | } 58 | redisSubscribe(c('channel1','channel2')) 59 | # Monitor channels for at least 1 minute: 60 | t1 <- proc.time()[[3]] 61 | while(proc.time()[[3]] - t1 < 60) 62 | { 63 | redisMonitorChannels() 64 | Sys.sleep(0.05) 65 | } 66 | redisUnsubscribe(c('channel1','channel2')) 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /man/redisUnsubscribe.Rd: -------------------------------------------------------------------------------- 1 | \name{redisUnsubscribe} 2 | \alias{redisUnsubscribe} 3 | \title{redisUnsubscribe} 4 | \description{Subscribe to one or more Redis message channels.} 5 | \usage{ 6 | redisUnsubscribe(channels, pattern=FALSE) 7 | } 8 | \arguments{ 9 | \item{channels}{A character vector or list of channel names to subscribe to.} 10 | \item{pattern}{If TRUE, allow wildcard pattern matching in channel names, 11 | otherwise names indicate full channel names.} 12 | } 13 | \details{(From the Redis.io documentation): 14 | \code{redisSubscribe}, \code{redisUnsubscribe} and \code{redisPublish} 15 | implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) 16 | senders (publishers) are not programmed to send their messages to specific 17 | receivers (subscribers). Rather, published messages are characterized into 18 | channels, without knowledge of what (if any) subscribers there may be. 19 | Subscribers express interest in one or more channels, and only receive messages 20 | that are of interest, without knowledge of what (if any) publishers there are. 21 | 22 | Use the Redis function \code{redisUnsubscribe} to unsubscribe from one or 23 | more channels. Service incoming messanges on the channels with either 24 | \code{redisGetResponse} or \code{redisMonitorChannels}. 25 | 26 | Use of any other Redis after \code{redisSubscribe} prior to calling 27 | \code{redisUnsubscribe} will result in an error. 28 | } 29 | \value{A list conforming to the Redis subscribe response message. 30 | Each subscribed channel corresponds to three list elements, the header 31 | element 'unsubscribe' followed by the channel name and a count indicating 32 | the total number of subscriptions.} 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisSubscribe}} 41 | \code{\link{redisUnsubscribe}} 42 | \code{\link{redisPublish}} 43 | \code{\link{redisGetResponse}} 44 | 45 | \code{\link{redisMonitorChannels}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | redisConnect() 50 | # Define a callback function to process messages from channel 1: 51 | channel1 <- function(x) { 52 | cat("Message received from channel 1: ",x,"\n") 53 | } 54 | # Define a callback function to process messages from channel 2: 55 | channel2 <- function(x) { 56 | cat("Message received from channel 2: ",x,"\n") 57 | } 58 | redisSubscribe(c('channel1','channel2')) 59 | # Monitor channels for at least 1 minute: 60 | t1 <- proc.time()[[3]] 61 | while(proc.time()[[3]] - t1 < 60) 62 | { 63 | redisMonitorChannels() 64 | Sys.sleep(0.05) 65 | } 66 | redisUnsubscribe(c('channel1','channel2')) 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /man/redisMonitorChannels.Rd: -------------------------------------------------------------------------------- 1 | \name{redisMonitorChannels} 2 | \alias{redisMonitorChannels} 3 | \title{redisMonitorChannels} 4 | \description{Subscribe to one or more Redis message channels.} 5 | \usage{ 6 | redisMonitorChannels() 7 | } 8 | \details{(From the Redis.io documentation): 9 | \code{redisSubscribe}, \code{redisUnsubscribe} and \code{redisPublish} 10 | implement the Publish/Subscribe messaging paradigm where (citing Wikipedia) 11 | senders (publishers) are not programmed to send their messages to specific 12 | receivers (subscribers). Rather, published messages are characterized into 13 | channels, without knowledge of what (if any) subscribers there may be. 14 | Subscribers express interest in one or more channels, and only receive messages 15 | that are of interest, without knowledge of what (if any) publishers there are. 16 | 17 | The \code{redisMonitorChannels} function may be called repeatedly in an 18 | event loop to service messages on all subscribed channels. When a message 19 | is received, the \code{redisMonitorChannels} function will attempt to 20 | evaluate a callback function with same name as the channel, with the message 21 | as its single argument. If no such function can be found, the message is 22 | returned. See the help page for \code{redisGetResponse} for a description 23 | of the message format. 24 | 25 | WARNING: The \code{redisMonitorChannels} function blocks indefinitely until a 26 | message is received. 27 | 28 | Use the lower-level \code{redisGetResponse} function to simply poll channels 29 | for messages without evaluating function callbacks. 30 | } 31 | \value{The result of an evaluated function callback message, or if 32 | no matching callback exists, the message.} 33 | \references{ 34 | http://redis.io/commands 35 | } 36 | \author{ 37 | B. W. Lewis 38 | } 39 | \seealso{ 40 | \code{\link{redisSubscribe}} 41 | \code{\link{redisPublish}} 42 | \code{\link{redisUnsubscribe}} 43 | \code{\link{redisGetResponse}} 44 | 45 | \code{\link{redisMonitorChannels}} 46 | } 47 | \examples{ 48 | \dontrun{ 49 | redisConnect() 50 | # Define a callback function to process messages from channel 1: 51 | channel1 <- function(x) { 52 | cat("Message received from channel 1: ",x,"\n") 53 | } 54 | # Define a callback function to process messages from channel 2: 55 | channel2 <- function(x) { 56 | cat("Message received from channel 2: ",x,"\n") 57 | } 58 | redisSubscribe(c('channel1','channel2')) 59 | # Monitor channels for at least 1 minute: 60 | t1 <- proc.time()[[3]] 61 | while(proc.time()[[3]] - t1 < 60) 62 | { 63 | redisMonitorChannels() 64 | Sys.sleep(0.05) 65 | } 66 | redisUnsubscribe(c('channel1','channel2')) 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /tests/basicTest.R: -------------------------------------------------------------------------------- 1 | require(rredis) 2 | checkEquals <- function(x, y) if(!isTRUE(all.equal(x, y, check.attributes=FALSE))) stop() 3 | 4 | if(Sys.getenv("RunRRedisTests") == "yes") 5 | { 6 | redisConnect() 7 | redisFlushAll() 8 | checkEquals(FALSE, redisExists("foo")) 9 | 10 | # delete test 11 | checkEquals(0, suppressWarnings(redisDelete("foo"))) 12 | 13 | # empty get test 14 | checkEquals(TRUE, is.null(redisGet("foo"))) 15 | 16 | # simple set test 17 | checkEquals("OK", redisSet("foo", "bar")) 18 | 19 | # simple getset test 20 | checkEquals("bar", redisGetSet("foo", "zip")) 21 | 22 | # getset confirm 23 | checkEquals("zip", redisGet("foo")) 24 | 25 | # set/serialize test 26 | foo <- runif(10) 27 | redisSet("foo", foo) 28 | checkEquals(foo, redisGet("foo")) 29 | 30 | # simple type check 31 | checkEquals("string", redisType("foo")) 32 | 33 | # mget test 34 | redisSet("foo", "bar") 35 | redisSet("bar", "foo") 36 | checkEquals(list(foo="bar", bar="foo"), redisMGet(c("foo", "bar"))) 37 | 38 | # simple mset test 39 | checkEquals("OK", redisMSet(list(foo="foo",bar="bar"))) 40 | 41 | # simple mset confirm 42 | checkEquals("foo", redisGet("foo")) 43 | 44 | # real mset test 45 | redisDelete(c("foo", "bar")) 46 | redisMSet(list(foo="bar",bar="foo")) 47 | checkEquals(list(foo="bar",bar="foo"), redisMGet(c("foo", "bar"))) 48 | redisDelete(c("foo", "bar")) 49 | 50 | # real exists test 51 | checkEquals(FALSE, redisExists("foo")) 52 | redisSet("foo", 1) 53 | checkEquals(TRUE, redisExists("foo")) 54 | redisDelete("foo") 55 | 56 | # expire test 57 | redisSet("foo", 1) 58 | redisExpire("foo", 1) 59 | Sys.sleep(2) 60 | checkEquals(FALSE, redisExists("foo")) 61 | 62 | # rename/renamenx test 63 | redisSet("foo", 1) 64 | redisSet("bar", 2) 65 | redisRename("foo", "bar") 66 | checkEquals(1, redisGet("bar")) 67 | redisSet("foo", 2) 68 | checkEquals("0", redisRename("foo", "bar", NX=TRUE)) 69 | redisDelete("bar") 70 | redisRename("foo", "bar", NX=TRUE) 71 | checkEquals(2, redisGet("bar")) 72 | 73 | # set/mset nx mode test 74 | redisFlushAll() 75 | checkEquals("1", redisSet("foo", 1, NX=TRUE)) 76 | checkEquals("0", redisSet("foo", 1, NX=TRUE)) 77 | checkEquals("0", redisMSet(list(foo=1), NX=TRUE)) 78 | redisDelete("foo") 79 | checkEquals("1", redisMSet(list(foo=1,bar=2), NX=TRUE)) 80 | 81 | redisFlushAll() 82 | 83 | # Incr/Decr 84 | redisSet("x", charToRaw("1")) 85 | y <- redisGet("x") 86 | redisSet("x", y) # tests a case internal to Pat's ".cerealize" function 87 | checkEquals("2", redisIncr("x")) 88 | checkEquals("3", redisIncrBy("x", 1)) 89 | checkEquals("4", redisIncrByFloat("x", 1)) 90 | checkEquals("3", redisDecrBy("x", 1)) 91 | checkEquals("2", redisDecr("x")) 92 | 93 | 94 | 95 | 96 | redisFlushAll() 97 | } 98 | -------------------------------------------------------------------------------- /man/hyperloglog.Rd: -------------------------------------------------------------------------------- 1 | \name{Hyperloglog functions} 2 | \alias{redisPfadd} 3 | \alias{redisPfcount} 4 | \alias{redisPfmerge} 5 | \title{Redis HyperLogLog Functions} 6 | \description{ 7 | \code{redisPfadd} 8 | Adds all the element arguments to the HyperLogLog data structure stored at the 9 | key name specified as first argument. 10 | \code{redisPfcount} 11 | 12 | When called with a single key, returns the approximated cardinality computed by 13 | the HyperLogLog data structure stored at the specified variable, which is 0 if 14 | the variable does not exist. 15 | 16 | When called with multiple keys, returns the approximated cardinality of the 17 | union of the HyperLogLogs passed, by internally merging the HyperLogLogs stored 18 | at the provided keys into a temporary HyperLogLog. 19 | 20 | \code{redisPfmerge} 21 | Merge multiple HyperLogLog values into a unique value that will approximate 22 | the cardinality of the union of the observed Sets of the source HyperLogLog 23 | structures. 24 | 25 | } 26 | \usage{ 27 | redisPfadd(key, elements) 28 | redisPfcount(keys) 29 | redisPfmerge(destkey, sourcekeys) 30 | } 31 | \arguments{ 32 | \item{key}{A Redis key name corresponding to a HyperLogLog value.} 33 | \item{keys}{A Redis key name or a vector of Redis key names corresponding to HyperLogLog values.} 34 | \item{elements}{A vector or list of elements to add to the HyperLogLog data structure associated with \code{key}.} 35 | \item{destkey}{The computed merged HyperLogLog is set to the destination key, which is 36 | created if does not exist (defaulting to an empty HyperLogLog).} 37 | \item{sourcekeys}{A single key name or vector of Redis key names corresponding to HyperLogLog values to be 38 | merged into a unqiue value.} 39 | } 40 | \details{ 41 | The HyperLogLog data structure can be used in order to count unique elements in 42 | a set using just a small constant amount of memory, specifically 12k bytes for 43 | every HyperLogLog (plus a few bytes for the key itself). 44 | 45 | The returned cardinality of the observed set is not exact, but approximated 46 | with a standard error of 0.81\%. For example in order to take the count of all 47 | the unique search queries performed in a day, a program needs to call 48 | \code{redisPfadd} every time a query is processed. The estimated number of 49 | unique queries can be retrieved with PFCOUNT at any time. 50 | } 51 | \value{ 52 | \code{redisPfadd} returns "1" if at least 1 HyperLogLog internal register was altered, "0" otherwise. 53 | 54 | \code{redisPfcount} returns a Redis integer value as a character string 55 | corresponding to the approximated number of unique elements observed. 56 | 57 | \code{redisPfmerge} just returns "OK". 58 | } 59 | \references{ 60 | http://redis.io/commands 61 | } 62 | \author{ 63 | B. W. Lewis 64 | } 65 | 66 | \seealso{ 67 | \code{\link{redisPfadd}} 68 | \code{\link{redisPfcount}} 69 | \code{\link{redisPfmerge}} 70 | } 71 | \examples{ 72 | \dontrun{ 73 | redisPfadd("testcounter", letters[1:10]) 74 | redisPfadd("testcounter", letters[1:20]) 75 | redisPfcount("testcounter") 76 | 77 | redisPfadd("testcounter_2", "z") 78 | redisPfmerge("testcounter", "testcounter_2") 79 | redisPfcount("testcounter") 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /R/controlCMD.R: -------------------------------------------------------------------------------- 1 | # This file contains various control functions. 2 | 3 | # Basic response handler, only really useful in pipelined cases 4 | # all function argument is left in for backward compatibility, 5 | # it is not used. 6 | redisGetResponse <- function(all=TRUE) 7 | { 8 | if(!exists('count',where=.redisEnv$current)) return(.getResponse()) 9 | if(.redisEnv$current$count < 1) return(NULL) 10 | replicate(.redisEnv$current$count, .getResponse(), simplify=FALSE) 11 | } 12 | 13 | redisSetPipeline <- function(value=FALSE) 14 | { 15 | value <- as.logical(value) 16 | if(is.na(value)) stop("logical value required") 17 | assign('pipeline',value,envir=.redisEnv$current) 18 | } 19 | 20 | redisConnect <- 21 | function(host='localhost', port=6379, password=NULL, 22 | returnRef=FALSE, nodelay=TRUE, timeout=86400L, closeExisting=TRUE) 23 | { 24 | if(closeExisting) tryCatch(redisClose(), error=invisible) 25 | .redisEnv$current <- new.env() 26 | assign('pipeline',FALSE,envir=.redisEnv$current) 27 | con <- .openConnection(host=host, port=port, nodelay=nodelay, timeout=timeout, envir=.redisEnv$current) 28 | if (!is.null(password)) tryCatch(redisAuth(password), 29 | error=function(e) { 30 | cat(paste('Error: ',e,'\n')) 31 | .closeConnection(con); 32 | rm(list='con',envir=.redisEnv$current) 33 | }) 34 | tryCatch(.redisPP(), 35 | error=function(e) { 36 | cat(paste('Error: ',e,'\n')) 37 | .closeConnection(con); 38 | rm(list='con',envir=.redisEnv$current) 39 | }) 40 | if(returnRef) return(.redisEnv$current) 41 | invisible() 42 | } 43 | 44 | redisClose <- 45 | function(e) 46 | { 47 | if(missing(e)) e = .redisEnv$current 48 | con <- .redis(e) 49 | .closeConnection(con) 50 | remove(list='con',envir=e) 51 | } 52 | 53 | redisAuth <- 54 | function(pwd) 55 | { 56 | .redisCmd(.raw('AUTH'), .raw(pwd)) 57 | } 58 | 59 | redisSave <- 60 | function() 61 | { 62 | .redisCmd(.raw('SAVE')) 63 | } 64 | 65 | redisBgSave <- 66 | function() 67 | { 68 | .redisCmd(.raw('BGSAVE')) 69 | } 70 | 71 | redisBgRewriteAOF <- 72 | function() 73 | { 74 | .redisCmd(.raw('BGREWRITEAOF')) 75 | } 76 | 77 | redisShutdown <- 78 | function() 79 | { 80 | .redisCmd(.raw('SHUTDOWN')) 81 | remove(list='con', envir=.redisEnv$current) 82 | } 83 | 84 | 85 | redisInfo <- 86 | function(){ 87 | x <- .redisCmd(.raw('INFO')) 88 | str <- strsplit(x,'\r\n')[[1]] 89 | 90 | splitvec <- regexec('^(.*?):([^#]*)(#.*)?', str) 91 | matches <- regmatches(str, splitvec) 92 | matches <- Filter(function(x)(length(x) > 0), matches) 93 | keys <- sapply(matches,function(x)x[2]) 94 | vals <- lapply(matches,function(x)x[3]) 95 | names(vals) <- keys 96 | return(vals) 97 | } 98 | 99 | redisSlaveOf <- 100 | function(host,port) 101 | { 102 | # Use host="no" port="one" to disable slave replication 103 | .redisCmd(.raw('SLAVEOF'),.raw(as.character(host)), .raw(as.character(port))) 104 | } 105 | 106 | redisFlushDB <- function() { 107 | .redisCmd(.raw('FLUSHDB')) 108 | } 109 | 110 | redisFlushAll <- function() { 111 | .redisCmd(.raw('FLUSHALL')) 112 | } 113 | 114 | redisSelect <- function(index) { 115 | .redisCmd(.raw('SELECT'),.raw(as.character(index))) 116 | } 117 | 118 | redisDBSize <- function() { 119 | .redisCmd(.raw('DBSIZE')) 120 | } 121 | 122 | redisGetContext <- function() { 123 | .redisEnv$current 124 | } 125 | 126 | redisSetContext <- function(e=NULL) 127 | { 128 | if(is.null(e)) .redisEnv$current <- .redisEnv 129 | else { 130 | if(!is.environment(e)) stop("Invalid context") 131 | .redisEnv$current <- e 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 1.7.2: 2 | - Removed old, now unnecessary, TCP Nagle code. `nodelay` options is now 3 | always TRUE. 4 | 1.7.0: 5 | - We implemented a great suggestion by Simon Urbanek. Values obtained from 6 | Redis that are *not* serialized R objects are now decorated with an attribute 7 | named "redis string value." The package uses this to automatically maintain 8 | fidelity of the original Redis value through repeated download/upload cycles. 9 | Previous versions of the rredis package uploaded everything as serialized R 10 | values unless explictly told otherwise. 11 | - Set `options('redis:num'=TRUE)` to return Redis "`:`" messages as numeric 12 | values. This was the default behavior of the rredis package for all versions 13 | up to 1.6.9. For versions of the R package later than that, redis "`:`" 14 | messages are returned as raw Redis string values to correspond to the data 15 | types stored in Redis. Redis commands affected by this option include all 16 | increment and decrement operations. 17 | 18 | 1.6.8.2: 19 | - The TCP Nagle disabling scheme has been improved. The default remains 20 | standard R connections. 21 | - A bug in the Lua script function 'redisEval' was fixed. 22 | 23 | 1.6.8: 24 | - The package now includes support for Redis bit operations thanks to 25 | code contributed by Kenny Helsens. 26 | - Wush Wu helped to add a new performance option on redisConnect to bring the 27 | rredis package closer to the performance of the hiredis C library. Use the 28 | nodelay=TRUE option to disable the TCP Nagle congestion control algorithm, 29 | which can dramatically improve performance especially for frequent short 30 | transactions, at the expense of basically allowing Redis to take over your 31 | network (diable TCP Nagle at your own risk, and only enable this option if 32 | you really need to). We include this option because that's what hiredis does 33 | by default (?!!), and we want to make this performance gain available. 34 | This TCP trickery unfortunately introduced a little bit of C code. 35 | - Use the `redisCmd` function to easily issue *any* Redis command, even 36 | if the R package does not yet have a wrapper function for it. Useul also 37 | for prototyping. This has been available for a while but people don't 38 | seem to know about it. 39 | - We've cut back and streamlined code when returning raw values and, 40 | based on a good suggestion of sherbert, there is now a unified way to return 41 | raw values across all functions that retrieve stored values from Redis. 42 | Simply add the `raw=TRUE` argument to skip unserialization of the returned 43 | result. 44 | 45 | 1.6.7: 46 | - Nonblocking connections in R are problematic, we switched 47 | to blocking mode. 48 | - Added redisBRPopLPush 49 | - Added connection timeout option to redisConnect 50 | - Added 'eval' lua scripting functions 51 | 52 | 1.6.6: 53 | - Fixed a bug in HMSet. 54 | 55 | 1.6.5: 56 | - Added missing HMGet function. 57 | - Added generic redis function. 58 | 59 | 1.6.3: 60 | - Support for new redisInfo format 61 | - Improved interrupt handling during communication 62 | - Minor man page fixes 63 | 64 | Significant changes in version 1.6: 65 | - Transactions are supported. 66 | - Pub/sub is supported. 67 | - Better support for raw value types across the board. 68 | 69 | Significant changes in version 1.4: 70 | - Many bugs were fixed in the sorted sets (redisZ*) functions. 71 | - New unit tests for sorted set functions were added. 72 | 73 | Significant changes in version 1.2: 74 | 1. We completely revamped communication with the Redis server, eliminating 75 | in-line messaging in anticipation of it's demise in future Redis versions. 76 | We also make a better effort to minimize copying by R prior to sending 77 | a message. 78 | 79 | 2. Added support for Redis hashes and ordered sets. The R/Redis client now 80 | fully supports all Redis types. 81 | -------------------------------------------------------------------------------- /R/zsetVal.R: -------------------------------------------------------------------------------- 1 | # Redis ordered set functions 2 | redisZAdd <- function(key, score, member) 3 | { 4 | .redisCmd(.raw('ZADD'), .raw(key), .raw(as.character(score)), .raw(member)) 5 | } 6 | 7 | redisZRem <- function(key, member) 8 | { 9 | .redisCmd(.raw('ZREM'), .raw(key), .raw(member)) 10 | } 11 | 12 | redisZIncrBy <- function(key, member, increment) 13 | { 14 | z <- NULL 15 | .redisCmd(.raw('ZINCRBY'), .raw(key), .raw(as.character(increment)), 16 | .raw(member)) 17 | } 18 | 19 | redisZRank <- function(key, member, decreasing=FALSE) 20 | { 21 | cmd <- .raw('ZRANK') 22 | if(decreasing) cmd <- .raw('ZREVRANK') 23 | .redisCmd(cmd, .raw(key), .raw(member)) 24 | } 25 | 26 | redisZRange <- function(key, start=0, end=-1, decreasing=FALSE, 27 | withscores=FALSE, ...) 28 | { 29 | cmd <- .raw('ZRANGE') 30 | if(decreasing) cmd <- .raw('ZREVRANGE') 31 | start <- as.character(start) 32 | end <- as.character(end) 33 | if(withscores) { 34 | z <- .redisCmd(cmd,.raw(key),.raw(start),.raw(end),.raw('WITHSCORES'),...) 35 | if(!is.null(z)) { 36 | return(list(elements=z[seq(1,length(z),by=2)], 37 | scores=as.list(as.numeric(z[seq(2,length(z),by=2)])))) 38 | } 39 | } 40 | else 41 | .redisCmd(cmd,.raw(key),.raw(start),.raw(end),...) 42 | } 43 | 44 | redisZRangeByScore <- function(key, min, max, offset=NULL, count=NULL, withscores=FALSE,...) 45 | { 46 | min <- as.character(min) 47 | max <- as.character(max) 48 | a <- c(alist(), list(.raw('ZRANGEBYSCORE'), .raw(key), .raw(min), .raw(max)),...) 49 | if(!is.null(offset) && !is.null(count)) { 50 | a <- c(a, list(.raw('LIMIT'), .raw(offset), .raw(count))) 51 | } 52 | if(withscores) { 53 | a <- c(a,list(.raw('WITHSCORES'))) 54 | z <- do.call('.redisCmd',a) 55 | if(!is.null(z)) { 56 | return(list(elements=z[seq(1,length(z),by=2)], 57 | scores=as.list(as.numeric(z[seq(2,length(z),by=2)])))) 58 | } 59 | } 60 | do.call('.redisCmd', a) 61 | } 62 | 63 | redisZRemRangeByRank <- function(key, start, end) 64 | { 65 | start <- as.character(start) 66 | end <- as.character(end) 67 | .redisCmd(.raw('ZREMRANGEBYRANK'), .raw(key), .raw(start), .raw(end)) 68 | } 69 | 70 | redisZRemRangeByScore <- function(key, min, max) 71 | { 72 | min <- as.character(min) 73 | max <- as.character(max) 74 | .redisCmd(.raw('ZREMRANGEBYSCORE'), .raw(key), .raw(min), .raw(max)) 75 | } 76 | 77 | redisZCount <- function(key, min, max) 78 | { 79 | min <- as.character(min) 80 | max <- as.character(max) 81 | .redisCmd(.raw('ZCOUNT'), .raw(key), .raw(min), .raw(max)) 82 | } 83 | 84 | redisZCard <- function(key) 85 | { 86 | .redisCmd(.raw('ZCARD'), .raw(key)) 87 | } 88 | 89 | redisZScore <- function(key, element) 90 | { 91 | ret <- .redisCmd(.raw('ZSCORE'), .raw(key), .raw(element)) 92 | if(!is.null(ret)) ret <- as.numeric(ret) 93 | ret 94 | } 95 | 96 | .zinu <- function(type, dstkey, keys, weights=c(), aggregate=NULL,...) 97 | { 98 | N <- length(keys) 99 | a <- c(alist(), list(.raw(type), .raw(dstkey), .raw(as.character(N))),...) 100 | sets <- lapply(keys,charToRaw) 101 | a <- c(a, sets) 102 | if(!is.null(weights)) { 103 | a <- c(a, list(.raw('WEIGHTS')), lapply(as.character(weights), charToRaw)) 104 | } 105 | if(!is.null(aggregate)) { 106 | a <- c(a, list(.raw('AGGREGATE'), .raw(aggregate))) 107 | } 108 | do.call('.redisCmd', a) 109 | } 110 | 111 | redisZInterStore <- function(dstkey, keys, weights=c(), aggregate=NULL,...) 112 | { 113 | .zinu('ZINTERSTORE', dstkey, keys, weights, aggregate,...) 114 | } 115 | 116 | redisZUnionStore <- function(dstkey, keys, weights=c(), aggregate=NULL,...) 117 | { 118 | .zinu('ZUNIONSTORE', dstkey, keys, weights, aggregate,...) 119 | } 120 | 121 | redisSort <- function(key, decreasing=FALSE, alpha=FALSE, by=NULL, start=NULL, 122 | count=NULL, get=NULL, store=NULL,...) 123 | { 124 | a <- c(alist(), list(.raw('SORT')), list(.raw(key)),...) 125 | if(!is.null(by)) 126 | a <- c(a, list(.raw('BY'), .raw(by))) 127 | if(!is.null(start) && !is.null(count)) 128 | a <- c(a, list(.raw('LIMIT'), .raw(start), .raw(count))) 129 | if(!is.null(get)) 130 | a <- c(a, list(.raw('GET'), .raw(get))) 131 | if(decreasing) 132 | a <- c(a, list(.raw('DESC'))) 133 | else 134 | a <- c(a, list(.raw('ASC'))) 135 | if(alpha) 136 | a <- c(a, list(.raw('ALPHA'))) 137 | if(!is.null(store)) 138 | a <- c(a, list(.raw('STORE'), .raw(store))) 139 | do.call('.redisCmd', a) 140 | } 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # *IMPORTANT NOTICE* 2 | 3 | The rredis is defunct and I will not continue developing it. I urge all rredis 4 | users to switch to the **redux** package, https://github.com/richfitz/redux 5 | (also on CRAN). The redux package provides a more complete interface to Redis, 6 | with a much better (consistent, flexible, simpler) internal design. 7 | 8 | It's easy to convert projects that rely on rredis to use redux. See the 9 | examples below. 10 | 11 | I'll keep rredis around for a long time until I'm sure most folks that depend 12 | on it have moved over to redux, so there is no great urgency to switch. But 13 | redux is better and you should use it! 14 | 15 | This package will be removed from CRAN soon, so switch to the redux package please. 16 | 17 | # rredis: An R client for Redis 18 | 19 | ## Example 20 | 21 | ```R 22 | library(rredis) 23 | redisConnect() 24 | redisSet('foo', runif(10)) 25 | bar <- redisGet('foo') 26 | bar 27 | # [1] 0.93499818 0.47159536 0.30597259 0.58325228 0.41589498 0.63914212 0.34658694 0.08633471 0.18111369 0.15763507 28 | 29 | redisMSet(list(x=pi,y='Cazart',z=runif(2))) 30 | redisMGet(list('z','y')) 31 | #$z 32 | #[1] 0.1155711 0.7166137 33 | # 34 | #$y 35 | #[1] "Cazart" 36 | 37 | redisClose() 38 | ``` 39 | 40 | 41 | ### Use `redisCmd` to run any Redis command 42 | 43 | This is more or less how the `redux` package works. 44 | 45 | Some Redis commands have corresponding convenience wrappers with online 46 | help in the R package. Use the generic `redisCmd` function to run _any_ 47 | Redis command, even ones not specifically implemented by the package. 48 | For example: 49 | 50 | ```r 51 | redisCmd("set","key1","foobar") 52 | redisCmd("set","key2","abcdef") 53 | redisCmd("bitop", "and", "dest", "key1", "key2") 54 | # [1] "6" 55 | redisCmd("get", "dest") 56 | # [1] "`bc`ab" 57 | 58 | # in redux: 59 | library(redux) 60 | con <- hiredis() 61 | con$set("key1", "foobar") 62 | con$get("key1") 63 | # [1] "foobar" 64 | 65 | # setting/getting a serialized R value in redux 66 | con$set("key2", serialize(pi, NULL)) 67 | unserialize(con$get("key2")) 68 | # [1] 3.14159 69 | ``` 70 | 71 | ## New in version 1.7.0 72 | 73 | ### Better value exchange between R and Redis 74 | 75 | We implemented a great suggestion by Simon Urbanek. Values obtained from Redis 76 | that are *not* serialized R objects are now decorated with an attribute named 77 | "redis string value." The package uses this to automatically maintain fidelity 78 | of the original Redis value through repeated download/upload cycles. Previous 79 | versions of the rredis package uploaded everything as serialized R values 80 | unless explictly told otherwise. 81 | 82 | Consider the following interplay between the `redis-cli` client and R: 83 | 84 | ``` 85 | redis-cli set key "string value" 86 | ``` 87 | And now in R: 88 | ```r 89 | > library(rredis) 90 | > redisConnect() 91 | > redisGet("key") 92 | [1] "string value" 93 | attr(,"redis string value") # <- note the new attribute 94 | [1] TRUE 95 | 96 | > redisSet("new key", redisGet("key")) 97 | ``` 98 | Recovering the "new key" value from the `redis-cli` client returns a string 99 | value now: 100 | ``` 101 | redis-cli get "new key" 102 | "string value" 103 | ``` 104 | Before this change, users needed to be careful about converting strings to 105 | raw values in R. Now things work much more intuitively. 106 | 107 | ### API change, and option to revert behavior 108 | 109 | Set `options('redis:num'=TRUE)` to return 110 | Redis "`:`" messages as numeric values. This was the default behavior 111 | of the rredis package for all versions prior to 1.6.9. For versions 112 | of the R package later than that, redis "`:`" messages are returned 113 | as raw Redis string values to correspond to the data types stored in Redis. 114 | Set this option to revert to the old behavior. 115 | 116 | Redis commands affected by this option importantly include the increment 117 | and decrement operations. This change is outlined in the following example: 118 | ``` 119 | > library(rredis) 120 | > redisConnect() 121 | > redisSet('x',charToRaw('1')) 122 | [1] "OK" 123 | 124 | > redisIncr('x') 125 | [1] "2" 126 | attr(,"redis string value") 127 | [1] TRUE 128 | 129 | > options('redis:num'=TRUE) 130 | > redisIncr('x') 131 | [1] 3 132 | 133 | > options('redis:num'=c()) 134 | > redisIncr('x') 135 | [1] "4" 136 | attr(,"redis string value") 137 | [1] TRUE 138 | ``` 139 | 140 | 141 | ## Performance 142 | 143 | Consider using the redisSetPipeline function to enable pipelining, and also 144 | read help about options available to the redisConnect function. Also see the 145 | available options in the redisConnect function. 146 | 147 | ## Status 148 | 149 | Travis CI status 150 | 151 | [![codecov.io](https://codecov.io/github/bwlewis/rredis/coverage.svg?branch=master)](https://codecov.io/github/bwlewis/rredis?branch=master) 152 | [![CRAN version](http://www.r-pkg.org/badges/version/rredis)](http://cran.rstudio.com/web/packages/rredis/index.html) 153 | -------------------------------------------------------------------------------- /R/redis-internal.R: -------------------------------------------------------------------------------- 1 | # This file contains functions and environments used internally 2 | # by the rredis package (not exported in the namespace). 3 | 4 | .redisEnv <- new.env() 5 | .redisEnv$current <- .redisEnv 6 | 7 | .redis <- function(e) 8 | { 9 | if(missing(e)) e = .redisEnv$current 10 | if(!exists('con',envir=e)) 11 | stop('Not connected, try using redisConnect()') 12 | e$con 13 | } 14 | 15 | .openConnection <- function(host, port, nodelay=FALSE, 16 | timeout=86400L, envir=rredis:::.redisEnv$current) 17 | { 18 | stopifnot(is.character(host)) 19 | stopifnot(is.numeric(port)) 20 | stopifnot(is.logical(nodelay)) 21 | con <- envir$con 22 | if(!is.null(con)) tryCatch(.closeConnection(con), error=invisible) 23 | con <- socketConnection(host, port, open="a+b", options="no-delay", 24 | blocking=TRUE, timeout=timeout) 25 | # Stash state in the redis enivronment describing this connection: 26 | assign('con',con,envir=envir) 27 | assign('host',host,envir=envir) 28 | assign('port',port,envir=envir) 29 | assign('nodelay',nodelay,envir=envir) 30 | # Count is for pipelined communication, it keeps track of the number of 31 | # getResponse calls that are pending. 32 | assign('count',0,envir=envir) 33 | con 34 | } 35 | 36 | .closeConnection <- function(s) 37 | { 38 | close(s) 39 | } 40 | 41 | # .redisError may be called by any function when a serious error occurs. 42 | # It will print an indicated error message, attempt to reset the current 43 | # Redis server connection, and signal the error. 44 | .redisError <- function(msg) 45 | { 46 | env <- .redisEnv$current 47 | con <- .redis() 48 | .closeConnection(con) 49 | # May stop with an error here on connect fail 50 | con <- .openConnection(host=env$host, 51 | port=env$port, nodelay=env$nodelay, envir=env) 52 | stop(as.character(msg)) 53 | } 54 | 55 | .redisPP <- function() 56 | { 57 | # Ping-pong 58 | .redisCmd(.raw('PING')) 59 | } 60 | 61 | .cerealize <- function(value) 62 | { 63 | if("redis string value" %in% names(attributes(value))) 64 | { 65 | value <- tryCatch(charToRaw(value) , error=function(e) value) 66 | } 67 | if(!is.raw(value)) serialize(value,ascii=FALSE,connection=NULL) 68 | else value 69 | } 70 | 71 | # Burn data in the RX buffer, used after interrupt conditions 72 | .burn <- function(e) 73 | { 74 | con <- .redis() 75 | count <- 0 76 | while(socketSelect(list(con),timeout=1L) && count < 5) 77 | { 78 | readBin(con, raw(), 5000000L) 79 | count <- count + 1 80 | } 81 | .redisError(e) 82 | } 83 | 84 | # 85 | # .raw converts single length character values to raw via charToRaw, 86 | # otherwise serializes the value 87 | # 88 | .raw <- function(word) 89 | { 90 | if(is.raw(word)) word 91 | if(is.character(word) && length(word) == 1) charToRaw(word) 92 | else .cerealize(word) 93 | } 94 | 95 | # Expose the basic Redis interface to the user, interpreting single-length 96 | # character values as raw for user convenience (cf. the internal .redisCmd) 97 | redisCmd <- function(CMD, ..., raw=FALSE) 98 | { 99 | a <- c(alist(),list(.raw(CMD)), 100 | lapply(list(...), function(x) .raw(x))) 101 | if(raw) a <- c(a,raw=TRUE) 102 | do.call('.redisCmd', a) 103 | } 104 | 105 | # .redisCmd corresponds to the Redis "multi bulk" protocol. It 106 | # expects an argument list of command elements. Arguments that 107 | # are not of type raw are serialized. 108 | # Examples: 109 | # .redisCmd(.raw('INFO')) 110 | # .redisCmd(.raw('SET'), .raw('X'), runif(5)) 111 | # 112 | # We use match.call here instead of, for example, as.list() to try to 113 | # avoid making unnecessary copies of (potentially large) function arguments. 114 | # 115 | # TODO 116 | # We can further improve this by writing a shadow serialization routine that 117 | # quickly computes the length of a serialized object without serializing it. 118 | # Then, we could serialize directly to the connection, avoiding the temporary 119 | # copy. 120 | .redisCmd <- function(...) 121 | { 122 | env <- .redisEnv$current 123 | con <- .redis() 124 | # Check to see if a rename list exists and use it if it does...we also 125 | # define a little helper function to handle replacing the command. 126 | # The rename list must have the form: 127 | # list(OLDCOMMAND="NEWCOMMAND", SOME_OTHER_CMD="SOME_OTHER_NEW_CMD",...) 128 | rep <- c() 129 | if(exists("rename",envir=.redisEnv)) rep = get("rename",envir=.redisEnv) 130 | f <- match.call() 131 | # Check for raw option (which means don't deserialize returned resuts) 132 | raw <- FALSE 133 | if(any("raw" %in% names(f))) 134 | { 135 | wr <- which(names(f)=="raw") 136 | raw <- f[[wr]] 137 | f <- f[-wr] 138 | } 139 | n <- length(f) - 1 140 | hdr <- sprintf('*%d\r\n', n) 141 | writeBin(.raw(hdr), con) 142 | tryCatch({ 143 | for(j in seq_len(n)) { 144 | if(j == 1) 145 | v <- .renameCommand(eval(f[[j+1]],envir=sys.frame(-1)), rep) 146 | else 147 | v <- eval(f[[j+1]],envir=sys.frame(-1)) 148 | if(!is.raw(v)) v <- .cerealize(v) 149 | l <- length(v) 150 | hdr <- sprintf('$%d\r\n', l) 151 | writeBin(c(.raw(hdr), v, .raw('\r\n')), con) 152 | } 153 | }, 154 | error=function(e) {.redisError("Invalid argument"); invisible()}, 155 | interrupt=function(e) .burn(e$message) 156 | ) 157 | 158 | pipeline <- FALSE 159 | if(exists('pipeline',envir=env)) pipeline <- get('pipeline',envir=env) 160 | if(!pipeline) 161 | return(.getResponse(raw=raw)) 162 | tryCatch( 163 | env$count <- env$count + 1, 164 | error = function(e) assign('count', 1, envir=env) 165 | ) 166 | invisible() 167 | } 168 | 169 | .renameCommand <- function(x, rep) 170 | { 171 | if(is.null(rep)) return(x) 172 | v <- rawToChar(x) 173 | if(v %in% names(rep)) return(charToRaw(rep[[v]])) 174 | x 175 | } 176 | 177 | .getResponse <- function(raw=FALSE) 178 | { 179 | env <- .redisEnv$current 180 | tryCatch({ 181 | con <- .redis() 182 | l <- readLines(con=con, n=1) 183 | 184 | if(length(l)==0) .burn("Empty") 185 | tryCatch( 186 | env$count <- max(env$count - 1,0), 187 | error = function(e) assign('count', 0, envir=env) 188 | ) 189 | s <- substr(l, 1, 1) 190 | if (nchar(l) < 2) { 191 | if(s == "+") { 192 | # '+' is a valid retrun message for at least one cmd (RANDOMKEY) 193 | return("") 194 | } 195 | .burn("Invalid") 196 | } 197 | switch(s, 198 | '-' = stop(substr(l,2,nchar(l))), 199 | '+' = substr(l,2,nchar(l)), 200 | ':' = { 201 | if(!is.null(getOption('redis:num'))) return(as.numeric(substr(l,2,nchar(l)))) 202 | un <- substr(l,2,nchar(l)) 203 | attr(un, "redis string value") <- TRUE 204 | un 205 | }, 206 | '$' = { 207 | n <- as.numeric(substr(l,2,nchar(l))) 208 | if (n < 0) { 209 | return(NULL) 210 | } 211 | dat <- tryCatch(readBin(con, 'raw', n=n), 212 | error=function(e) .redisError(e$message)) 213 | m <- length(dat) 214 | if(m==n) 215 | { 216 | l <- readLines(con,n=1) 217 | if(raw) 218 | return(dat) 219 | else 220 | return(tryCatch(unserialize(dat), 221 | error=function(e) 222 | { 223 | un <- rawToChar(dat) 224 | attr(un, "redis string value") <- TRUE 225 | un 226 | })) 227 | } 228 | # The message was not fully recieved in one pass for whatever reason. 229 | # We allocate a list to hold incremental messages and then concatenate it. 230 | # This perfromance enhancement was adapted from the Rbig server package, 231 | # written by Steve Weston and Pat Shields. 232 | rlen <- 50 233 | j <- 1 234 | r <- vector('list',rlen) 235 | r[j] <- list(dat) 236 | while(mrlen) 242 | { 243 | rlen <- 2*rlen 244 | length(r) <- rlen 245 | } 246 | r[j] <- list(dat) 247 | m <- m + length(dat) 248 | } 249 | l <- readLines(con,n=1) # Trailing \r\n 250 | length(r) <- j 251 | if(raw) 252 | do.call(c,r) 253 | else 254 | tryCatch(unserialize(do.call(c,r)), 255 | error=function(e) rawToChar(do.call(c,r))) 256 | }, 257 | '*' = { 258 | numVars <- as.integer(substr(l,2,nchar(l))) 259 | if(numVars > 0L) { 260 | replicate(numVars, .getResponse(raw=raw), simplify=FALSE) 261 | } else NULL 262 | }, 263 | stop('Unknown message type') 264 | ) 265 | }, interrupt=function(e) .burn(e$message) 266 | ) 267 | } 268 | -------------------------------------------------------------------------------- /vignettes/rredis.Rnw: -------------------------------------------------------------------------------- 1 | %\VignetteIndexEntry{rredis Manual} 2 | %\VignetteDepends{rredis} 3 | %\VignettePackage{rredis} 4 | \documentclass[12pt]{article} 5 | \usepackage{amsmath} 6 | \usepackage[pdftex]{graphicx} 7 | \usepackage{color} 8 | \usepackage{xspace} 9 | \usepackage{fancyvrb} 10 | \usepackage{fancyhdr} 11 | \usepackage[ 12 | colorlinks=true, 13 | linkcolor=blue, 14 | citecolor=blue, 15 | urlcolor=blue] 16 | {hyperref} 17 | \usepackage{lscape} 18 | \usepackage{Sweave} 19 | \usepackage{tabularx} 20 | \usepackage{listings} 21 | \usepackage{mdwlist} 22 | 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | 25 | % define new colors for use 26 | \definecolor{darkgreen}{rgb}{0,0.6,0} 27 | \definecolor{darkred}{rgb}{0.6,0.0,0} 28 | \definecolor{lightbrown}{rgb}{1,0.9,0.8} 29 | \definecolor{brown}{rgb}{0.6,0.3,0.3} 30 | \definecolor{darkblue}{rgb}{0,0,0.8} 31 | \definecolor{darkmagenta}{rgb}{0.5,0,0.5} 32 | 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | 35 | \newcommand{\bld}[1]{\mbox{\boldmath $#1$}} 36 | \newcommand{\shell}[1]{\mbox{$#1$}} 37 | \renewcommand{\vec}[1]{\mbox{\bf {#1}}} 38 | \newcommand{\ReallySmallSpacing}{\renewcommand{\baselinestretch}{.6}\Large\normalsize} 39 | \newcommand{\SmallSpacing}{\renewcommand{\baselinestretch}{1.1}\Large\normalsize} 40 | \def\tm{\leavevmode\hbox{$\rm {}^{TM}$}} 41 | 42 | 43 | \setlength{\oddsidemargin}{-.25 truein} 44 | \setlength{\evensidemargin}{0truein} 45 | \setlength{\topmargin}{-0.2truein} 46 | \setlength{\textwidth}{7 truein} 47 | \setlength{\textheight}{8.5 truein} 48 | \setlength{\parindent}{0.20truein} 49 | \setlength{\parskip}{0.10truein} 50 | 51 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 52 | \pagestyle{fancy} 53 | \lhead{} 54 | \chead{The {\tt rredis} Package} 55 | \rhead{} 56 | \lfoot{} 57 | \cfoot{} 58 | \rfoot{\thepage} 59 | \renewcommand{\headrulewidth}{1pt} 60 | \renewcommand{\footrulewidth}{1pt} 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | \title{The {\tt rredis} Package} 63 | \author{Bryan W. Lewis \\ 64 | blewis@illposed.net\\ 65 | {\it and contributions from many others}} 66 | 67 | \begin{document} 68 | \maketitle 69 | 70 | \thispagestyle{empty} 71 | 72 | \setlength{\parindent}{0in} 73 | \section{Introduction} 74 | 75 | The {\tt rredis} package provides a native R interface to Redis. Redis is an 76 | in memory key/value database with many innovative features written by Salvatore 77 | Sanfilippo\footnote{https://github.com/antirez}. It supports data persistence, 78 | networked client/server operation, command pipelining, structured value types, 79 | server replication, data expiration, clustering, multicast-like 80 | publish/subscribe, and it's very fast. 81 | 82 | The following simple example illustrates a typical use of the rredis package: 83 | \lstset{columns=flexible, basicstyle={\ttfamily\slshape}} 84 | \begin{lstlisting} 85 | > library("rredis") 86 | > redisConnect() 87 | > redisSet("x",rnorm(5)) 88 | [1] "OK" 89 | > redisGet("x") 90 | [1] 0.808448325 0.341482747 -0.728739322 -0.105507214 -0.002349064 91 | \end{lstlisting} 92 | The key name ``x'' is associated with the R vector produced by \verb+rnorm(5)+ 93 | and stored in Redis. Note that the R object associated with ``x'' is available 94 | to other rredis clients, and indeed to any Redis client that can deserialize R 95 | objects. Neither the Redis server nor the rredis clients need reside on the 96 | machine on which the result was generated. Depending on the Redis server 97 | settings, ``x'' can be persistent--that is the value and its association with 98 | ``x'' will persist even if the Redis server is terminated and re-started. 99 | 100 | Values in Redis are classified by type. Value types are perhaps the most 101 | distinguishing feature of Redis. 102 | \begin{itemize} 103 | \item The canonical {\it string} type holds general-purpose 104 | objects, for example any serializable R object, text, or arbitrary binary data. 105 | \item The {\it list} type represents lists of Redis {\it string} objects, 106 | ordered by insertion order. Data can be accessed from lists with stack-like 107 | PUSH and POP operations, or by directly indexing ranges of elements. 108 | Importantly, redis lists support atomic blocking and asynchronous operation. 109 | \item Redis {\it sets} are unordered 110 | collections of unique Redis {\it strings} equipped with typical set operations 111 | like unions and intersections. Uniqueness is enforced by Redis at 112 | insertion-time. Redis also supports operations on ordered sets, 113 | with set commands prefixed by ``Z.'' 114 | \item Redis {\it hashes} are collections of Redis {\it strings} indexed 115 | by a hashed set of secondary keys. 116 | \end{itemize} 117 | 118 | Expiration intervals or absolute expiration times may be set on any Redis 119 | value. The Redis server can handle lots of small transactions with aplomb, 120 | easily exceeding 50,000 transactions/second even on very limited 121 | hardware\footnote{Redis easily exceeds 100,000 transactions/second on typical 122 | high-end workstations}. 123 | 124 | \section{Supported Platforms} 125 | The Redis server is written in ANSI C and supported on most POSIX systems 126 | including GNU/Linux, Solaris, *BSD, and Mac OS X. 127 | Microsoft supports a fork of Redis for Windows available here: 128 | \htmladdnormallink{https://github.com/MSOpenTech/redis}{https://github.com/MSOpenTech/redis}. 129 | 130 | The rredis package for R is supported on all supported R platforms, including 131 | Microsoft Windows, and can connect to a Redis server running on a supported 132 | platform. 133 | 134 | Redis clients are available for lots of languages other than R, including 135 | Java, C, C\#, Ruby, Python, PHP, Tcl, Perl, Erlang, Clojure, JavaScript, 136 | Scala, and more... 137 | 138 | \subsection{Obtaining and Installing the Redis server}\label{install} 139 | 140 | Redis is an open-source project available from 141 | \htmladdnormallink{http://redis.io}{http://redis.io}, with source code 142 | available from Github at 143 | \htmladdnormallink{http://github.com/antirez/redis}{http://github.com/antirez/redis}. 144 | Redis is also available as an installable package for most modern GNU/Linux 145 | operating systems. 146 | 147 | The Redis server is completely configured by the file 148 | \verb+redis.conf+. 149 | In order to run the Redis server as a background process, 150 | edit this file and change the line: 151 | 152 | \noindent \verb+daemonize no+ 153 | 154 | \noindent to: 155 | 156 | \noindent \verb+daemonize yes+ 157 | 158 | Most default Redis configuration files are set to disconnect connected 159 | clients after an inactivity time out interval. It's possible to disable 160 | that behavior in the \verb_redis.conf_ file with: 161 | 162 | \noindent \verb+timeout 0+ 163 | 164 | \noindent You may wish to peruse the rest of the configuration file and 165 | experiment with the other server settings as well. Finally, start up the 166 | Redis server with 167 | \lstset{columns=flexible, basicstyle={\ttfamily\slshape}} 168 | \begin{lstlisting} 169 | redis-server ./redis.conf 170 | \end{lstlisting} 171 | Note that some packaged versions of Redis on GNU/Linux set the Redis 172 | server to start on boot as a service. 173 | 174 | \section{The rredis Package by Example} 175 | 176 | We explore operation of many of the Redis features available to R 177 | through a few examples. Seek out the rredis package documentation and the 178 | excellent Redis Wiki referenced therein for additional help and examples. 179 | 180 | \subsection{Basic Operation and Redis Strings} 181 | Redis {\it strings} represent the canonical value type. They are used to 182 | store any R object that can be serialized to a bit-stream. Most R objects 183 | are serializable. Notable exceptions include objects with open connections 184 | and external reference pointers. 185 | 186 | We assume from now on that the rredis package is loaded in the running R 187 | session using either 188 | \begin{lstlisting} 189 | require("rredis") 190 | \end{lstlisting} 191 | or 192 | \begin{lstlisting} 193 | library("rredis") 194 | \end{lstlisting} 195 | prior to running any example. 196 | 197 | Open a connection to a Redis server with \texttt{redisConnect}. By default, 198 | \texttt{redisConnect()} attempts to connect to a Redis server locally on 199 | a default port (6379). Explicitly specify a host and/or port to connect 200 | to a server running on a computer different from the computer on which 201 | the R session is running, for example, 202 | \begin{lstlisting} 203 | redisConnect(host="illposed.net", port=5555) 204 | \end{lstlisting} 205 | to connect to a Redis server running on host 'illposed.net' at port 5555. 206 | 207 | 208 | Once connected we can easily store and retrieve values in the Redis 209 | database with \texttt{redisSet} and \texttt{redisGet}: 210 | \begin{lstlisting} 211 | > x <- rnorm(5) 212 | > print(x) 213 | [1] -0.3297596 1.0417431 -1.3216719 -0.8186305 -0.2705817 214 | > redisSet("x",x) 215 | [1] "OK" 216 | > y <- redisGet("x") 217 | > print(y) 218 | [1] -0.3297596 1.0417431 -1.3216719 -0.8186305 -0.2705817 219 | > all.equal(x,y) 220 | [1] TRUE 221 | > redisGet("z") 222 | NULL 223 | \end{lstlisting} 224 | Note that one must explicitly specify a key name (``x'' in the above example) 225 | and that Redis key names need not correspond to R variable names. 226 | 227 | The SET/GET operations are atomic--that is, multiple SET and or GET operations 228 | are guaranteed not to simultaneously occur. 229 | And \texttt{redisGet} always returns immediately, even if a value is 230 | not available in which case it returns NULL (see the example). 231 | 232 | The true power of Redis becomes apparent when we share values across multiple 233 | clients. For example, start up a new R session and try: 234 | \begin{lstlisting} 235 | > library("rredis") 236 | > redisConnect() 237 | > y <- redisGet("x") 238 | > print(y) 239 | [1] -0.3297596 1.0417431 -1.3216719 -0.8186305 -0.2705817 240 | \end{lstlisting} 241 | 242 | The default behavior of Redis is to make the database persistent, so the 243 | value associated with ``x'' in the above examples will last until it is 244 | overwritten or explicitly removed, even if the Redis server is re-started. 245 | One may immediately purge Redis of all key/value pairs with the 246 | (dangerous) \texttt{redisFlushAll} command. 247 | 248 | Redis supports multiple distinct key workspaces, indexed by number. 249 | Access may be switched 250 | between workspaces with the \texttt{redisSelect} function as illustrated below. 251 | We also use \texttt{redisKeys} to list all key names in the current workspace. 252 | \begin{lstlisting} 253 | > redisKeys() 254 | [[1]] 255 | [1] "x" 256 | 257 | > redisSelect(1) 258 | [1] "OK" 259 | > redisKeys() 260 | NULL 261 | 262 | redisSelect(0) 263 | > redisKeys() 264 | [[1]] 265 | [1] "x" 266 | \end{lstlisting} 267 | The number of available workspaces is user-configurable in the \verb+redis.conf+ 268 | file (the default is 16). Note also that index values in Redis begin with 0. 269 | 270 | One may easily store and retrieve multiple objects in one operation with 271 | \texttt{redisMSet} and \texttt{redisMGet}. The example also illustrates how 272 | values may be expired (in this case, after one second) with 273 | \texttt{redisExpire}. 274 | \begin{lstlisting} 275 | > redisMSet(list(x=pi,y=runif(5),z=sqrt(2))) 276 | [1] "OK" 277 | > redisMGet(c("x","y","z")) 278 | $x 279 | [1] 3.141593 280 | $y 281 | [1] 0.85396951 0.80191589 0.21750311 0.02535608 0.11929247 282 | $z 283 | [1] 1.414214 284 | 285 | > redisExpire("z",1) 286 | [1] 1 287 | > Sys.sleep(1) 288 | > redisGet("z") 289 | NULL 290 | \end{lstlisting} 291 | 292 | \subsection{Sharing Data with Clients other than R} 293 | 294 | Redis is a particularly convenient system for sharing data between many 295 | different applications. We illustrate cross-application communication with 296 | simple examples using R and the \texttt{redis-cli} command-line program that is 297 | included with the Redis server. 298 | 299 | Store a sample value in the Redis database with the {\texttt{redis-cli}} 300 | program from the command line as follows: 301 | \begin{lstlisting} 302 | redis-cli set shell "Greetings, R client!" 303 | OK 304 | \end{lstlisting} 305 | Now, leaving the terminal window open, from an R session, try: 306 | \begin{lstlisting} 307 | > redisGet("shell") 308 | [1] "Greetings, R client!" 309 | attr(,"redis string value") 310 | [1] TRUE 311 | \end{lstlisting} 312 | And, voil\`{a}, R and shell communicate text through Redis. 313 | The returned character string value is decorated with an attribute 314 | named "redis string value" to indicate that the original value in 315 | Redis was not a serialized R object. 316 | 317 | When R values with the "redis string value" attribute are uploaded 318 | to Redis, R serialization is bypassed and the value is uploaded 319 | as raw binary data. This mechanism was introduced to preserve 320 | the original nature of Redis values through download/upload 321 | sequences. For example: 322 | \begin{lstlisting} 323 | > x <- redisGet("shell") 324 | > redisSet("hello", x) 325 | \end{lstlisting} 326 | We can now use the {\texttt{redis-cli}} client to recover the 327 | value inserted by R from the new key: 328 | \begin{lstlisting} 329 | redis-cli get hello 330 | "Greetings, R client!" 331 | \end{lstlisting} 332 | 333 | In general, however, R objects are serialized by default before 334 | uploading to Redis. Consider the following example: 335 | \begin{lstlisting} 336 | > redisSet("R", "Greetings, shell client!") 337 | \end{lstlisting} 338 | And now, switch over to the shell client and run: 339 | \begin{lstlisting} 340 | ./redis-cli get R 341 | <> 342 | \end{lstlisting} 343 | This example produces undesirable results because the default behavior 344 | of the R \texttt{redisSet} command is to store data as R objects, which 345 | the shell client cannot decipher. Instead, we must encode the R object 346 | (in this case, a character string) in a format that shell can understand: 347 | \begin{lstlisting} 348 | > redisSet("R", charToRaw("Greetings, shell client!")) 349 | [1] "OK" 350 | \end{lstlisting} 351 | And now, switch over to the shell client and run: 352 | \begin{lstlisting} 353 | ./redis-cli get R 354 | Greetings, shell client! 355 | \end{lstlisting} 356 | It can be tricky to share arbitrary R objects with other languages, but 357 | raw character strings usually provide a reasonable, if sometimes 358 | inefficient, common tongue. 359 | 360 | The {\tt raw=TRUE} option may be set on most package functions that 361 | receive data, for example {\tt redisGet}. Use the {\tt{RAW}} option 362 | to leave the message data as is (otherwise the functions try to deserialize 363 | it to a standard R object). The {\tt{RAW}} format is useful for binary 364 | exchange of data with programs other than R. 365 | 366 | \subsection{Redis Lists} 367 | Redis list value types provide us with a remarkably powerful and rich set of 368 | operations. Redis lists may be used to set up data queues and they may be 369 | accessed either synchronously or asynchronously. 370 | 371 | We walk through basic Redis list operation in the first example below. 372 | The example shows how \texttt{redisLPush} pushes values onto a list from 373 | the left, and \texttt{redisRPush} pushes values from the right. 374 | \begin{lstlisting} 375 | > redisLPush("a",1) 376 | [1] 1 377 | > redisLPush("a",2) 378 | [1] 2 379 | > redisLPush("a",3) 380 | [1] 3 381 | > redisLRange("a",0,2) 382 | [[1]] 383 | [1] 3 384 | [[2]] 385 | [1] 2 386 | [[3]] 387 | [1] 1 388 | 389 | > redisLPop("a") 390 | [1] 3 391 | > redisLRange("a",0,-1) 392 | [[1]] 393 | [1] 2 394 | [[2]] 395 | [1] 1 396 | 397 | > redisRPush("a","A") 398 | [1] 3 399 | > redisRPush("a","B") 400 | [1] 4 401 | > redisLRange("a",0,-1) 402 | [[1]] 403 | [1] 2 404 | [[2]] 405 | [1] 1 406 | [[3]] 407 | [1] "A" 408 | [[4]] 409 | [1] "B" 410 | 411 | > redisRPop("a") 412 | [1] "B" 413 | \end{lstlisting} 414 | 415 | Like the \texttt{redisGet} function, \texttt{redisLPop} and \texttt{redisRPop} 416 | always return immediately, even when no value is available in which case they 417 | return NULL. Redis includes a blocking variant of the list ``Pop'' commands 418 | that is illustrated in the next example. 419 | \begin{lstlisting} 420 | > redisBLPop("b",timeout=1) 421 | NULL 422 | 423 | > redisLPush("b",runif(5)) 424 | [1] 1 425 | > redisBLPop("b",timeout=1) 426 | $b 427 | [1] 0.3423658 0.4188430 0.2494071 0.9960606 0.5643137 428 | \end{lstlisting} 429 | In the first case above, the NULL value is returned after a one-second timeout 430 | because no value was immediately available in the list. Once populated with 431 | data, the second attempt consumes the list value and returns immediately. 432 | 433 | We can also block on multiple lists, returning when data is available 434 | on at least one of the lists: 435 | \begin{lstlisting} 436 | > redisFlushAll() 437 | [1] "OK" 438 | > redisLPush("b",5) 439 | [1] 1 440 | > redisBLPop(c("a","b","c")) 441 | $b 442 | [1] 5 443 | \end{lstlisting} 444 | 445 | Although blocking list operations seem simple, they provide an extraordinarily 446 | powerful environment for coordinating events between multiple R (and other 447 | client) processes. The following example illustrates a simple event stream 448 | in which data is emitted periodically by a shell script, and consumed 449 | and processed as events arrive by an R process. 450 | 451 | First, open an R window and block on the ``a'' and ``b'' lists: 452 | \begin{lstlisting} 453 | > redisFlushAll() 454 | > for (j in 1:5) { 455 | + x <- redisBLPop(c("a","b")) 456 | + print (x) 457 | + } 458 | \end{lstlisting} 459 | Your R session should freeze, waiting for events to process. 460 | 461 | Now, open a terminal window and navigate to the directory that contains 462 | the \texttt{redis-cli} program. Run (the following may all be typed on 463 | one line): 464 | \begin{lstlisting} 465 | for x in 1 2 3 4 5;do sleep $x; 466 | if test $x == "2"; 467 | then ./redis-cli lpush a $x; 468 | else ./redis-cli lpush b $x; 469 | fi; 470 | done 471 | 472 | \end{lstlisting} 473 | 474 | And now you will see your R session processing the events as they are generated 475 | by the shell script: 476 | \begin{lstlisting} 477 | $b 478 | [1] "1" 479 | 480 | $a 481 | [1] "2" 482 | 483 | $b 484 | [1] "3" 485 | 486 | $b 487 | [1] "4" 488 | 489 | $b 490 | [1] "5" 491 | \end{lstlisting} 492 | 493 | Now, imagine that events may be processed independently, and that they occur 494 | at an extraordinary rate--a rate too fast for R to keep up. The solution in 495 | this case is simple, start up another R process and it will handle events 496 | as they come in, relieving the first R process of about half the event load. 497 | Still not enough, start up another, etc. 498 | 499 | Keeping in mind that the R clients can run on different computers, we realize 500 | that this simple example can easily lead to a very scalable parallel event 501 | processing system that requires very little programming effort! 502 | 503 | \subsection{Redis Sets} 504 | The Redis set value type operates somewhat like Redis lists, but only 505 | allowing unique values within a set. Sets also come equipped with the 506 | expected set operations, as illustrated in the following example. 507 | \begin{lstlisting} 508 | > redisSAdd("A",runif(2)) 509 | [1] 1 510 | > redisSAdd("A",55) 511 | [1] 1 512 | > redisSAdd("B",55) 513 | [1] 1 514 | > redisSAdd("B",rnorm(3)) 515 | [1] 1 516 | > redisSCard("A") 517 | [1] 2 518 | > redisSDiff(c("A","B")) 519 | [[1]] 520 | [1] 0.5449955 0.7848509 521 | 522 | > redisSInter(c("A","B")) 523 | [[1]] 524 | [1] 55 525 | 526 | > redisSUnion(c("A","B")) 527 | [[1]] 528 | [1] 55 529 | 530 | [[2]] 531 | [1] 0.5449955 0.7848509 532 | 533 | [[3]] 534 | [1] -1.3153612 0.9943198 -0.3725513 535 | \end{lstlisting} 536 | Redis sets do not include blocking operations. 537 | 538 | \subsection{Future Redis Commands} 539 | 540 | Redis changes and sometimes new Redis commands are introduced. Thanks to the 541 | elegant design of the underlying Redis protocol, the rredis package can 542 | support any Redis command, even those not yet explicitly wrapped by R functions 543 | in the package. 544 | 545 | Use the low-level \verb+redisCmd(CMD, ...)+ function 546 | to perform {\it any} 547 | Redis operation. The \verb+CMD+ argument must be a character 548 | string that represents a valid Redis command, see for example 549 | \htmladdnormallink{http://redis.io/commands}{http://redis.io/commands}. 550 | 551 | Replace the \verb+...+ with any additional arguments specific to the Redis 552 | command. Arguments that are not already in raw format will be converted to raw 553 | byte format, and non-character values will be serialized as R objects 554 | (character strings will be left as unserialized ASCII by default). 555 | 556 | Here is a simple example that emulates the \verb+redisSet+ and \verb+redisGet+ 557 | functions: 558 | \begin{lstlisting} 559 | > redisCmd("set","x",runif(5)) 560 | [1] "OK" 561 | 562 | > redisCmd("get","x") 563 | [1] 0.0006776408 0.5652672122 0.0985793471 0.5748420910 0.4098101135 564 | \end{lstlisting} 565 | 566 | 567 | 568 | \section{Performance Considerations and Limitations} 569 | Redis values are limited to $512\,$MB. R objects that exceed this size once 570 | serialized can't be stored in Redis. 571 | 572 | Redis is well-known as an exceptionally robust and high-performance key/value 573 | store. Although the rredis package uses the standard R connections 574 | interface (for maximum portability across all R platforms), it's performance as 575 | a Redis client is reasonable. The ideas outlined in this section and the next 576 | will help you get the most performance out of the rredis package. 577 | 578 | A frequent cause for performance anxiety using the rredis package 579 | occurs when rapidly executing many smallish transactions. Consider the 580 | next example, run locally on a pretty wimpy Linux laptop: 581 | \begin{lstlisting} 582 | > library("rredis") 583 | > redisConnect() 584 | > t1 <- proc.time() 585 | > for(j in 1:100) redisSet("x", j) 586 | > print(proc.time() - t1) 587 | 588 | user system elapsed 589 | 0.990 0.060 4.066 590 | 591 | \end{lstlisting} 592 | That performance seems terrible. After all, isn't Redis capable of tens of 593 | thousands of transactions per second? 594 | 595 | There are at least three approaches to improving the performance of the last 596 | example: Redis pipelining (the best way), enable TCP\_NODELAY, or use 597 | Wush Wu's alternate hiredis-based support package for rredis or an alternative 598 | hiredis-based R client package. 599 | 600 | \subsection{Redis Pipelining} 601 | 602 | The rredis package supports Redis pipelining. Quoting from the Wiki 603 | page 604 | \htmladdnormallink{http://redis.io/commands}{http://redis.io/commands}: 605 | \begin{quote} 606 | A Request/Response server can be implemented so that it is able to process new 607 | requests even if the client didn't already read the old responses. This way it 608 | is possible to send multiple commands to the server without waiting for the 609 | replies at all, and finally read the replies in a single step. 610 | \end{quote} 611 | 612 | Redis pipelining is enabled in the rredis package with the 613 | \verb+redisSetPipeline(TRUE)+ function. Once enabled, results are not 614 | immediately returned to the R client but instead cached at the Redis server 615 | until explicitly requested with the \verb+redisGetResponse+ function. 616 | 617 | Here is our example with pipelining enabled: 618 | \begin{lstlisting} 619 | > library("rredis") 620 | > redisConnect() 621 | > redisSetPipeline(TRUE) 622 | > t1 <- proc.time() 623 | > for(j in 1:100) redisSet("x", j) 624 | > resp <- redisGetResponse() 625 | > print(proc.time() - t1) 626 | 627 | user system elapsed 628 | 0.115 0.020 0.161 629 | 630 | \end{lstlisting} 631 | Now that's much better! 632 | 633 | You may find that it's inconvenient to always have to call \verb+getResponse+; 634 | thus pipelining is best reserved for circumstances similar to the above example 635 | that substantially benefit from it. 636 | 637 | \subsection{Enabling TCP\_NODELAY} 638 | 639 | Enabling the TCP\_NODELAY option is one performance approach that hiredis (the 640 | official Redis C library client) takes: see 641 | \htmladdnormallink{https://github.com/redis/hiredis}{https://github.com/redis/hiredis}. 642 | It disables the TCP Nagle 643 | congestion control algorithm and can flood your network with lots of Redis 644 | traffic resulting in heartburn for your system administrators. With that 645 | caveat, we recently added the ability to support this in the rredis package 646 | using standard R connections. Here is an example: 647 | 648 | \begin{lstlisting} 649 | > library("rredis") 650 | > redisConnect(nodelay=TRUE) 651 | > t1 <- proc.time() 652 | > for(j in 1:100) redisSet("x", j) 653 | > print(proc.time() - t1) 654 | 655 | user system elapsed 656 | 0.135 0.025 0.207 657 | 658 | \end{lstlisting} 659 | We see that enabling TCP\_NODELAY gives similar performance 660 | to the pipelined approach (at least on a wimpy laptop) 661 | without the added inconvenience of requiring \verb+getResponse+. 662 | 663 | \subsection{Alternate clients} 664 | Wush Wu and Dirk Eddelbuettel have an R client for Redis based on the hiredis 665 | C library that generally gives better performance than the rredis 666 | package a the expense of portability and disabling Nagle all the time. Wush 667 | is also working on a pluggable hiredis support package for the rredis 668 | package that should be available soon. Here are some links of interest: 669 | \htmladdnormallink{https://github.com/eddelbuettel/rhiredis}{https://github.com/eddelbuettel/rhiredis}\newline 670 | \htmladdnormallink{https://github.com/wush978/rredis}{https://github.com/wush978/rredis} 671 | 672 | 673 | \section{Transactions} 674 | Redis supports batch submission of multiple Redis operations. 675 | Aggregating operations with transactions can in many cases significantly 676 | increase performance. The following 677 | description is adapted from the Redis documentation at 678 | \htmladdnormallink{http://redis.io}{http://redis.io}: 679 | 680 | The {\tt redisMulti}, {\tt redisExec}, {\tt redisDiscard} and {\tt redisWatch} 681 | form the foundation of transactions in Redis. They allow the execution of a 682 | group of commands in a single step, with two important guarantees: 683 | 684 | \begin{enumerate} 685 | \item 686 | All the commands in a transaction are serialized and executed sequentially. It 687 | can never happen that a request issued by another client is served in the 688 | middle of the execution of a Redis transaction. This guarantees that the 689 | commands are executed as a single atomic operation. 690 | \item 691 | Either all of the commands or none are processed. The {\tt redisExec} command 692 | triggers the execution of all the commands in the transaction, so if a client 693 | loses the connection to the server in the context of a transaction before 694 | calling the {\tt redisMulti} command none of the operations are performed, 695 | instead if the {\tt redisExec} command is called, all the operations are 696 | performed. When using the append-only file Redis makes sure to use a single 697 | write(2) syscall to write the transaction on disk. However if the Redis server 698 | crashes or is killed by the system administrator in some hard way it is 699 | possible that only a partial number of operations are registered. Redis will 700 | detect this condition at restart, and will exit with an error. Using the 701 | redis-check-aof tool it is possible to fix the append only file that will 702 | remove the partial transaction so that the server can start again. 703 | \end{enumerate} 704 | 705 | Queued Redis commands may be discarded with the {\tt redisDiscard} function. 706 | Upon successful execution of a transaction, the results from all of the 707 | queued commands are returned as a list. 708 | 709 | The {\tt redisWatch} function provides a check and set style 710 | conditional transaction. Use {\tt redisWatch} to monitor any number of Redis 711 | keys. If any watched key values change prior to calling {\tt redisExec} the 712 | entire queued sequence will be discarded. Conditioning transactions with 713 | {\tt redisWatch} is quite useful in multi-client asynchronous settings. 714 | 715 | The following extremely basic example illustrates transactions conditional 716 | on no change in value corresponding to the ``z'' key: 717 | \begin{lstlisting} 718 | > redisWatch("z") 719 | [1] "OK" 720 | > redisMulti() 721 | [1] "OK" 722 | > redisSet("x",runif(3)) 723 | [1] "QUEUED" 724 | > redisSet("y",pi) 725 | [1] "QUEUED" 726 | > redisGet("x") 727 | [1] "QUEUED" 728 | > redisExec() 729 | [[1]] 730 | [1] "OK" 731 | 732 | [[2]] 733 | [1] "OK" 734 | 735 | [[3]] 736 | [1] 0.7620601 0.5982853 0.8274721 737 | \end{lstlisting} 738 | 739 | 740 | \section{Publish/Subscribe} 741 | 742 | The publish/subscribe functions let Redis clients reliably multicast (publish) 743 | messages over ``channels'' that any client may subscribe to. Channels are 744 | identified by name (character string). Use the {\tt redisSubscribe} function to 745 | subscribe to one or more channels. Use the {\tt redisPublish} function to 746 | transmit messages over a channel. Once subscribed, channels must be monitored 747 | for incoming messages using the {\tt redisGetResponse} function, usually in an 748 | event loop. Beware that the {\tt redisGetResponse} function indefinitely blocks 749 | for an incoming message on subscribed channels. 750 | 751 | Here is a simple example: 752 | 753 | \begin{lstlisting} 754 | > redisSubscribe("channel1") 755 | 756 | # The loop will receive three messages from "channel1": 757 | > for(j in 1:3) print(redisGetResponse()) 758 | # A typical message might look like: 759 | [1]] 760 | [1] "message" 761 | 762 | [[2]] 763 | [1] "channel1" 764 | 765 | [[3]] 766 | [1] "message3" 767 | 768 | # Finally, unsubscribe to the channel: 769 | > redisUnsubscribe("channel1") 770 | \end{lstlisting} 771 | 772 | Note that the only Redis functions that may be used in between the 773 | {\tt redisSubscribe} and {\tt redisUnsubscribe} functions are 774 | {\tt redisGetResponse}, {\tt redisSubscribe}, and {\tt redisMonitorChannels} 775 | functions. 776 | 777 | \section{Miscellaneous} 778 | We cover a few miscellaneous features of the package here. 779 | 780 | \subsection{Renaming Redis Commands} 781 | 782 | Redis may be configured with renamed commands. This is one of the more obscure 783 | features of Redis. For example, suppose that we desire to rename the Redis 784 | commands "SET" and "GET" as "NEWSET" and "NETGET," respectively. 785 | That can be achieved by adding the following two lines to your 786 | redis.conf file: 787 | 788 | \begin{lstlisting} 789 | rename-command SET NEWSET 790 | rename-command GET NEWGET 791 | \end{lstlisting} 792 | 793 | Note that after restarting Redis with this configuration, the 794 | \verb+redisSet+ and \verb+redisGet+ won't work anymore since those 795 | commands have been renamed. 796 | 797 | In order to use the new names in the rredis package, create an R list 798 | with the replacement names as follows and place that list in a special 799 | environment used by the rredis package used to store state associated with 800 | open Redis connections: 801 | 802 | \begin{lstlisting} 803 | > assign("rename", list(SET="NEWSET", GET="NEWGET"), envir=rredis:::.redisEnv) 804 | \end{lstlisting} 805 | 806 | And then the normal \verb+redisSet+ and \verb+redisGet+ functions work again! 807 | Similarly rename any other renamed Redis commands. Note that this renaming 808 | strategy applies to the current running R session (it applies to 809 | {\it all} open Redis connections in that session). 810 | 811 | \subsection{Authentication} 812 | Redis supports a really basic password authentication scheme. If you use 813 | this, it's probably a good idea to use stunnel or an SSH tunnel or something 814 | similar to encrypt all network traffic between Redis clients and Redis. 815 | Otherwise passwords are transmitted in clear text over the network. 816 | 817 | Use the \verb+redisAuth(password)+ function to authenticate with Redis, or 818 | optionally supply the \verb+password+ argument to the \verb+redisConnect+ 819 | function. 820 | 821 | \end{document} 822 | --------------------------------------------------------------------------------