go-redis - GNU Octave redis client
...but Matlab is supported too. When I don't support Matlab, someone else will do and I have to emulate it with Octave.
Tested with Linux and Mac OS X.
For more detailed information next to this README.md
, take a look at the Wiki
- Data-Structure
- Collaborative Workspace
- Gaussian Elimination
- Supports pipeline: âś“
- Supports Redis-Cluster: âś“
- Classdef support
- Octave >= 4.0
- Matlab >= R2012b? (dunno when classdef was introduced...)
- C-Compiler
- hiredis library
- Linux or Mac OS X (never tried with Windows)
- install a C compiler
- Ubuntu:
sudo apt-get install build-essential
- Arch:
sudo pacman -S base-devel
- Mac: Install xcode
- install hiredis library
- Ubuntu:
sudo apt-get install libhiredis-dev libhiredis0.10
*for 14.04 LTS - Arch:
sudo pacman -S hiredis
- Mac:
brew install hiredis
- mex.h
- Distributed with your Matlab or GNU Octave installation
-
clone/download and build go-redis directly from Matlab/GNU Octave
>> cd go-redis/mex >> setup >> % go where ever you want and just do "addpath ('go-redis/inst')"
The default path to hiredis is set to /usr/include/hiredis
. You can change it by set a variable LIBPATH
with a absolute path to hiredis before running the setup script.
- optional - run tests
The mex
folder contains a test_redis.m
script with many assert()
checks.
>> test_redis
This test will delete all databases of your redis instance on 127.0.0.1 6379.
To continue type "YES": YES
everything passed
>>
You can compile it directly in the Matlab commandline.
mex -lhiredis -I/usr/include/hiredis/ CFLAGS='-fPIC -O2 -pedantic -std=c++11 -g' redis_.cpp
Afterwards mv redis_.mex*
from mex
folder into inst/private
folder.
From GNU Octave commandline
mkoctfile -lhiredis -I/usr/include/hiredis --mex -fPIC -O2 -pedantic -std=c++11 -g redis_.cpp
Afterwards mv redis_.mex
from mex
folder into inst/private
folder.
Currently (3/19/2015) there is a bug in classdef. You have to do addpath private
in octave as a workaround!
https://savannah.gnu.org/bugs/?41723
You can compile it in bash too
gcc -fPIC -I <PATH TO mex.h> -lm -I <PATH TO hiredis.h> -lhiredis -shared -O2 redis_.cpp -o redis_.mex
e.g.
gcc -fPIC -std=c++11 -I /usr/include/octave-4.0.0/octave/ -lm -I /usr/include/hiredis/ -lhiredis -shared -O2 -pedantic redis_.cpp -o redis_.mex
- maybe add
hiredis
as a submodule to simplify the setup process? - improve c-code
- still some problems with unicodes between matlab and GNU Octave (it's a natural problem between octave and matlab)
- improve
pipeline
(subclass)
-
pipeline()
can not handle cluster instances! -
GNU Octave
- there is a bug in classdef. You have to do
addpath private
in octave as a workaround! https://savannah.gnu.org/bugs/?41723 inputname
is currently not supported in a classdef environment. So you have to name you array by yourself when usingarray2redis
.
- there is a bug in classdef. You have to do
redis()
class is using inputParser, so you can switch inputarguments as you like
>> help redis
redis mex client for Matlab and GNU Octave
r = redis()
r = redis('hostname', '127.0.0.1')
r = redis('port', 6379)
r = redis('dbnr', 0)
r = redis('password', 'foobar')
r = redis('precision', 16)
r = redis('batchsize', 128)
r = redis('hostname', 'some.domain', 'password', 'thisone')
precision
- type double
- default:
4
- number of decimal points stored in
array2redis()
batchsize
- type double
- default:
64
- when number of commands in
pipeline
==batchsize
, it automatically execute thepipeline
.
verboseCluster
- boolean
- default:
false
- prints information when changing the instance in a cluster like
MOVED 6373 127.0.0.1:30002
hostname
- type char
- default:
127.0.0.1
port
- type double
- default:
6379
db
- type double
- default:
0
- database number to use
pwd
- type char
- default: empty
- auth password
>> r = redis()
r =
redis with properties:
precision: 4
batchsize: 64
verboseCluster: 1
ret = r.ping
ret =
PONG
r.set(key, value)
r.get(key)
r.getset(key, value)
r.append(key, value)
-
value can be a double or a char (expect
append
there it has to be a char) -
doubles will be converted to char
ret = r.set('go-redis', 1) ret = OK
-
return type of
GET*
commands will be a char or a double (depends on the reply of hiredis)
r.incr(key)
r.incrby(key, double)
r.incrbyfloat(key, double)
r.decr(key)
r.decrby(key, double)
-
r.precision
will handle the decimal places for*by...
command. -
return type will be double.
ret = r.incr('go-redis') ret = 2
r.del(key)
-
return will be true (1) or false (0)
>> r.del('s') ans = 1
r.move(key, dbnr)
- return will be true (1) or false (0)
dbnr
can be a char'1'
or a double1
.
r.db(newdbnr)
-
changing to another database number
>> r = r.db(1);
r.rename(oldkeyname, newkeyname)
- return will be
OK
orERR: ...
- keynames have to be chars
r.save()
- return will be
OK
r.type(key)
return will be a string
>> r.type('s')
ans =
string
An array reply will be transformed into a cell array in Octave/Matlab.
octave:2> r.call('keys *')
ans =
{
[1,1] = b
[2,1] = A
}
r.call(command)
- for debugging
- functions that are not directly supported by redis() class
- for disable the overhead of redis() class functions
- command can be a string or a cell (e.g.
{'SET', 'my keyname', 'this is a value'}
)
>> r.delete()
go-redis
support the redis-cluster automatically (when the redis instance is a cluster).
>> r = redis('127.0.0.1', 30001)
r =
redis with properties:
precision: 4
batchsize: 64
verboseCluster: 1
>> r.get('Z')
MOVED 15295 127.0.0.1:30003
ans =
5
>> r.get('A')
MOVED 6373 127.0.0.1:30002
ans =
4
>> r.verboseCluster = false;
>> r.set('Z', 7)
ans =
OK
>> r.get('Z')
ans =
7
r.pipeline(command)
r.execute()
Using r.pipeline
will speedup your writing commands 2-4x.
But be aware, pipeline()
is not implemented as a subclass! That means you have to put everything into a string by yourself at the moment.
But the cool thing is: the pipeline is executed automatically when a number of commands is reached. The default value of r.batchsize
is 64
.
So you just need to call r.execute()
(Yes, it takes no arguments!) one time when you're done to get execute the rest in your pipeline.
r = redis();
r.call('SET M 0');
tic
for n = 1:5000
r.call('INCR M');
end
toc
tic
for n = 1:5000
r = r.pipeline('INCR M');
end
r = r.execute();
toc
tic
for n = 1:5000
r.call('SET M 5');
end
toc
tic
for n = 1:5000
r = r.pipeline('SET M 5');
end
r = r.execute();
toc
command
can be a cell array too, like r = r.pipeline({'INCR', 'A'}); r = r.pipeline({'INCR', 'A'});
.
But you can pass a cell array of arguments too, to bypass the class functionality and its magic pipe execution.
r.call({'SET A 0'; 'INCR A'; 'INCR A'})
r.array2redis(array, name)
For storing a multidimension numeric array in redis
>> r.array2redis(rand(3,3), 'm')
ans =
1
r.redis2array(name)
For reading a multidimension numeric array from redis back into workspace
>> r.redis2array('m')
ans =
0.8147 0.9134 0.2785
0.9058 0.6324 0.5469
0.1270 0.0975 0.9575
r.range2array(name, x, y, z)
For reading just a range of an array which is stored in redis.
- it only support 2D and 3D numerical arrays
For the older go-redis version - pure written in Octave using
instrumen-control package - do git checkout fcf757b