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
d0686e07
Commit
d0686e07
authored
Jun 04, 2010
by
Pieter Noordhuis
Browse files
add thresholds for converting a ziplist to a real list
parent
846d8b3e
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
d0686e07
...
@@ -237,9 +237,11 @@ static char* strencoding[] = {
...
@@ -237,9 +237,11 @@ static char* strencoding[] = {
#define APPENDFSYNC_ALWAYS 1
#define APPENDFSYNC_ALWAYS 1
#define APPENDFSYNC_EVERYSEC 2
#define APPENDFSYNC_EVERYSEC 2
/*
Hashes
related defaults */
/*
Zip structure
related defaults */
#define REDIS_HASH_MAX_ZIPMAP_ENTRIES 64
#define REDIS_HASH_MAX_ZIPMAP_ENTRIES 64
#define REDIS_HASH_MAX_ZIPMAP_VALUE 512
#define REDIS_HASH_MAX_ZIPMAP_VALUE 512
#define REDIS_LIST_MAX_ZIPLIST_ENTRIES 1024
#define REDIS_LIST_MAX_ZIPLIST_VALUE 32
/* We can print the stacktrace, so our assert is defined this way: */
/* We can print the stacktrace, so our assert is defined this way: */
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
...
@@ -425,9 +427,11 @@ struct redisServer {
...
@@ -425,9 +427,11 @@ struct redisServer {
off_t vm_page_size;
off_t vm_page_size;
off_t vm_pages;
off_t vm_pages;
unsigned long long vm_max_memory;
unsigned long long vm_max_memory;
/*
Hashes
config */
/*
Zip structure
config */
size_t hash_max_zipmap_entries;
size_t hash_max_zipmap_entries;
size_t hash_max_zipmap_value;
size_t hash_max_zipmap_value;
size_t list_max_ziplist_entries;
size_t list_max_ziplist_value;
/* Virtual memory state */
/* Virtual memory state */
FILE *vm_fp;
FILE *vm_fp;
int vm_fd;
int vm_fd;
...
@@ -646,6 +650,7 @@ static struct redisCommand *lookupCommand(char *name);
...
@@ -646,6 +650,7 @@ static struct redisCommand *lookupCommand(char *name);
static void call(redisClient *c, struct redisCommand *cmd);
static void call(redisClient *c, struct redisCommand *cmd);
static void resetClient(redisClient *c);
static void resetClient(redisClient *c);
static void convertToRealHash(robj *o);
static void convertToRealHash(robj *o);
static void convertList(robj *o, int enc);
static int pubsubUnsubscribeAllChannels(redisClient *c, int notify);
static int pubsubUnsubscribeAllChannels(redisClient *c, int notify);
static int pubsubUnsubscribeAllPatterns(redisClient *c, int notify);
static int pubsubUnsubscribeAllPatterns(redisClient *c, int notify);
static void freePubsubPattern(void *p);
static void freePubsubPattern(void *p);
...
@@ -1755,6 +1760,8 @@ static void initServerConfig() {
...
@@ -1755,6 +1760,8 @@ static void initServerConfig() {
server.vm_blocked_clients = 0;
server.vm_blocked_clients = 0;
server.hash_max_zipmap_entries = REDIS_HASH_MAX_ZIPMAP_ENTRIES;
server.hash_max_zipmap_entries = REDIS_HASH_MAX_ZIPMAP_ENTRIES;
server.hash_max_zipmap_value = REDIS_HASH_MAX_ZIPMAP_VALUE;
server.hash_max_zipmap_value = REDIS_HASH_MAX_ZIPMAP_VALUE;
server.list_max_ziplist_entries = REDIS_LIST_MAX_ZIPLIST_ENTRIES;
server.list_max_ziplist_value = REDIS_LIST_MAX_ZIPLIST_VALUE;
server.shutdown_asap = 0;
server.shutdown_asap = 0;
resetServerSaveParams();
resetServerSaveParams();
...
@@ -2033,6 +2040,10 @@ static void loadServerConfig(char *filename) {
...
@@ -2033,6 +2040,10 @@ static void loadServerConfig(char *filename) {
server.hash_max_zipmap_entries = memtoll(argv[1], NULL);
server.hash_max_zipmap_entries = memtoll(argv[1], NULL);
} else if (!strcasecmp(argv[0],"hash-max-zipmap-value") && argc == 2){
} else if (!strcasecmp(argv[0],"hash-max-zipmap-value") && argc == 2){
server.hash_max_zipmap_value = memtoll(argv[1], NULL);
server.hash_max_zipmap_value = memtoll(argv[1], NULL);
} else if (!strcasecmp(argv[0],"list-max-ziplist-entries") && argc == 2){
server.list_max_ziplist_entries = memtoll(argv[1], NULL);
} else if (!strcasecmp(argv[0],"list-max-ziplist-value") && argc == 2){
server.list_max_ziplist_value = memtoll(argv[1], NULL);
} else {
} else {
err = "Bad directive or wrong number of arguments"; goto loaderr;
err = "Bad directive or wrong number of arguments"; goto loaderr;
}
}
...
@@ -4154,12 +4165,24 @@ static robj *rdbLoadObject(int type, FILE *fp) {
...
@@ -4154,12 +4165,24 @@ static robj *rdbLoadObject(int type, FILE *fp) {
/* Read list value */
/* Read list value */
if ((len = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL;
if ((len = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL;
o
=
createZiplistObject
();
/* Use a real list when there are too many entries */
if (len > server.list_max_ziplist_entries) {
o = createListObject();
} else {
o = createZiplistObject();
}
/* Load every single element of the list */
/* Load every single element of the list */
while(len--) {
while(len--) {
if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL;
if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL;
/* If we are using a ziplist and the value is too big, convert
* the object to a real list. */
if (o->encoding == REDIS_ENCODING_ZIPLIST &&
ele->encoding == REDIS_ENCODING_RAW &&
sdslen(ele->ptr) > server.list_max_ziplist_value)
convertList(o,REDIS_ENCODING_LIST);
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
dec = getDecodedObject(ele);
dec = getDecodedObject(ele);
o->ptr = ziplistPush(o->ptr,dec->ptr,sdslen(dec->ptr),REDIS_TAIL);
o->ptr = ziplistPush(o->ptr,dec->ptr,sdslen(dec->ptr),REDIS_TAIL);
...
@@ -4882,7 +4905,25 @@ static void moveCommand(redisClient *c) {
...
@@ -4882,7 +4905,25 @@ static void moveCommand(redisClient *c) {
}
}
/* =================================== Lists ================================ */
/* =================================== Lists ================================ */
/* Check the argument length to see if it requires us to convert the ziplist
* to a real list. Only check raw-encoded objects because integer encoded
* objects are never too long. */
static void listTryConversion(robj *subject, robj *value) {
if (subject->encoding != REDIS_ENCODING_ZIPLIST) return;
if (value->encoding == REDIS_ENCODING_RAW &&
sdslen(value->ptr) > server.list_max_ziplist_value)
convertList(subject,REDIS_ENCODING_LIST);
}
static void lPush(robj *subject, robj *value, int where) {
static void lPush(robj *subject, robj *value, int where) {
/* Check if we need to convert the ziplist */
listTryConversion(subject,value);
if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
convertList(subject,REDIS_ENCODING_LIST);
if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
int pos = (where == REDIS_HEAD) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
int pos = (where == REDIS_HEAD) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
value = getDecodedObject(value);
value = getDecodedObject(value);
...
@@ -5077,6 +5118,27 @@ static void lDelete(lEntry *entry) {
...
@@ -5077,6 +5118,27 @@ static void lDelete(lEntry *entry) {
}
}
}
}
static void convertList(robj *subject, int enc) {
lIterator *li;
lEntry entry;
redisAssert(subject->type == REDIS_LIST);
if (enc == REDIS_ENCODING_LIST) {
list *l = listCreate();
/* lGet returns a robj with incremented refcount */
li = lInitIterator(subject,0,REDIS_TAIL);
while (lNext(li,&entry)) listAddNodeTail(l,lGet(&entry));
lReleaseIterator(li);
subject->encoding = REDIS_ENCODING_LIST;
zfree(subject->ptr);
subject->ptr = l;
} else {
redisPanic("Unsupported list conversion");
}
}
static void pushGenericCommand(redisClient *c, int where) {
static void pushGenericCommand(redisClient *c, int where) {
robj *lobj = lookupKeyWrite(c->db,c->argv[1]);
robj *lobj = lookupKeyWrite(c->db,c->argv[1]);
if (lobj == NULL) {
if (lobj == NULL) {
...
@@ -5157,6 +5219,7 @@ static void lsetCommand(redisClient *c) {
...
@@ -5157,6 +5219,7 @@ static void lsetCommand(redisClient *c) {
int index = atoi(c->argv[2]->ptr);
int index = atoi(c->argv[2]->ptr);
robj *value = c->argv[3];
robj *value = c->argv[3];
listTryConversion(o,value);
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
unsigned char *p, *zl = o->ptr;
unsigned char *p, *zl = o->ptr;
p = ziplistIndex(zl,index);
p = ziplistIndex(zl,index);
...
...
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