|
85 | 85 |
|
86 | 86 | /* Hash table parameters */
|
87 | 87 | #define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
|
88 |
| -#define REDIS_HT_MINSLOTS 16384 /* Never resize the HT under this */ |
89 | 88 |
|
90 | 89 | /* Command flags */
|
91 | 90 | #define REDIS_CMD_BULK 1 /* Bulk write command */
|
@@ -370,6 +369,7 @@ static void sremCommand(redisClient *c);
|
370 | 369 | static void smoveCommand(redisClient *c);
|
371 | 370 | static void sismemberCommand(redisClient *c);
|
372 | 371 | static void scardCommand(redisClient *c);
|
| 372 | +static void spopCommand(redisClient *c); |
373 | 373 | static void sinterCommand(redisClient *c);
|
374 | 374 | static void sinterstoreCommand(redisClient *c);
|
375 | 375 | static void sunionCommand(redisClient *c);
|
@@ -417,6 +417,7 @@ static struct redisCommand cmdTable[] = {
|
417 | 417 | {"smove",smoveCommand,4,REDIS_CMD_BULK},
|
418 | 418 | {"sismember",sismemberCommand,3,REDIS_CMD_BULK},
|
419 | 419 | {"scard",scardCommand,2,REDIS_CMD_INLINE},
|
| 420 | + {"spop",spopCommand,2,REDIS_CMD_INLINE}, |
420 | 421 | {"sinter",sinterCommand,-2,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
421 | 422 | {"sinterstore",sinterstoreCommand,-3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
422 | 423 | {"sunion",sunionCommand,-2,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
@@ -691,22 +692,28 @@ static void closeTimedoutClients(void) {
|
691 | 692 | }
|
692 | 693 | }
|
693 | 694 |
|
| 695 | +static int htNeedsResize(dict *dict) { |
| 696 | + long long size, used; |
| 697 | + |
| 698 | + size = dictSlots(dict); |
| 699 | + used = dictSize(dict); |
| 700 | + return (size && used && size > DICT_HT_INITIAL_SIZE && |
| 701 | + (used*100/size < REDIS_HT_MINFILL)); |
| 702 | +} |
| 703 | + |
694 | 704 | /* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL
|
695 | 705 | * we resize the hash table to save memory */
|
696 | 706 | static void tryResizeHashTables(void) {
|
697 | 707 | int j;
|
698 | 708 |
|
699 | 709 | for (j = 0; j < server.dbnum; j++) {
|
700 |
| - long long size, used; |
701 |
| - |
702 |
| - size = dictSlots(server.db[j].dict); |
703 |
| - used = dictSize(server.db[j].dict); |
704 |
| - if (size && used && size > REDIS_HT_MINSLOTS && |
705 |
| - (used*100/size < REDIS_HT_MINFILL)) { |
706 |
| - redisLog(REDIS_NOTICE,"The hash table %d is too sparse, resize it...",j); |
| 710 | + if (htNeedsResize(server.db[j].dict)) { |
| 711 | + redisLog(REDIS_DEBUG,"The hash table %d is too sparse, resize it...",j); |
707 | 712 | dictResize(server.db[j].dict);
|
708 |
| - redisLog(REDIS_NOTICE,"Hash table %d resized.",j); |
| 713 | + redisLog(REDIS_DEBUG,"Hash table %d resized.",j); |
709 | 714 | }
|
| 715 | + if (htNeedsResize(server.db[j].expires)) |
| 716 | + dictResize(server.db[j].expires); |
710 | 717 | }
|
711 | 718 | }
|
712 | 719 |
|
@@ -2961,6 +2968,7 @@ static void sremCommand(redisClient *c) {
|
2961 | 2968 | }
|
2962 | 2969 | if (dictDelete(set->ptr,c->argv[2]) == DICT_OK) {
|
2963 | 2970 | server.dirty++;
|
| 2971 | + if (htNeedsResize(set->ptr)) dictResize(set->ptr); |
2964 | 2972 | addReply(c,shared.cone);
|
2965 | 2973 | } else {
|
2966 | 2974 | addReply(c,shared.czero);
|
@@ -3040,6 +3048,34 @@ static void scardCommand(redisClient *c) {
|
3040 | 3048 | }
|
3041 | 3049 | }
|
3042 | 3050 |
|
| 3051 | +static void spopCommand(redisClient *c) { |
| 3052 | + robj *set; |
| 3053 | + dictEntry *de; |
| 3054 | + |
| 3055 | + set = lookupKeyWrite(c->db,c->argv[1]); |
| 3056 | + if (set == NULL) { |
| 3057 | + addReply(c,shared.nullbulk); |
| 3058 | + } else { |
| 3059 | + if (set->type != REDIS_SET) { |
| 3060 | + addReply(c,shared.wrongtypeerr); |
| 3061 | + return; |
| 3062 | + } |
| 3063 | + de = dictGetRandomKey(set->ptr); |
| 3064 | + if (de == NULL) { |
| 3065 | + addReply(c,shared.nullbulk); |
| 3066 | + } else { |
| 3067 | + robj *ele = dictGetEntryKey(de); |
| 3068 | + |
| 3069 | + addReplySds(c,sdscatprintf(sdsempty(),"$%d\r\n",sdslen(ele->ptr))); |
| 3070 | + addReply(c,ele); |
| 3071 | + addReply(c,shared.crlf); |
| 3072 | + dictDelete(set->ptr,ele); |
| 3073 | + if (htNeedsResize(set->ptr)) dictResize(set->ptr); |
| 3074 | + server.dirty++; |
| 3075 | + } |
| 3076 | + } |
| 3077 | +} |
| 3078 | + |
3043 | 3079 | static int qsortCompareSetsByCardinality(const void *s1, const void *s2) {
|
3044 | 3080 | dict **d1 = (void*) s1, **d2 = (void*) s2;
|
3045 | 3081 |
|
@@ -4170,6 +4206,7 @@ static struct redisFunctionSym symsTable[] = {
|
4170 | 4206 | {"smoveCommand", (unsigned long)smoveCommand},
|
4171 | 4207 | {"sismemberCommand", (unsigned long)sismemberCommand},
|
4172 | 4208 | {"scardCommand", (unsigned long)scardCommand},
|
| 4209 | +{"spopCommand", (unsigned long)spopCommand}, |
4173 | 4210 | {"sinterCommand", (unsigned long)sinterCommand},
|
4174 | 4211 | {"sinterstoreCommand", (unsigned long)sinterstoreCommand},
|
4175 | 4212 | {"sunionCommand", (unsigned long)sunionCommand},
|
@@ -4296,6 +4333,9 @@ static void setupSigSegvAction(void) {
|
4296 | 4333 | act.sa_sigaction = segvHandler;
|
4297 | 4334 | sigaction (SIGSEGV, &act, NULL);
|
4298 | 4335 | sigaction (SIGBUS, &act, NULL);
|
| 4336 | + sigaction (SIGFPE, &act, NULL); |
| 4337 | + sigaction (SIGILL, &act, NULL); |
| 4338 | + sigaction (SIGBUS, &act, NULL); |
4299 | 4339 | return;
|
4300 | 4340 | }
|
4301 | 4341 | #else /* HAVE_BACKTRACE */
|
|
0 commit comments