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
hiredisas 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 privatein octave as a workaround! https://savannah.gnu.org/bugs/?41723 inputnameis 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
appendthere 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.precisionwill 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)
dbnrcan 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
OKorERR: ... - 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