Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
1b1f47c9
Commit
1b1f47c9
authored
Nov 03, 2010
by
antirez
Browse files
command lookup process turned into a much more flexible and probably faster hash table
parent
297e77c6
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/db.c
View file @
1b1f47c9
...
@@ -435,16 +435,14 @@ time_t getExpire(redisDb *db, robj *key) {
...
@@ -435,16 +435,14 @@ time_t getExpire(redisDb *db, robj *key) {
* will be consistent even if we allow write operations against expiring
* will be consistent even if we allow write operations against expiring
* keys. */
* keys. */
void
propagateExpire
(
redisDb
*
db
,
robj
*
key
)
{
void
propagateExpire
(
redisDb
*
db
,
robj
*
key
)
{
struct
redisCommand
*
cmd
;
robj
*
argv
[
2
];
robj
*
argv
[
2
];
cmd
=
lookupCommand
(
"del"
);
argv
[
0
]
=
createStringObject
(
"DEL"
,
3
);
argv
[
0
]
=
createStringObject
(
"DEL"
,
3
);
argv
[
1
]
=
key
;
argv
[
1
]
=
key
;
incrRefCount
(
key
);
incrRefCount
(
key
);
if
(
server
.
appendonly
)
if
(
server
.
appendonly
)
feedAppendOnlyFile
(
cm
d
,
db
->
id
,
argv
,
2
);
feedAppendOnlyFile
(
server
.
delComman
d
,
db
->
id
,
argv
,
2
);
if
(
listLength
(
server
.
slaves
))
if
(
listLength
(
server
.
slaves
))
replicationFeedSlaves
(
server
.
slaves
,
db
->
id
,
argv
,
2
);
replicationFeedSlaves
(
server
.
slaves
,
db
->
id
,
argv
,
2
);
...
...
src/dict.c
View file @
1b1f47c9
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
#include <assert.h>
#include <assert.h>
#include <limits.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/time.h>
#include <ctype.h>
#include "dict.h"
#include "dict.h"
#include "zmalloc.h"
#include "zmalloc.h"
...
@@ -94,6 +95,15 @@ unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
...
@@ -94,6 +95,15 @@ unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
return
hash
;
return
hash
;
}
}
/* And a case insensitive version */
unsigned
int
dictGenCaseHashFunction
(
const
unsigned
char
*
buf
,
int
len
)
{
unsigned
int
hash
=
5381
;
while
(
len
--
)
hash
=
((
hash
<<
5
)
+
hash
)
+
(
tolower
(
*
buf
++
));
/* hash * 33 + c */
return
hash
;
}
/* ----------------------------- API implementation ------------------------- */
/* ----------------------------- API implementation ------------------------- */
/* Reset an hashtable already initialized with ht_init().
/* Reset an hashtable already initialized with ht_init().
...
...
src/dict.h
View file @
1b1f47c9
...
@@ -137,6 +137,7 @@ void dictReleaseIterator(dictIterator *iter);
...
@@ -137,6 +137,7 @@ void dictReleaseIterator(dictIterator *iter);
dictEntry
*
dictGetRandomKey
(
dict
*
d
);
dictEntry
*
dictGetRandomKey
(
dict
*
d
);
void
dictPrintStats
(
dict
*
d
);
void
dictPrintStats
(
dict
*
d
);
unsigned
int
dictGenHashFunction
(
const
unsigned
char
*
buf
,
int
len
);
unsigned
int
dictGenHashFunction
(
const
unsigned
char
*
buf
,
int
len
);
unsigned
int
dictGenCaseHashFunction
(
const
unsigned
char
*
buf
,
int
len
);
void
dictEmpty
(
dict
*
d
);
void
dictEmpty
(
dict
*
d
);
void
dictEnableResize
(
void
);
void
dictEnableResize
(
void
);
void
dictDisableResize
(
void
);
void
dictDisableResize
(
void
);
...
...
src/multi.c
View file @
1b1f47c9
...
@@ -65,12 +65,10 @@ void discardCommand(redisClient *c) {
...
@@ -65,12 +65,10 @@ void discardCommand(redisClient *c) {
/* Send a MULTI command to all the slaves and AOF file. Check the execCommand
/* Send a MULTI command to all the slaves and AOF file. Check the execCommand
* implememntation for more information. */
* implememntation for more information. */
void
execCommandReplicateMulti
(
redisClient
*
c
)
{
void
execCommandReplicateMulti
(
redisClient
*
c
)
{
struct
redisCommand
*
cmd
;
robj
*
multistring
=
createStringObject
(
"MULTI"
,
5
);
robj
*
multistring
=
createStringObject
(
"MULTI"
,
5
);
cmd
=
lookupCommand
(
"multi"
);
if
(
server
.
appendonly
)
if
(
server
.
appendonly
)
feedAppendOnlyFile
(
cm
d
,
c
->
db
->
id
,
&
multistring
,
1
);
feedAppendOnlyFile
(
server
.
multiComman
d
,
c
->
db
->
id
,
&
multistring
,
1
);
if
(
listLength
(
server
.
slaves
))
if
(
listLength
(
server
.
slaves
))
replicationFeedSlaves
(
server
.
slaves
,
c
->
db
->
id
,
&
multistring
,
1
);
replicationFeedSlaves
(
server
.
slaves
,
c
->
db
->
id
,
&
multistring
,
1
);
decrRefCount
(
multistring
);
decrRefCount
(
multistring
);
...
...
src/redis.c
View file @
1b1f47c9
...
@@ -252,6 +252,15 @@ int dictSdsKeyCompare(void *privdata, const void *key1,
...
@@ -252,6 +252,15 @@ int dictSdsKeyCompare(void *privdata, const void *key1,
return
memcmp
(
key1
,
key2
,
l1
)
==
0
;
return
memcmp
(
key1
,
key2
,
l1
)
==
0
;
}
}
/* A case insensitive version used for the command lookup table. */
int
dictSdsKeyCaseCompare
(
void
*
privdata
,
const
void
*
key1
,
const
void
*
key2
)
{
DICT_NOTUSED
(
privdata
);
return
strcasecmp
(
key1
,
key2
)
==
0
;
}
void
dictRedisObjectDestructor
(
void
*
privdata
,
void
*
val
)
void
dictRedisObjectDestructor
(
void
*
privdata
,
void
*
val
)
{
{
DICT_NOTUSED
(
privdata
);
DICT_NOTUSED
(
privdata
);
...
@@ -283,6 +292,10 @@ unsigned int dictSdsHash(const void *key) {
...
@@ -283,6 +292,10 @@ unsigned int dictSdsHash(const void *key) {
return
dictGenHashFunction
((
unsigned
char
*
)
key
,
sdslen
((
char
*
)
key
));
return
dictGenHashFunction
((
unsigned
char
*
)
key
,
sdslen
((
char
*
)
key
));
}
}
unsigned
int
dictSdsCaseHash
(
const
void
*
key
)
{
return
dictGenCaseHashFunction
((
unsigned
char
*
)
key
,
sdslen
((
char
*
)
key
));
}
int
dictEncObjKeyCompare
(
void
*
privdata
,
const
void
*
key1
,
int
dictEncObjKeyCompare
(
void
*
privdata
,
const
void
*
key1
,
const
void
*
key2
)
const
void
*
key2
)
{
{
...
@@ -364,6 +377,16 @@ dictType keyptrDictType = {
...
@@ -364,6 +377,16 @@ dictType keyptrDictType = {
NULL
/* val destructor */
NULL
/* val destructor */
};
};
/* Command table. sds string -> command struct pointer. */
dictType
commandTableDictType
=
{
dictSdsCaseHash
,
/* hash function */
NULL
,
/* key dup */
NULL
,
/* val dup */
dictSdsKeyCaseCompare
,
/* key compare */
dictSdsDestructor
,
/* key destructor */
NULL
/* val destructor */
};
/* Hash type hash table (note that small hashes are represented with zimpaps) */
/* Hash type hash table (note that small hashes are represented with zimpaps) */
dictType
hashDictType
=
{
dictType
hashDictType
=
{
dictEncObjHash
,
/* hash function */
dictEncObjHash
,
/* hash function */
...
@@ -791,6 +814,12 @@ void initServer() {
...
@@ -791,6 +814,12 @@ void initServer() {
redisLog
(
REDIS_WARNING
,
"Can't open /dev/null: %s"
,
server
.
neterr
);
redisLog
(
REDIS_WARNING
,
"Can't open /dev/null: %s"
,
server
.
neterr
);
exit
(
1
);
exit
(
1
);
}
}
server
.
commands
=
dictCreate
(
&
commandTableDictType
,
NULL
);
populateCommandTable
();
server
.
delCommand
=
lookupCommandByCString
(
"del"
);
server
.
multiCommand
=
lookupCommandByCString
(
"multi"
);
server
.
clients
=
listCreate
();
server
.
clients
=
listCreate
();
server
.
slaves
=
listCreate
();
server
.
slaves
=
listCreate
();
server
.
monitors
=
listCreate
();
server
.
monitors
=
listCreate
();
...
@@ -860,31 +889,34 @@ void initServer() {
...
@@ -860,31 +889,34 @@ void initServer() {
if
(
server
.
vm_enabled
)
vmInit
();
if
(
server
.
vm_enabled
)
vmInit
();
}
}
int
qsortRedisCommands
(
const
void
*
r1
,
const
void
*
r2
)
{
/* Populates the Redis Command Table starting from the hard coded list
return
strcasecmp
(
* we have on top of redis.c file. */
((
struct
redisCommand
*
)
r1
)
->
name
,
void
populateCommandTable
(
void
)
{
((
struct
redisCommand
*
)
r2
)
->
name
);
int
j
;
}
int
numcommands
=
sizeof
(
readonlyCommandTable
)
/
sizeof
(
struct
redisCommand
);
for
(
j
=
0
;
j
<
numcommands
;
j
++
)
{
struct
redisCommand
*
c
=
readonlyCommandTable
+
j
;
int
retval
;
void
sortCommandTable
()
{
retval
=
dictAdd
(
server
.
commands
,
sdsnew
(
c
->
name
),
c
);
/* Copy and sort the read-only version of the command table */
assert
(
retval
==
DICT_OK
);
commandTable
=
(
struct
redisCommand
*
)
zmalloc
(
sizeof
(
readonlyCommandTable
));
}
memcpy
(
commandTable
,
readonlyCommandTable
,
sizeof
(
readonlyCommandTable
));
qsort
(
commandTable
,
sizeof
(
readonlyCommandTable
)
/
sizeof
(
struct
redisCommand
),
sizeof
(
struct
redisCommand
),
qsortRedisCommands
);
}
}
/* ====================== Commands lookup and execution ===================== */
/* ====================== Commands lookup and execution ===================== */
struct
redisCommand
*
lookupCommand
(
char
*
name
)
{
struct
redisCommand
*
lookupCommand
(
sds
name
)
{
struct
redisCommand
tmp
=
{
name
,
NULL
,
0
,
0
,
NULL
,
0
,
0
,
0
};
return
dictFetchValue
(
server
.
commands
,
name
);
return
bsearch
(
}
&
tmp
,
commandTable
,
struct
redisCommand
*
lookupCommandByCString
(
char
*
s
)
{
sizeof
(
readonlyCommandTable
)
/
sizeof
(
struct
redisCommand
),
struct
redisCommand
*
cmd
;
sizeof
(
struct
redisCommand
),
sds
name
=
sdsnew
(
s
);
qsortRedisCommands
);
cmd
=
dictFetchValue
(
server
.
commands
,
name
);
sdsfree
(
name
);
return
cmd
;
}
}
/* Call() is the core of Redis execution of a command */
/* Call() is the core of Redis execution of a command */
...
@@ -1443,7 +1475,6 @@ int main(int argc, char **argv) {
...
@@ -1443,7 +1475,6 @@ int main(int argc, char **argv) {
time_t
start
;
time_t
start
;
initServerConfig
();
initServerConfig
();
sortCommandTable
();
if
(
argc
==
2
)
{
if
(
argc
==
2
)
{
if
(
strcmp
(
argv
[
1
],
"-v"
)
==
0
||
if
(
strcmp
(
argv
[
1
],
"-v"
)
==
0
||
strcmp
(
argv
[
1
],
"--version"
)
==
0
)
version
();
strcmp
(
argv
[
1
],
"--version"
)
==
0
)
version
();
...
...
src/redis.h
View file @
1b1f47c9
...
@@ -360,6 +360,8 @@ struct redisServer {
...
@@ -360,6 +360,8 @@ struct redisServer {
long
long
dirty
;
/* changes to DB from the last save */
long
long
dirty
;
/* changes to DB from the last save */
long
long
dirty_before_bgsave
;
/* used to restore dirty on failed BGSAVE */
long
long
dirty_before_bgsave
;
/* used to restore dirty on failed BGSAVE */
list
*
clients
;
list
*
clients
;
dict
*
commands
;
/* Command table hahs table */
struct
redisCommand
*
delCommand
,
*
multiCommand
;
/* often lookedup cmds */
list
*
slaves
,
*
monitors
;
list
*
slaves
,
*
monitors
;
char
neterr
[
ANET_ERR_LEN
];
char
neterr
[
ANET_ERR_LEN
];
aeEventLoop
*
el
;
aeEventLoop
*
el
;
...
@@ -746,7 +748,8 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
...
@@ -746,7 +748,8 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
void
freeMemoryIfNeeded
(
void
);
void
freeMemoryIfNeeded
(
void
);
int
processCommand
(
redisClient
*
c
);
int
processCommand
(
redisClient
*
c
);
void
setupSigSegvAction
(
void
);
void
setupSigSegvAction
(
void
);
struct
redisCommand
*
lookupCommand
(
char
*
name
);
struct
redisCommand
*
lookupCommand
(
sds
name
);
struct
redisCommand
*
lookupCommandByCString
(
char
*
s
);
void
call
(
redisClient
*
c
,
struct
redisCommand
*
cmd
);
void
call
(
redisClient
*
c
,
struct
redisCommand
*
cmd
);
int
prepareForShutdown
();
int
prepareForShutdown
();
void
redisLog
(
int
level
,
const
char
*
fmt
,
...);
void
redisLog
(
int
level
,
const
char
*
fmt
,
...);
...
@@ -754,6 +757,7 @@ void usage();
...
@@ -754,6 +757,7 @@ void usage();
void
updateDictResizePolicy
(
void
);
void
updateDictResizePolicy
(
void
);
int
htNeedsResize
(
dict
*
dict
);
int
htNeedsResize
(
dict
*
dict
);
void
oom
(
const
char
*
msg
);
void
oom
(
const
char
*
msg
);
void
populateCommandTable
(
void
);
/* Virtual Memory */
/* Virtual Memory */
void
vmInit
(
void
);
void
vmInit
(
void
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment