This commit is contained in:
mingmingtsao 2024-04-17 21:09:16 +08:00 committed by GitHub
commit e5eba41df7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 2 deletions

View File

@ -505,7 +505,7 @@ typedef enum {
#define UNUSED(V) ((void) V)
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
#define ZSKIPLIST_P_DENOMINATOR 4 /* Skiplist P = 1/4 */
#define ZSKIPLIST_MAX_SEARCH 10
/* Append only defines */

View File

@ -58,6 +58,7 @@
#include "server.h"
#include "intset.h" /* Compact integer set structure */
#include "mt19937-64.h"
#include <math.h>
/*-----------------------------------------------------------------------------
@ -124,11 +125,23 @@ void zslFree(zskiplist *zsl) {
* (both inclusive), with a powerlaw-alike distribution where higher
* levels are less likely to be returned. */
int zslRandomLevel(void) {
static const int threshold = ZSKIPLIST_P*RAND_MAX;
#if ZSKIPLIST_P_DENOMINATOR == 4 && ZSKIPLIST_MAXLEVEL == 32
/* Optimized implementation for P = 1/4 and MAXLEVEL = 32.
* Only a single random number is generated, enhancing performance.
* Calculate the count of trailing zeros in a 64-bit random number. The random
* number is bitwise OR'ed with 1<<63 to ensure it's not zero. */
int ctz = __builtin_ctzll(genrand64_int64()|(1LL<<63));
/* Calculate the level based on ctz, with a division by 2 to balance the probability to 1/4. */
int level = 1+(ctz/2);
serverAssert(level<=ZSKIPLIST_MAXLEVEL);
return level;
#else
static const int threshold = RAND_MAX/ZSKIPLIST_P_DENOMINATOR;
int level = 1;
while (random() < threshold)
level += 1;
return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
#endif
}
/* Insert a new node in the skiplist. Assumes the element does not already