Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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