hirlite 0.0.2.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/ext/hirlite_ext/hirlite_ext.h +1 -1
- data/ext/hirlite_ext/rlite.c +3 -23
- data/lib/hirlite/connection.rb +4 -0
- data/lib/hirlite/version.rb +1 -1
- data/vendor/rlite/deps/lua/src/lua_cjson.c +1 -1
- data/vendor/rlite/src/Makefile +12 -25
- data/vendor/rlite/src/dump.c +3 -3
- data/vendor/rlite/src/flock_posix.c +79 -0
- data/vendor/rlite/src/flock_win.c +6 -0
- data/vendor/rlite/src/hirlite.c +265 -25
- data/vendor/rlite/src/hyperloglog.c +1 -1
- data/vendor/rlite/src/lzf_c.c +1 -1
- data/vendor/rlite/src/lzf_d.c +1 -1
- data/vendor/rlite/src/page_btree.c +3 -3
- data/vendor/rlite/src/page_key.c +12 -13
- data/vendor/rlite/src/page_list.c +4 -4
- data/vendor/rlite/src/page_long.c +2 -2
- data/vendor/rlite/src/page_multi_string.c +5 -5
- data/vendor/rlite/src/page_skiplist.c +3 -3
- data/vendor/rlite/src/page_string.c +2 -2
- data/vendor/rlite/src/pubsub.c +448 -0
- data/vendor/rlite/src/restore.c +5 -5
- data/vendor/rlite/src/rlite.c +141 -146
- data/vendor/rlite/src/rlite.h +40 -12
- data/vendor/rlite/src/{constants.h → rlite/constants.h} +0 -0
- data/vendor/rlite/src/{crc64.h → rlite/crc64.h} +0 -0
- data/vendor/rlite/src/{dump.h → rlite/dump.h} +0 -0
- data/vendor/rlite/src/{endianconv.h → rlite/endianconv.h} +0 -0
- data/vendor/rlite/src/rlite/flock.h +8 -0
- data/vendor/rlite/src/{hirlite.h → rlite/hirlite.h} +1 -0
- data/vendor/rlite/src/{hyperloglog.h → rlite/hyperloglog.h} +0 -0
- data/vendor/rlite/src/{lzf.h → rlite/lzf.h} +0 -0
- data/vendor/rlite/src/{lzfP.h → rlite/lzfP.h} +0 -0
- data/vendor/rlite/src/{page_btree.h → rlite/page_btree.h} +0 -0
- data/vendor/rlite/src/{page_key.h → rlite/page_key.h} +0 -0
- data/vendor/rlite/src/{page_list.h → rlite/page_list.h} +0 -0
- data/vendor/rlite/src/{page_long.h → rlite/page_long.h} +0 -0
- data/vendor/rlite/src/{page_multi_string.h → rlite/page_multi_string.h} +0 -0
- data/vendor/rlite/src/{page_skiplist.h → rlite/page_skiplist.h} +0 -0
- data/vendor/rlite/src/{page_string.h → rlite/page_string.h} +0 -0
- data/vendor/rlite/src/{pqsort.h → rlite/pqsort.h} +0 -0
- data/vendor/rlite/src/rlite/pubsub.h +25 -0
- data/vendor/rlite/src/{rand.h → rlite/rand.h} +0 -0
- data/vendor/rlite/src/{restore.h → rlite/restore.h} +0 -0
- data/vendor/rlite/src/{scripting.h → rlite/scripting.h} +0 -0
- data/vendor/rlite/src/{sha1.h → rlite/sha1.h} +0 -0
- data/vendor/rlite/src/rlite/signal.h +11 -0
- data/vendor/rlite/src/{solarisfixes.h → rlite/solarisfixes.h} +0 -0
- data/vendor/rlite/src/{sort.h → rlite/sort.h} +0 -0
- data/vendor/rlite/src/{status.h → rlite/status.h} +1 -0
- data/vendor/rlite/src/{type_hash.h → rlite/type_hash.h} +0 -0
- data/vendor/rlite/src/{type_list.h → rlite/type_list.h} +0 -0
- data/vendor/rlite/src/{type_set.h → rlite/type_set.h} +0 -0
- data/vendor/rlite/src/{type_string.h → rlite/type_string.h} +0 -0
- data/vendor/rlite/src/{type_zset.h → rlite/type_zset.h} +0 -0
- data/vendor/rlite/src/{util.h → rlite/util.h} +2 -1
- data/vendor/rlite/src/{utilfromredis.h → rlite/utilfromredis.h} +0 -0
- data/vendor/rlite/src/rlite/wal.h +8 -0
- data/vendor/rlite/src/scripting.c +8 -10
- data/vendor/rlite/src/sha1.c +2 -2
- data/vendor/rlite/src/signal_posix.c +118 -0
- data/vendor/rlite/src/signal_win.c +17 -0
- data/vendor/rlite/src/sort.c +2 -2
- data/vendor/rlite/src/type_hash.c +4 -4
- data/vendor/rlite/src/type_list.c +4 -4
- data/vendor/rlite/src/type_set.c +4 -4
- data/vendor/rlite/src/type_string.c +4 -4
- data/vendor/rlite/src/type_zset.c +7 -7
- data/vendor/rlite/src/util.c +28 -5
- data/vendor/rlite/src/utilfromredis.c +1 -1
- data/vendor/rlite/src/wal.c +309 -0
- metadata +59 -35
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjUxZDMzOWRkZTFmMzM5MzczYWM4ODMwMDNhNjdiNzQ0N2M5ZDBkOQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZTVlOGRiYjkyZGIzZGFlOGFlNTg0YzBhZWJhMWZjYjE2ZmM0Y2U2OA==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjBjNDIxZjdiYTUwM2FlOWQ1ODFjOGI0Yjg3ZTllMmE3ZmU0NGYzZWYyNDMy
|
10
|
+
YzNkYzliYThhMjlhYWQ5NTBiNmJiOGY3YjhjYjAyOWZjNmE3MzFiZTY4YTBj
|
11
|
+
MmU0YzBlYWM3NDlhNGNkMTY2ZmM2Yzk3ZjUzMzI1MjEyMDliNjA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NDYwOWQ5YWE5OWI0MWFmNGQ4ZDk1YzIxZDU1MDliN2QyMDk0NTkzYWM0YTI1
|
14
|
+
NjgxNDY1MTZlZmM0YWE3MzI5NWRiYzZlNzI4MjhmMjg2MTVhMjVjOTJlZmFj
|
15
|
+
MTM0NWQzNTQ2NDYzNzZmNmQ2ZjNlOTAxMzhmMDY3OTVlYWVkODc=
|
data/ext/hirlite_ext/rlite.c
CHANGED
@@ -95,7 +95,7 @@ static VALUE rlite_parent_context_alloc(VALUE klass) {
|
|
95
95
|
return Data_Wrap_Struct(klass, parent_context_mark, parent_context_free, pc);
|
96
96
|
}
|
97
97
|
|
98
|
-
static VALUE rlite_generic_connect(VALUE self, rliteContext *c
|
98
|
+
static VALUE rlite_generic_connect(VALUE self, rliteContext *c) {
|
99
99
|
rliteParentContext *pc;
|
100
100
|
|
101
101
|
Data_Get_Struct(self,rliteParentContext,pc);
|
@@ -127,50 +127,30 @@ static VALUE rlite_connect(int argc, VALUE *argv, VALUE self) {
|
|
127
127
|
rliteContext *c;
|
128
128
|
VALUE arg_host = Qnil;
|
129
129
|
VALUE arg_port = Qnil;
|
130
|
-
VALUE arg_timeout = Qnil;
|
131
130
|
|
132
131
|
if (argc == 2 || argc == 3) {
|
133
132
|
arg_host = argv[0];
|
134
133
|
arg_port = argv[1];
|
135
|
-
|
136
|
-
if (argc == 3) {
|
137
|
-
arg_timeout = argv[2];
|
138
|
-
|
139
|
-
/* Sanity check */
|
140
|
-
if (NUM2INT(arg_timeout) <= 0) {
|
141
|
-
rb_raise(rb_eArgError, "timeout should be positive");
|
142
|
-
}
|
143
|
-
}
|
144
134
|
} else {
|
145
135
|
rb_raise(rb_eArgError, "invalid number of arguments");
|
146
136
|
}
|
147
137
|
|
148
138
|
c = rliteConnectNonBlock(StringValuePtr(arg_host), NUM2INT(arg_port));
|
149
|
-
return rlite_generic_connect(self,c
|
139
|
+
return rlite_generic_connect(self,c);
|
150
140
|
}
|
151
141
|
|
152
142
|
static VALUE rlite_connect_unix(int argc, VALUE *argv, VALUE self) {
|
153
143
|
rliteContext *c;
|
154
144
|
VALUE arg_path = Qnil;
|
155
|
-
VALUE arg_timeout = Qnil;
|
156
145
|
|
157
146
|
if (argc == 1 || argc == 2) {
|
158
147
|
arg_path = argv[0];
|
159
|
-
|
160
|
-
if (argc == 2) {
|
161
|
-
arg_timeout = argv[1];
|
162
|
-
|
163
|
-
/* Sanity check */
|
164
|
-
if (NUM2INT(arg_timeout) <= 0) {
|
165
|
-
rb_raise(rb_eArgError, "timeout should be positive");
|
166
|
-
}
|
167
|
-
}
|
168
148
|
} else {
|
169
149
|
rb_raise(rb_eArgError, "invalid number of arguments");
|
170
150
|
}
|
171
151
|
|
172
152
|
c = rliteConnectUnixNonBlock(StringValuePtr(arg_path));
|
173
|
-
return rlite_generic_connect(self,c
|
153
|
+
return rlite_generic_connect(self,c);
|
174
154
|
}
|
175
155
|
|
176
156
|
static VALUE rlite_is_connected(VALUE self) {
|
data/lib/hirlite/connection.rb
CHANGED
data/lib/hirlite/version.rb
CHANGED
data/vendor/rlite/src/Makefile
CHANGED
@@ -8,7 +8,8 @@
|
|
8
8
|
|
9
9
|
uname_S:= $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
10
10
|
|
11
|
-
OBJ=rlite.o page_skiplist.o page_string.o page_list.o page_btree.o page_key.o page_multi_string.o page_long.o type_string.o type_list.o type_set.o type_zset.o type_hash.o util.o restore.o dump.o sort.o pqsort.o utilfromredis.o hyperloglog.o sha1.o crc64.o lzf_c.o lzf_d.o scripting.o rand.o hirlite.o
|
11
|
+
OBJ=rlite.o page_skiplist.o page_string.o page_list.o page_btree.o page_key.o page_multi_string.o page_long.o type_string.o type_list.o type_set.o type_zset.o type_hash.o util.o restore.o dump.o sort.o pqsort.o utilfromredis.o hyperloglog.o sha1.o crc64.o lzf_c.o lzf_d.o scripting.o rand.o flock_posix.o signal_posix.o pubsub.o wal.o hirlite.o
|
12
|
+
LUA_OBJ=../deps/lua/src/lapi.o ../deps/lua/src/lcode.o ../deps/lua/src/ldebug.o ../deps/lua/src/ldo.o ../deps/lua/src/ldump.o ../deps/lua/src/lfunc.o ../deps/lua/src/lgc.o ../deps/lua/src/llex.o ../deps/lua/src/lmem.o ../deps/lua/src/lobject.o ../deps/lua/src/lopcodes.o ../deps/lua/src/lparser.o ../deps/lua/src/lstate.o ../deps/lua/src/lstring.o ../deps/lua/src/ltable.o ../deps/lua/src/ltm.o ../deps/lua/src/lundump.o ../deps/lua/src/lvm.o ../deps/lua/src/lzio.o ../deps/lua/src/strbuf.o ../deps/lua/src/fpconv.o ../deps/lua/src/lauxlib.o ../deps/lua/src/lbaselib.o ../deps/lua/src/ldblib.o ../deps/lua/src/liolib.o ../deps/lua/src/lmathlib.o ../deps/lua/src/loslib.o ../deps/lua/src/ltablib.o ../deps/lua/src/lstrlib.o ../deps/lua/src/loadlib.o ../deps/lua/src/linit.o ../deps/lua/src/lua_cjson.o ../deps/lua/src/lua_struct.o ../deps/lua/src/lua_cmsgpack.o ../deps/lua/src/lua_bit.o
|
12
13
|
LIBNAME=libhirlite
|
13
14
|
PKGCONFNAME=hirlite.pc
|
14
15
|
|
@@ -27,7 +28,6 @@ endif
|
|
27
28
|
|
28
29
|
CFLAGS += -I./ -I../deps/lua/src/
|
29
30
|
|
30
|
-
DEBUG.gcc += -rdynamic
|
31
31
|
CFLAGS.gcc += -std=c99
|
32
32
|
|
33
33
|
ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang version"), 1)
|
@@ -38,7 +38,7 @@ DEBUG += ${DEBUG.gcc}
|
|
38
38
|
CFLAGS += ${CFLAGS.gcc}
|
39
39
|
endif
|
40
40
|
|
41
|
-
LIBS=-lm
|
41
|
+
LIBS=-lm -lpthread
|
42
42
|
|
43
43
|
INSTALL?= cp -a
|
44
44
|
# Installation related variables and target
|
@@ -70,19 +70,11 @@ STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
|
|
70
70
|
|
71
71
|
all: $(DYLIBNAME) $(STLIBNAME)
|
72
72
|
|
73
|
-
gcov: CFLAGS += -fprofile-arcs -ftest-coverage
|
74
|
-
gcov: clean test
|
75
|
-
|
76
|
-
builddebug: CFLAGS += -DDEBUG=1
|
77
|
-
builddebug: clean buildtest
|
78
|
-
|
79
|
-
debug: builddebug vtest
|
80
|
-
|
81
73
|
ifeq ($(uname_S),SunOS)
|
82
74
|
# Make isinf() available
|
83
75
|
LUA_CFLAGS= -D__C99FEATURES__=1
|
84
76
|
endif
|
85
|
-
LUA_CFLAGS+= -O2 -Wall -DENABLE_CJSON_GLOBAL $(CFLAGS)
|
77
|
+
LUA_CFLAGS+= -O2 -Wall -DENABLE_CJSON_GLOBAL -fPIC $(CFLAGS)
|
86
78
|
LUA_LDFLAGS+= $(LDFLAGS)
|
87
79
|
LUA_STLIB=../deps/lua/src/liblua.a
|
88
80
|
AR=ar
|
@@ -96,9 +88,6 @@ lcov: gcov
|
|
96
88
|
lcov --directory . --capture --output-file lcov/app.info
|
97
89
|
genhtml lcov/app.info -o lcov/html
|
98
90
|
|
99
|
-
full-lcov: CFLAGS += -fprofile-arcs -ftest-coverage -DDEBUG=1
|
100
|
-
full-lcov: clean buildtest
|
101
|
-
|
102
91
|
clang-analyzer:
|
103
92
|
rm -rf analyzer
|
104
93
|
scan-build -o analyzer $(MAKE)
|
@@ -107,22 +96,19 @@ clang-analyzer:
|
|
107
96
|
$(CC) $(ARCH) $(DEBUG) $(CFLAGS) -c $<
|
108
97
|
|
109
98
|
$(DYLIBNAME): $(OBJ) lua
|
110
|
-
$(DYLIB_MAKE_CMD) $(
|
99
|
+
$(DYLIB_MAKE_CMD) $(LUA_OBJ) $(OBJ)
|
111
100
|
|
112
101
|
$(STLIBNAME): $(OBJ)
|
113
102
|
ar -cq libhirlite.a $(OBJ)
|
114
103
|
|
115
|
-
buildtest: $(STLIBNAME)
|
116
|
-
|
117
|
-
$(CC) $(DEBUG) $(CFLAGS) -o hirlite-test echo.o hash.o list.o parser.o set.o string.o test_hirlite.o zset.o db.o multi.o hsort.o scripting-test.o $(STLIBNAME) $(LUA_STLIB) $(LIBS)
|
104
|
+
buildtest: $(STLIBNAME)
|
105
|
+
cd ../tests/ && $(MAKE) buildtest
|
118
106
|
|
119
|
-
test:
|
120
|
-
|
121
|
-
./hirlite-test
|
107
|
+
test: $(STLIBNAME)
|
108
|
+
cd ../tests/ && $(MAKE) test
|
122
109
|
|
123
|
-
vtest:
|
124
|
-
|
125
|
-
valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./hirlite-test
|
110
|
+
vtest: $(STLIBNAME)
|
111
|
+
cd ../tests/ && $(MAKE) vtest
|
126
112
|
|
127
113
|
$(PKGCONFNAME): hirlite.h
|
128
114
|
@echo "Generating $@ for pkgconfig..."
|
@@ -149,3 +135,4 @@ install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
|
|
149
135
|
|
150
136
|
clean:
|
151
137
|
rm -rf *-test *.o *.a *.dSYM *.gcda *.gcno lcov *.dylib ./deps/lua/src/*.a
|
138
|
+
cd ../tests && $(MAKE) clean
|
data/vendor/rlite/src/dump.c
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#include <arpa/inet.h>
|
2
2
|
#include "rlite.h"
|
3
|
-
#include "util.h"
|
4
|
-
#include "crc64.h"
|
5
|
-
#include "endianconv.h"
|
3
|
+
#include "rlite/util.h"
|
4
|
+
#include "rlite/crc64.h"
|
5
|
+
#include "rlite/endianconv.h"
|
6
6
|
|
7
7
|
int rl_dump(struct rlite *db, const unsigned char *key, long keylen, unsigned char **data, long *datalen)
|
8
8
|
{
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#include <sys/fcntl.h>
|
2
|
+
#include <sys/file.h>
|
3
|
+
#include <sys/time.h>
|
4
|
+
#include <unistd.h>
|
5
|
+
#include <errno.h>
|
6
|
+
|
7
|
+
#include "rlite.h"
|
8
|
+
|
9
|
+
int rl_flock(FILE *fp, int type)
|
10
|
+
{
|
11
|
+
int fd = fileno(fp);
|
12
|
+
int locktype;
|
13
|
+
if (type == RLITE_FLOCK_SH) {
|
14
|
+
locktype = LOCK_SH;
|
15
|
+
} else if (type == RLITE_FLOCK_EX) {
|
16
|
+
locktype = LOCK_EX;
|
17
|
+
} else if (type == RLITE_FLOCK_UN) {
|
18
|
+
locktype = LOCK_UN;
|
19
|
+
} else {
|
20
|
+
return RL_UNEXPECTED;
|
21
|
+
}
|
22
|
+
flock(fd, locktype);
|
23
|
+
return RL_OK;
|
24
|
+
}
|
25
|
+
|
26
|
+
int rl_is_flocked(const char *path, int type)
|
27
|
+
{
|
28
|
+
int retval, oflags = O_NONBLOCK;
|
29
|
+
int locktype;
|
30
|
+
|
31
|
+
if (type == RLITE_FLOCK_SH) {
|
32
|
+
oflags |= O_RDONLY;
|
33
|
+
// we want to know if someone has a shared lock
|
34
|
+
// if we can get an exclusive, we know they do not
|
35
|
+
// if we cannot, we will try to get a shared to discard someone
|
36
|
+
// having an exclusive one
|
37
|
+
locktype = LOCK_EX;
|
38
|
+
} else if (type == RLITE_FLOCK_EX) {
|
39
|
+
oflags |= O_WRONLY;
|
40
|
+
// we'll get a shared lock iff nobody has an exclusive lock
|
41
|
+
locktype = LOCK_SH;
|
42
|
+
} else {
|
43
|
+
return RL_UNEXPECTED;
|
44
|
+
}
|
45
|
+
int fd = open(path, oflags);
|
46
|
+
if (fd == -1) {
|
47
|
+
// if the file does not exist, the lock is not found
|
48
|
+
if (errno == ENOENT || errno == EACCES) {
|
49
|
+
return RL_NOT_FOUND;
|
50
|
+
}
|
51
|
+
return RL_UNEXPECTED;
|
52
|
+
}
|
53
|
+
|
54
|
+
retval = flock(fd, locktype | LOCK_NB);
|
55
|
+
if (retval == 0) {
|
56
|
+
retval = RL_NOT_FOUND;
|
57
|
+
goto cleanup;
|
58
|
+
}
|
59
|
+
if (errno == EWOULDBLOCK) {
|
60
|
+
if (type == RLITE_FLOCK_SH) {
|
61
|
+
retval = flock(fd, LOCK_SH | LOCK_NB);
|
62
|
+
if (retval == 0) {
|
63
|
+
// can get a shared lock but not an exclusive
|
64
|
+
// thus someone has a shared lock
|
65
|
+
retval = RL_FOUND;
|
66
|
+
goto cleanup;
|
67
|
+
} else {
|
68
|
+
retval = RL_NOT_FOUND;
|
69
|
+
goto cleanup;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
retval = RL_FOUND;
|
73
|
+
goto cleanup;
|
74
|
+
}
|
75
|
+
retval = RL_UNEXPECTED;
|
76
|
+
cleanup:
|
77
|
+
close(fd);
|
78
|
+
return retval;
|
79
|
+
}
|
data/vendor/rlite/src/hirlite.c
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#include <stdio.h>
|
2
|
-
#include "constants.h"
|
2
|
+
#include "rlite/constants.h"
|
3
3
|
#include <assert.h>
|
4
4
|
#include <errno.h>
|
5
5
|
#include <ctype.h>
|
@@ -11,10 +11,11 @@
|
|
11
11
|
#include <time.h>
|
12
12
|
#include <unistd.h>
|
13
13
|
|
14
|
-
#include "hyperloglog.h"
|
15
|
-
#include "hirlite.h"
|
16
|
-
#include "scripting.h"
|
17
|
-
#include "util.h"
|
14
|
+
#include "rlite/hyperloglog.h"
|
15
|
+
#include "rlite/hirlite.h"
|
16
|
+
#include "rlite/scripting.h"
|
17
|
+
#include "rlite/util.h"
|
18
|
+
#include "rlite/pubsub.h"
|
18
19
|
|
19
20
|
#define UNSIGN(val) ((unsigned char *)val)
|
20
21
|
|
@@ -23,9 +24,13 @@
|
|
23
24
|
c->reply = createErrorObject(RLITE_WRONGTYPEERR);\
|
24
25
|
goto cleanup;\
|
25
26
|
}\
|
27
|
+
if (retval == RL_UNEXPECTED) {\
|
28
|
+
c->reply = createErrorObject("ERR unexpected");\
|
29
|
+
goto cleanup;\
|
30
|
+
}\
|
26
31
|
if (retval == RL_OVERFLOW) {\
|
27
32
|
c->reply = createErrorObject("ERR increment would produce NaN or Infinity");\
|
28
|
-
|
33
|
+
goto cleanup;\
|
29
34
|
}\
|
30
35
|
if (retval == RL_NAN) {\
|
31
36
|
c->reply = createErrorObject("ERR resulting score is not a number (NaN)");\
|
@@ -188,8 +193,7 @@ static int addReply(rliteContext* c, rliteReply *reply) {
|
|
188
193
|
c->replies = tmp;
|
189
194
|
}
|
190
195
|
|
191
|
-
c->replies[c->
|
192
|
-
c->replyLength++;
|
196
|
+
c->replies[c->replyLength++] = reply;
|
193
197
|
return RLITE_OK;
|
194
198
|
}
|
195
199
|
|
@@ -605,6 +609,10 @@ int rliteFormatCommandArgv(rliteClient *client, int argc, char **argv, size_t *a
|
|
605
609
|
return RLITE_OK;
|
606
610
|
}
|
607
611
|
|
612
|
+
static int refresh_rlite_fp(rliteContext* context) {
|
613
|
+
return rl_refresh(context->db);
|
614
|
+
}
|
615
|
+
|
608
616
|
#define DEFAULT_REPLIES_SIZE 16
|
609
617
|
static rliteContext *_rliteConnect(const char *path) {
|
610
618
|
rliteContext *context = malloc(sizeof(*context));
|
@@ -617,6 +625,15 @@ static rliteContext *_rliteConnect(const char *path) {
|
|
617
625
|
context = NULL;
|
618
626
|
goto cleanup;
|
619
627
|
}
|
628
|
+
size_t pathlen = 1 + strlen(path);
|
629
|
+
context->path = malloc(sizeof(char) * pathlen);
|
630
|
+
if (!context->path) {
|
631
|
+
free(context->replies);
|
632
|
+
free(context);
|
633
|
+
context = NULL;
|
634
|
+
goto cleanup;
|
635
|
+
}
|
636
|
+
memcpy(context->path, path, pathlen);
|
620
637
|
context->err = 0;
|
621
638
|
context->writeCommand = NULL;
|
622
639
|
context->replyPosition = 0;
|
@@ -627,18 +644,31 @@ static rliteContext *_rliteConnect(const char *path) {
|
|
627
644
|
context->cluster_enabled = 0;
|
628
645
|
context->hashtableLimitValue = 0;
|
629
646
|
context->inLuaScript = 0;
|
630
|
-
int retval = rl_open(path, &context->db, RLITE_OPEN_READWRITE | RLITE_OPEN_CREATE);
|
631
|
-
if (retval != RL_OK) {
|
632
|
-
free(context);
|
633
|
-
context = NULL;
|
634
|
-
goto cleanup;
|
635
|
-
}
|
636
647
|
context->inTransaction = 0;
|
637
648
|
context->transactionFailed = 0;
|
638
649
|
context->watchedKeysLength = context->enqueuedCommandsLength = 0;
|
639
650
|
context->watchedKeysAlloc = context->enqueuedCommandsAlloc = 0;
|
640
651
|
context->watchedKeys = NULL;
|
641
652
|
context->enqueuedCommands = NULL;
|
653
|
+
context->db = NULL;
|
654
|
+
int retval = rl_open(context->path, &context->db, RLITE_OPEN_READWRITE | RLITE_OPEN_CREATE);;
|
655
|
+
if (retval != RL_OK) {
|
656
|
+
free(context->path);
|
657
|
+
free(context->replies);
|
658
|
+
free(context);
|
659
|
+
context = NULL;
|
660
|
+
goto cleanup;
|
661
|
+
}
|
662
|
+
// if created, need to release locks
|
663
|
+
retval = rl_commit(context->db);
|
664
|
+
if (retval != RL_OK) {
|
665
|
+
rl_close(context->db);
|
666
|
+
free(context->path);
|
667
|
+
free(context->replies);
|
668
|
+
free(context);
|
669
|
+
context = NULL;
|
670
|
+
goto cleanup;
|
671
|
+
}
|
642
672
|
cleanup:
|
643
673
|
return context;
|
644
674
|
}
|
@@ -682,12 +712,15 @@ int rliteEnableKeepAlive(rliteContext *UNUSED(c)) {
|
|
682
712
|
return 0;
|
683
713
|
}
|
684
714
|
void rliteFree(rliteContext *c) {
|
685
|
-
|
715
|
+
if (c->db) {
|
716
|
+
rl_close(c->db);
|
717
|
+
}
|
686
718
|
int i;
|
687
719
|
for (i = c->replyPosition; i < c->replyLength; i++) {
|
688
720
|
rliteFreeReplyObject(c->replies[i]);
|
689
721
|
}
|
690
722
|
free(c->replies);
|
723
|
+
free(c->path);
|
691
724
|
free(c);
|
692
725
|
}
|
693
726
|
|
@@ -759,6 +792,7 @@ static void execCommand(rliteClient *c) {
|
|
759
792
|
c->reply = createErrorObject("EXECABORT Transaction discarded because of previous errors.");
|
760
793
|
goto cleanup;
|
761
794
|
}
|
795
|
+
RL_CALL(refresh_rlite_fp, RL_OK, c->context);
|
762
796
|
retval = rl_check_watched_keys(c->context->db, c->context->watchedKeysLength, c->context->watchedKeys);
|
763
797
|
RLITE_SERVER_ERR(c, retval);
|
764
798
|
if (retval != RL_OK) {
|
@@ -797,7 +831,7 @@ static void execCommand(rliteClient *c) {
|
|
797
831
|
if (command->sflags[i] == 'w') {
|
798
832
|
char *argv[] = {"multi"};
|
799
833
|
size_t argvlen[] = {5};
|
800
|
-
c->context->writeCommand(c->context->db
|
834
|
+
c->context->writeCommand(rl_get_selected_db(c->context->db), 1, argv, argvlen);
|
801
835
|
written = 1;
|
802
836
|
break;
|
803
837
|
}
|
@@ -805,7 +839,7 @@ static void execCommand(rliteClient *c) {
|
|
805
839
|
}
|
806
840
|
RL_CALL(rl_dirty_hash, RL_OK, client->context->db, &newhash);
|
807
841
|
if (newhash && (!oldhash || memcmp(newhash, oldhash, 20) != 0)) {
|
808
|
-
client->context->writeCommand(client->context->db
|
842
|
+
client->context->writeCommand(rl_get_selected_db(client->context->db), client->argc, client->argv, client->argvlen);
|
809
843
|
}
|
810
844
|
}
|
811
845
|
rl_free(oldhash);
|
@@ -817,7 +851,7 @@ static void execCommand(rliteClient *c) {
|
|
817
851
|
if (written) {
|
818
852
|
char *argv[] = {"exec"};
|
819
853
|
size_t argvlen[] = {4};
|
820
|
-
c->context->writeCommand(c->context->db
|
854
|
+
c->context->writeCommand(rl_get_selected_db(c->context->db), 1, argv, argvlen);
|
821
855
|
}
|
822
856
|
|
823
857
|
retval = rl_commit(c->context->db);
|
@@ -888,6 +922,18 @@ static void unwatchCommand(rliteClient *c) {
|
|
888
922
|
c->reply = createStatusObject(RLITE_STR_OK);
|
889
923
|
}
|
890
924
|
|
925
|
+
static rliteReply *pollToReply(long elementc, unsigned char **elements, long *elementslen) {
|
926
|
+
long i;
|
927
|
+
rliteReply *reply = createArrayObject(elementc);
|
928
|
+
for (i = 0; i < elementc; i++) {
|
929
|
+
reply->element[i] = createStringObject((char *)elements[i], elementslen[i]);
|
930
|
+
rl_free(elements[i]);
|
931
|
+
}
|
932
|
+
rl_free(elements);
|
933
|
+
rl_free(elementslen);
|
934
|
+
return reply;
|
935
|
+
}
|
936
|
+
|
891
937
|
static void *_popReply(rliteContext *c) {
|
892
938
|
if (c->replyPosition < c->replyLength) {
|
893
939
|
void *ret;
|
@@ -897,6 +943,18 @@ static void *_popReply(rliteContext *c) {
|
|
897
943
|
c->replyPosition = c->replyLength = 0;
|
898
944
|
}
|
899
945
|
return ret;
|
946
|
+
} else if (c->replyPosition == c->replyLength && c->db->subscriber_id) {
|
947
|
+
int elementc;
|
948
|
+
unsigned char **elements;
|
949
|
+
long *elementslen;
|
950
|
+
int retval = rl_poll_wait(c->db, &elementc, &elements, &elementslen, NULL);
|
951
|
+
if (retval == RL_NOT_FOUND) {
|
952
|
+
return createReplyObject(RLITE_REPLY_NIL);
|
953
|
+
} else if (retval == RL_OK) {
|
954
|
+
return pollToReply(elementc, elements, elementslen);
|
955
|
+
} else {
|
956
|
+
return createErrorObject("unknown retval");
|
957
|
+
}
|
900
958
|
} else {
|
901
959
|
return NULL;
|
902
960
|
}
|
@@ -931,6 +989,8 @@ int rliteAppendCommandClient(rliteClient *client) {
|
|
931
989
|
retval = addReplyErrorFormat(client->context, "wrong number of arguments for '%s' command", command->name);
|
932
990
|
flagTransactions(client);
|
933
991
|
} else {
|
992
|
+
RL_CALL(refresh_rlite_fp, RL_OK, client->context);
|
993
|
+
|
934
994
|
if (client->context->inTransaction && (command->proc != execCommand && command->proc != discardCommand &&
|
935
995
|
command->proc != multiCommand && command->proc != watchCommand)) {
|
936
996
|
if (client->context->enqueuedCommandsLength == client->context->enqueuedCommandsAlloc) {
|
@@ -984,7 +1044,7 @@ int rliteAppendCommandClient(rliteClient *client) {
|
|
984
1044
|
if (client->context->writeCommand) {
|
985
1045
|
RL_CALL(rl_dirty_hash, RL_OK, client->context->db, &newhash);
|
986
1046
|
if (newhash && (!oldhash || memcmp(newhash, oldhash, 20) != 0)) {
|
987
|
-
client->context->writeCommand(client->context->db
|
1047
|
+
client->context->writeCommand(rl_get_selected_db(client->context->db), client->argc, client->argv, client->argvlen);
|
988
1048
|
}
|
989
1049
|
}
|
990
1050
|
RL_CALL(rl_commit, RL_OK, client->context->db);
|
@@ -3819,6 +3879,185 @@ cleanup:
|
|
3819
3879
|
free(getvlen);
|
3820
3880
|
}
|
3821
3881
|
|
3882
|
+
static void pubsubVarargCommandProcessed(rliteClient *c, const char *type, int argc, unsigned char **args, long *argslen, int func(rlite *db, int argc, unsigned char **argv, long *argvlen)) {
|
3883
|
+
int i, retval;
|
3884
|
+
retval = func(c->context->db, argc, args, argslen);
|
3885
|
+
RLITE_SERVER_ERR(c, retval);
|
3886
|
+
|
3887
|
+
long count = 0;
|
3888
|
+
int subscribing = !strcasecmp(type, "subscribe") || !strcasecmp(type, "psubscribe");
|
3889
|
+
rl_pubsub_count_subscriptions(c->context->db, &count);
|
3890
|
+
for (i = 0; i < argc; i++) {
|
3891
|
+
rliteReply *reply = createArrayObject(3);;
|
3892
|
+
if (reply) {
|
3893
|
+
reply->element[0] = createCStringObject(type);
|
3894
|
+
reply->element[1] = createStringObject((char *)args[i], argslen[i]);
|
3895
|
+
// TODO: count might be off if a clients connects to the same channel multiple times
|
3896
|
+
reply->element[2] = createLongLongObject(subscribing ? (count - argc + i + 1) : (count + argc - i - 1));
|
3897
|
+
addReply(c->context, reply);
|
3898
|
+
}
|
3899
|
+
}
|
3900
|
+
retval = RL_OK;
|
3901
|
+
cleanup:
|
3902
|
+
return;
|
3903
|
+
}
|
3904
|
+
|
3905
|
+
static void pubsubVarargCommand(rliteClient *c, const char *type, int func(rlite *db, int argc, unsigned char **argv, long *argvlen)) {
|
3906
|
+
int i = 0, argc = c->argc - 1;
|
3907
|
+
unsigned char **args = NULL;
|
3908
|
+
long *argslen = NULL;
|
3909
|
+
|
3910
|
+
args = malloc(sizeof(unsigned char *) * argc);
|
3911
|
+
if (!args) {
|
3912
|
+
__rliteSetError(c->context, RLITE_ERR_OOM, "Out of memory");
|
3913
|
+
goto cleanup;
|
3914
|
+
}
|
3915
|
+
argslen = malloc(sizeof(long) * argc);
|
3916
|
+
if (!argslen) {
|
3917
|
+
__rliteSetError(c->context, RLITE_ERR_OOM, "Out of memory");
|
3918
|
+
goto cleanup;
|
3919
|
+
}
|
3920
|
+
for (i = 0; i < argc; i++) {
|
3921
|
+
args[i] = (unsigned char *)c->argv[1 + i];
|
3922
|
+
argslen[i] = (long)c->argvlen[1 + i];
|
3923
|
+
}
|
3924
|
+
pubsubVarargCommandProcessed(c, type, argc, args, argslen, func);
|
3925
|
+
cleanup:
|
3926
|
+
rl_free(args);
|
3927
|
+
rl_free(argslen);
|
3928
|
+
}
|
3929
|
+
|
3930
|
+
static void subscribeCommand(rliteClient *c) {
|
3931
|
+
pubsubVarargCommand(c, "subscribe", rl_subscribe);
|
3932
|
+
}
|
3933
|
+
|
3934
|
+
static void unsubscribeCommand(rliteClient *c) {
|
3935
|
+
long i, channelc = 0;
|
3936
|
+
unsigned char **channelv = NULL;
|
3937
|
+
long *channelvlen = NULL;
|
3938
|
+
if (c->argc == 1) {
|
3939
|
+
int retval = rl_pubsub_channels(c->context->db, NULL, 0, &channelc, &channelv, &channelvlen);
|
3940
|
+
RLITE_SERVER_ERR(c, retval);
|
3941
|
+
pubsubVarargCommandProcessed(c, "unsubscribe", channelc, channelv, channelvlen, rl_unsubscribe);
|
3942
|
+
} else {
|
3943
|
+
pubsubVarargCommand(c, "unsubscribe", rl_unsubscribe);
|
3944
|
+
}
|
3945
|
+
|
3946
|
+
cleanup:
|
3947
|
+
for (i = 0; i < channelc; i++) {
|
3948
|
+
rl_free(channelv[i]);
|
3949
|
+
}
|
3950
|
+
rl_free(channelv);
|
3951
|
+
rl_free(channelvlen);
|
3952
|
+
}
|
3953
|
+
|
3954
|
+
static void psubscribeCommand(rliteClient *c) {
|
3955
|
+
pubsubVarargCommand(c, "psubscribe", rl_psubscribe);
|
3956
|
+
}
|
3957
|
+
|
3958
|
+
static void punsubscribeCommand(rliteClient *c) {
|
3959
|
+
long i, patternc = 0;
|
3960
|
+
unsigned char **patternv = NULL;
|
3961
|
+
long *patternvlen = NULL;
|
3962
|
+
if (c->argc == 1) {
|
3963
|
+
int retval = rl_pubsub_patterns(c->context->db, &patternc, &patternv, &patternvlen);
|
3964
|
+
RLITE_SERVER_ERR(c, retval);
|
3965
|
+
pubsubVarargCommandProcessed(c, "punsubscribe", patternc, patternv, patternvlen, rl_punsubscribe);
|
3966
|
+
} else {
|
3967
|
+
pubsubVarargCommand(c, "punsubscribe", rl_punsubscribe);
|
3968
|
+
}
|
3969
|
+
|
3970
|
+
cleanup:
|
3971
|
+
for (i = 0; i < patternc; i++) {
|
3972
|
+
rl_free(patternv[i]);
|
3973
|
+
}
|
3974
|
+
rl_free(patternv);
|
3975
|
+
rl_free(patternvlen);
|
3976
|
+
}
|
3977
|
+
|
3978
|
+
static void publishCommand(rliteClient *c) {
|
3979
|
+
unsigned char *channel = (unsigned char *)c->argv[1];
|
3980
|
+
size_t channellen = c->argvlen[1];
|
3981
|
+
char *data = c->argv[2];
|
3982
|
+
size_t datalen = c->argvlen[2];
|
3983
|
+
long recipients = 0;
|
3984
|
+
int retval = rl_publish(c->context->db, channel, channellen, data, datalen, &recipients);
|
3985
|
+
RLITE_SERVER_ERR(c, retval);
|
3986
|
+
c->reply = createLongLongObject(recipients);
|
3987
|
+
cleanup:
|
3988
|
+
return;
|
3989
|
+
}
|
3990
|
+
|
3991
|
+
static void pubsubCommand(rliteClient *c) {
|
3992
|
+
long i, channelc = 0;
|
3993
|
+
unsigned char **channelv = NULL;
|
3994
|
+
long *channelvlen = NULL;
|
3995
|
+
int retval;
|
3996
|
+
if (!strcasecmp(c->argv[1],"channels")) {
|
3997
|
+
unsigned char *pattern = NULL;
|
3998
|
+
long patternlen = 0;
|
3999
|
+
if (c->argc >= 3) {
|
4000
|
+
pattern = (unsigned char *)c->argv[2];
|
4001
|
+
patternlen = c->argvlen[2];
|
4002
|
+
}
|
4003
|
+
retval = rl_pubsub_channels(c->context->db, pattern, patternlen, &channelc, &channelv, &channelvlen);
|
4004
|
+
RLITE_SERVER_ERR(c, retval);
|
4005
|
+
c->reply = createArrayObject(channelc);
|
4006
|
+
if (c->reply == NULL) {
|
4007
|
+
goto cleanup;
|
4008
|
+
}
|
4009
|
+
for (i = 0; i < channelc; i++) {
|
4010
|
+
c->reply->element[i] = createStringObject((char *)channelv[i], channelvlen[i]);
|
4011
|
+
}
|
4012
|
+
} else if (!strcasecmp(c->argv[1],"numsub")) {
|
4013
|
+
long numsub;
|
4014
|
+
retval = rl_pubsub_numsub(c->context->db, c->argc - 2, (unsigned char **)&c->argv[2], (long *)&c->argvlen[2], &numsub);
|
4015
|
+
c->reply = createLongLongObject(numsub);
|
4016
|
+
} else if (!strcasecmp(c->argv[1],"numpat")) {
|
4017
|
+
long numpat;
|
4018
|
+
retval = rl_pubsub_numpat(c->context->db, &numpat);
|
4019
|
+
c->reply = createLongLongObject(numpat);
|
4020
|
+
}
|
4021
|
+
cleanup:
|
4022
|
+
for (i = 0; i < channelc; i++) {
|
4023
|
+
rl_free(channelv[i]);
|
4024
|
+
}
|
4025
|
+
rl_free(channelv);
|
4026
|
+
rl_free(channelvlen);
|
4027
|
+
return;
|
4028
|
+
}
|
4029
|
+
|
4030
|
+
void pubsubPollCommand(rliteClient *c) {
|
4031
|
+
int retval;
|
4032
|
+
int elementc;
|
4033
|
+
unsigned char **elements;
|
4034
|
+
long *elementslen;
|
4035
|
+
if (c->argc >= 2) {
|
4036
|
+
long timeout_param;
|
4037
|
+
struct timeval timeout;
|
4038
|
+
if ((getLongFromObjectOrReply(c, c->argv[1], c->argvlen[1], &timeout_param, NULL) != RLITE_OK)) {
|
4039
|
+
return;
|
4040
|
+
}
|
4041
|
+
if (timeout_param != 0) {
|
4042
|
+
timeout.tv_sec = 0;
|
4043
|
+
timeout.tv_usec = timeout_param;
|
4044
|
+
}
|
4045
|
+
retval = rl_poll_wait(c->context->db, &elementc, &elements, &elementslen, timeout_param == 0 ? NULL : &timeout);
|
4046
|
+
} else {
|
4047
|
+
retval = rl_poll(c->context->db, &elementc, &elements, &elementslen);
|
4048
|
+
}
|
4049
|
+
RLITE_SERVER_ERR(c, retval);
|
4050
|
+
if (retval == RL_NOT_FOUND) {
|
4051
|
+
c->reply = createReplyObject(RLITE_REPLY_NIL);
|
4052
|
+
} else if (retval == RL_OK) {
|
4053
|
+
c->reply = pollToReply(elementc, elements, elementslen);
|
4054
|
+
} else {
|
4055
|
+
addReplyErrorFormat(c->context, "unknown retval %d", retval);
|
4056
|
+
}
|
4057
|
+
cleanup:
|
4058
|
+
return;
|
4059
|
+
}
|
4060
|
+
|
3822
4061
|
static struct rliteCommand rliteCommandTable[] = {
|
3823
4062
|
{"get",getCommand,2,"rF",0,1,1,1,0,0},
|
3824
4063
|
{"set",setCommand,-3,"wm",0,1,1,1,0,0},
|
@@ -3949,12 +4188,13 @@ static struct rliteCommand rliteCommandTable[] = {
|
|
3949
4188
|
// {"role",roleCommand,1,"last",0,NULL,0,0,0,0,0},
|
3950
4189
|
{"debug",debugCommand,-2,"as",0,0,0,0,0,0},
|
3951
4190
|
// {"config",configCommand,-2,"art",0,NULL,0,0,0,0,0},
|
3952
|
-
|
3953
|
-
|
3954
|
-
|
3955
|
-
|
3956
|
-
|
3957
|
-
|
4191
|
+
{"subscribe",subscribeCommand,-2,"rpslt",0,0,0,0,0,0},
|
4192
|
+
{"unsubscribe",unsubscribeCommand,-1,"rpslt",0,0,0,0,0,0},
|
4193
|
+
{"psubscribe",psubscribeCommand,-2,"rpslt",0,0,0,0,0,0},
|
4194
|
+
{"punsubscribe",punsubscribeCommand,-1,"rpslt",0,0,0,0,0,0},
|
4195
|
+
{"publish",publishCommand,3,"pltrF",0,0,0,0,0,0},
|
4196
|
+
{"pubsub",pubsubCommand,-2,"pltrR",0,0,0,0,0,0},
|
4197
|
+
{"__rlite_poll",pubsubPollCommand,-1,"pltrR",0,0,0,0,0,0},
|
3958
4198
|
{"watch",watchCommand,-2,"rsF",0,1,-1,1,0,0},
|
3959
4199
|
{"unwatch",unwatchCommand,1,"rsF",0,0,0,0,0,0},
|
3960
4200
|
// {"cluster",clusterCommand,-2,"ar",0,NULL,0,0,0,0,0},
|