hiredis 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/hiredis_ext/connection.c +7 -10
- data/ext/hiredis_ext/reader.c +3 -6
- data/lib/hiredis/connection.rb +5 -1
- data/lib/hiredis/em.rb +1 -0
- data/lib/hiredis/em/base.rb +36 -0
- data/lib/hiredis/em/connection.rb +25 -0
- data/lib/hiredis/version.rb +1 -1
- data/vendor/hiredis/Makefile +22 -18
- data/vendor/hiredis/async.c +305 -56
- data/vendor/hiredis/async.h +30 -11
- data/vendor/hiredis/dict.c +388 -0
- data/vendor/hiredis/dict.h +130 -0
- data/vendor/hiredis/hiredis.c +12 -4
- data/vendor/hiredis/hiredis.h +16 -2
- data/vendor/hiredis/net.c +17 -1
- data/vendor/hiredis/net.h +9 -0
- data/vendor/hiredis/test.c +10 -1
- metadata +10 -5
@@ -0,0 +1,130 @@
|
|
1
|
+
/* Hash Tables Implementation.
|
2
|
+
*
|
3
|
+
* This file implements in memory hash tables with insert/del/replace/find/
|
4
|
+
* get-random-element operations. Hash tables will auto resize if needed
|
5
|
+
* tables of power of two in size are used, collisions are handled by
|
6
|
+
* chaining. See the source code for more information... :)
|
7
|
+
*
|
8
|
+
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
9
|
+
* All rights reserved.
|
10
|
+
*
|
11
|
+
* Redistribution and use in source and binary forms, with or without
|
12
|
+
* modification, are permitted provided that the following conditions are met:
|
13
|
+
*
|
14
|
+
* * Redistributions of source code must retain the above copyright notice,
|
15
|
+
* this list of conditions and the following disclaimer.
|
16
|
+
* * Redistributions in binary form must reproduce the above copyright
|
17
|
+
* notice, this list of conditions and the following disclaimer in the
|
18
|
+
* documentation and/or other materials provided with the distribution.
|
19
|
+
* * Neither the name of Redis nor the names of its contributors may be used
|
20
|
+
* to endorse or promote products derived from this software without
|
21
|
+
* specific prior written permission.
|
22
|
+
*
|
23
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
24
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
25
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
26
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
27
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
28
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
29
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
30
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
31
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
32
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
*/
|
35
|
+
|
36
|
+
#ifndef __DICT_H
|
37
|
+
#define __DICT_H
|
38
|
+
|
39
|
+
#define DICT_OK 0
|
40
|
+
#define DICT_ERR 1
|
41
|
+
|
42
|
+
/* Unused arguments generate annoying warnings... */
|
43
|
+
#define DICT_NOTUSED(V) ((void) V)
|
44
|
+
|
45
|
+
typedef struct dictEntry {
|
46
|
+
void *key;
|
47
|
+
void *val;
|
48
|
+
struct dictEntry *next;
|
49
|
+
} dictEntry;
|
50
|
+
|
51
|
+
typedef struct dictType {
|
52
|
+
unsigned int (*hashFunction)(const void *key);
|
53
|
+
void *(*keyDup)(void *privdata, const void *key);
|
54
|
+
void *(*valDup)(void *privdata, const void *obj);
|
55
|
+
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
|
56
|
+
void (*keyDestructor)(void *privdata, void *key);
|
57
|
+
void (*valDestructor)(void *privdata, void *obj);
|
58
|
+
} dictType;
|
59
|
+
|
60
|
+
typedef struct dict {
|
61
|
+
dictEntry **table;
|
62
|
+
dictType *type;
|
63
|
+
unsigned long size;
|
64
|
+
unsigned long sizemask;
|
65
|
+
unsigned long used;
|
66
|
+
void *privdata;
|
67
|
+
} dict;
|
68
|
+
|
69
|
+
typedef struct dictIterator {
|
70
|
+
dict *ht;
|
71
|
+
int index;
|
72
|
+
dictEntry *entry, *nextEntry;
|
73
|
+
} dictIterator;
|
74
|
+
|
75
|
+
/* This is the initial size of every hash table */
|
76
|
+
#define DICT_HT_INITIAL_SIZE 4
|
77
|
+
|
78
|
+
/* ------------------------------- Macros ------------------------------------*/
|
79
|
+
#define dictFreeEntryVal(ht, entry) \
|
80
|
+
if ((ht)->type->valDestructor) \
|
81
|
+
(ht)->type->valDestructor((ht)->privdata, (entry)->val)
|
82
|
+
|
83
|
+
#define dictSetHashVal(ht, entry, _val_) do { \
|
84
|
+
if ((ht)->type->valDup) \
|
85
|
+
entry->val = (ht)->type->valDup((ht)->privdata, _val_); \
|
86
|
+
else \
|
87
|
+
entry->val = (_val_); \
|
88
|
+
} while(0)
|
89
|
+
|
90
|
+
#define dictFreeEntryKey(ht, entry) \
|
91
|
+
if ((ht)->type->keyDestructor) \
|
92
|
+
(ht)->type->keyDestructor((ht)->privdata, (entry)->key)
|
93
|
+
|
94
|
+
#define dictSetHashKey(ht, entry, _key_) do { \
|
95
|
+
if ((ht)->type->keyDup) \
|
96
|
+
entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \
|
97
|
+
else \
|
98
|
+
entry->key = (_key_); \
|
99
|
+
} while(0)
|
100
|
+
|
101
|
+
#define dictCompareHashKeys(ht, key1, key2) \
|
102
|
+
(((ht)->type->keyCompare) ? \
|
103
|
+
(ht)->type->keyCompare((ht)->privdata, key1, key2) : \
|
104
|
+
(key1) == (key2))
|
105
|
+
|
106
|
+
#define dictHashKey(ht, key) (ht)->type->hashFunction(key)
|
107
|
+
|
108
|
+
#define dictGetEntryKey(he) ((he)->key)
|
109
|
+
#define dictGetEntryVal(he) ((he)->val)
|
110
|
+
#define dictSlots(ht) ((ht)->size)
|
111
|
+
#define dictSize(ht) ((ht)->used)
|
112
|
+
|
113
|
+
/* API */
|
114
|
+
dict *dictCreate(dictType *type, void *privDataPtr);
|
115
|
+
int dictExpand(dict *ht, unsigned long size);
|
116
|
+
int dictAdd(dict *ht, void *key, void *val);
|
117
|
+
int dictReplace(dict *ht, void *key, void *val);
|
118
|
+
int dictDelete(dict *ht, const void *key);
|
119
|
+
int dictDeleteNoFree(dict *ht, const void *key);
|
120
|
+
void dictRelease(dict *ht);
|
121
|
+
dictEntry * dictFind(dict *ht, const void *key);
|
122
|
+
int dictResize(dict *ht);
|
123
|
+
dictIterator *dictGetIterator(dict *ht);
|
124
|
+
dictEntry *dictNext(dictIterator *iter);
|
125
|
+
void dictReleaseIterator(dictIterator *iter);
|
126
|
+
dictEntry *dictGetRandomKey(dict *ht);
|
127
|
+
unsigned int dictGenHashFunction(const unsigned char *buf, int len);
|
128
|
+
void dictEmpty(dict *ht);
|
129
|
+
|
130
|
+
#endif /* __DICT_H */
|
data/vendor/hiredis/hiredis.c
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
3
|
+
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
4
|
+
*
|
3
5
|
* All rights reserved.
|
4
6
|
*
|
5
7
|
* Redistribution and use in source and binary forms, with or without
|
@@ -807,8 +809,7 @@ static redisContext *redisContextInit() {
|
|
807
809
|
}
|
808
810
|
|
809
811
|
void redisFree(redisContext *c) {
|
810
|
-
|
811
|
-
if (c->flags & REDIS_CONNECTED)
|
812
|
+
if (c->fd > 0)
|
812
813
|
close(c->fd);
|
813
814
|
if (c->errstr != NULL)
|
814
815
|
sdsfree(c->errstr);
|
@@ -850,6 +851,13 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
|
|
850
851
|
return c;
|
851
852
|
}
|
852
853
|
|
854
|
+
/* Set read/write timeout on a blocking socket. */
|
855
|
+
int redisSetTimeout(redisContext *c, struct timeval tv) {
|
856
|
+
if (c->flags & REDIS_BLOCK)
|
857
|
+
return redisContextSetTimeout(c,tv);
|
858
|
+
return REDIS_ERR;
|
859
|
+
}
|
860
|
+
|
853
861
|
/* Set the replyObjectFunctions to use. Returns REDIS_ERR when the reader
|
854
862
|
* was already initialized and the function set could not be re-set.
|
855
863
|
* Return REDIS_OK when they could be set. */
|
@@ -877,7 +885,7 @@ int redisBufferRead(redisContext *c) {
|
|
877
885
|
char buf[2048];
|
878
886
|
int nread = read(c->fd,buf,sizeof(buf));
|
879
887
|
if (nread == -1) {
|
880
|
-
if (errno == EAGAIN) {
|
888
|
+
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
|
881
889
|
/* Try again later */
|
882
890
|
} else {
|
883
891
|
__redisSetError(c,REDIS_ERR_IO,NULL);
|
@@ -908,7 +916,7 @@ int redisBufferWrite(redisContext *c, int *done) {
|
|
908
916
|
if (sdslen(c->obuf) > 0) {
|
909
917
|
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
|
910
918
|
if (nwritten == -1) {
|
911
|
-
if (errno == EAGAIN) {
|
919
|
+
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
|
912
920
|
/* Try again later */
|
913
921
|
} else {
|
914
922
|
__redisSetError(c,REDIS_ERR_IO,NULL);
|
data/vendor/hiredis/hiredis.h
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
3
|
+
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
4
|
+
*
|
3
5
|
* All rights reserved.
|
4
6
|
*
|
5
7
|
* Redistribution and use in source and binary forms, with or without
|
@@ -31,10 +33,11 @@
|
|
31
33
|
#define __HIREDIS_H
|
32
34
|
#include <stdio.h> /* for size_t */
|
33
35
|
#include <stdarg.h> /* for va_list */
|
36
|
+
#include <sys/time.h> /* for struct timeval */
|
34
37
|
|
35
38
|
#define HIREDIS_MAJOR 0
|
36
39
|
#define HIREDIS_MINOR 9
|
37
|
-
#define HIREDIS_PATCH
|
40
|
+
#define HIREDIS_PATCH 2
|
38
41
|
|
39
42
|
#define REDIS_ERR -1
|
40
43
|
#define REDIS_OK 0
|
@@ -62,12 +65,22 @@
|
|
62
65
|
* should be terminated once all replies have been read. */
|
63
66
|
#define REDIS_DISCONNECTING 0x4
|
64
67
|
|
65
|
-
|
68
|
+
/* Flag specific to the async API which means that the context should be clean
|
69
|
+
* up as soon as possible. */
|
70
|
+
#define REDIS_FREEING 0x8
|
71
|
+
|
72
|
+
/* Flag that is set when an async callback is executed. */
|
73
|
+
#define REDIS_IN_CALLBACK 0x10
|
74
|
+
|
75
|
+
/* Flag that is set when the async context has one or more subscriptions. */
|
76
|
+
#define REDIS_SUBSCRIBED 0x20
|
77
|
+
|
66
78
|
#define REDIS_REPLY_STRING 1
|
67
79
|
#define REDIS_REPLY_ARRAY 2
|
68
80
|
#define REDIS_REPLY_INTEGER 3
|
69
81
|
#define REDIS_REPLY_NIL 4
|
70
82
|
#define REDIS_REPLY_STATUS 5
|
83
|
+
#define REDIS_REPLY_ERROR 6
|
71
84
|
|
72
85
|
#ifdef __cplusplus
|
73
86
|
extern "C" {
|
@@ -134,6 +147,7 @@ redisContext *redisConnect(const char *ip, int port);
|
|
134
147
|
redisContext *redisConnectNonBlock(const char *ip, int port);
|
135
148
|
redisContext *redisConnectUnix(const char *path);
|
136
149
|
redisContext *redisConnectUnixNonBlock(const char *path);
|
150
|
+
int redisSetTimeout(redisContext *c, struct timeval tv);
|
137
151
|
int redisSetReplyObjectFunctions(redisContext *c, redisReplyObjectFunctions *fn);
|
138
152
|
void redisFree(redisContext *c);
|
139
153
|
int redisBufferRead(redisContext *c);
|
data/vendor/hiredis/net.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
/* Extracted from anet.c to work properly with Hiredis error reporting.
|
2
2
|
*
|
3
3
|
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
4
|
+
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
5
|
+
*
|
4
6
|
* All rights reserved.
|
5
7
|
*
|
6
8
|
* Redistribution and use in source and binary forms, with or without
|
@@ -43,7 +45,7 @@
|
|
43
45
|
#include <stdarg.h>
|
44
46
|
#include <stdio.h>
|
45
47
|
|
46
|
-
#include "
|
48
|
+
#include "net.h"
|
47
49
|
#include "sds.h"
|
48
50
|
|
49
51
|
/* Forward declaration */
|
@@ -96,6 +98,20 @@ static int redisSetTcpNoDelay(redisContext *c, int fd) {
|
|
96
98
|
return REDIS_OK;
|
97
99
|
}
|
98
100
|
|
101
|
+
int redisContextSetTimeout(redisContext *c, struct timeval tv) {
|
102
|
+
if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
|
103
|
+
__redisSetError(c,REDIS_ERR_IO,
|
104
|
+
sdscatprintf(sdsempty(), "setsockopt(SO_RCVTIMEO): %s", strerror(errno)));
|
105
|
+
return REDIS_ERR;
|
106
|
+
}
|
107
|
+
if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
|
108
|
+
__redisSetError(c,REDIS_ERR_IO,
|
109
|
+
sdscatprintf(sdsempty(), "setsockopt(SO_SNDTIMEO): %s", strerror(errno)));
|
110
|
+
return REDIS_ERR;
|
111
|
+
}
|
112
|
+
return REDIS_OK;
|
113
|
+
}
|
114
|
+
|
99
115
|
int redisContextConnectTcp(redisContext *c, const char *addr, int port) {
|
100
116
|
int s;
|
101
117
|
int blocking = (c->flags & REDIS_BLOCK);
|
data/vendor/hiredis/net.h
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
/* Extracted from anet.c to work properly with Hiredis error reporting.
|
2
2
|
*
|
3
3
|
* Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
4
|
+
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
5
|
+
*
|
4
6
|
* All rights reserved.
|
5
7
|
*
|
6
8
|
* Redistribution and use in source and binary forms, with or without
|
@@ -31,6 +33,13 @@
|
|
31
33
|
#ifndef __NET_H
|
32
34
|
#define __NET_H
|
33
35
|
|
36
|
+
#include "hiredis.h"
|
37
|
+
|
38
|
+
#if defined(__sun)
|
39
|
+
#define AF_LOCAL AF_UNIX
|
40
|
+
#endif
|
41
|
+
|
42
|
+
int redisContextSetTimeout(redisContext *c, struct timeval tv);
|
34
43
|
int redisContextConnectTcp(redisContext *c, const char *addr, int port);
|
35
44
|
int redisContextConnectUnix(redisContext *c, const char *path);
|
36
45
|
|
data/vendor/hiredis/test.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#include <assert.h>
|
7
7
|
#include <unistd.h>
|
8
8
|
#include <signal.h>
|
9
|
+
#include <errno.h>
|
9
10
|
|
10
11
|
#include "hiredis.h"
|
11
12
|
|
@@ -246,9 +247,17 @@ static void test_blocking_connection() {
|
|
246
247
|
* conditions, the error will be set to EOF. */
|
247
248
|
assert(c->err == REDIS_ERR_EOF &&
|
248
249
|
strcmp(c->errstr,"Server closed the connection") == 0);
|
250
|
+
redisFree(c);
|
249
251
|
|
250
|
-
|
252
|
+
__connect(&c);
|
253
|
+
test("Returns I/O error on socket timeout: ");
|
254
|
+
struct timeval tv = { 0, 1000 };
|
255
|
+
assert(redisSetTimeout(c,tv) == REDIS_OK);
|
256
|
+
test_cond(redisGetReply(c,(void**)&reply) == REDIS_ERR &&
|
257
|
+
c->err == REDIS_ERR_IO && errno == EAGAIN);
|
251
258
|
redisFree(c);
|
259
|
+
|
260
|
+
/* Context should be connected */
|
252
261
|
__connect(&c);
|
253
262
|
}
|
254
263
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pieter Noordhuis
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-07 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -67,15 +67,20 @@ files:
|
|
67
67
|
- ext/hiredis_ext/reader.c
|
68
68
|
- ext/hiredis_ext/hiredis_ext.h
|
69
69
|
- lib/hiredis/connection.rb
|
70
|
+
- lib/hiredis/em/base.rb
|
71
|
+
- lib/hiredis/em/connection.rb
|
72
|
+
- lib/hiredis/em.rb
|
70
73
|
- lib/hiredis/reader.rb
|
71
74
|
- lib/hiredis/version.rb
|
72
75
|
- lib/hiredis.rb
|
73
76
|
- vendor/hiredis/async.c
|
77
|
+
- vendor/hiredis/dict.c
|
74
78
|
- vendor/hiredis/hiredis.c
|
75
79
|
- vendor/hiredis/net.c
|
76
80
|
- vendor/hiredis/sds.c
|
77
81
|
- vendor/hiredis/test.c
|
78
82
|
- vendor/hiredis/async.h
|
83
|
+
- vendor/hiredis/dict.h
|
79
84
|
- vendor/hiredis/fmacros.h
|
80
85
|
- vendor/hiredis/hiredis.h
|
81
86
|
- vendor/hiredis/net.h
|