Skip to content

Instantly share code, notes, and snippets.

@justdoit0823
Last active October 27, 2018 06:42
Show Gist options
  • Save justdoit0823/d0cb338fd02f7ed12404ea8cd42c89d8 to your computer and use it in GitHub Desktop.
Save justdoit0823/d0cb338fd02f7ed12404ea8cd42c89d8 to your computer and use it in GitHub Desktop.
Redis internal data type analysis.

Internal basic type

  • hashtable
typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

/* This is our hash table structure. Every dictionary has two of this as we
 * implement incremental rehashing, for the old to the new table. */
typedef struct dictht {
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;

The most basic data type hashtable in redis server, which consists of two dictht structs. Then every dictht is a dictEntry array which handles the entry conflicts with a single linked list.

  • intset
typedef struct intset {
    uint32_t encoding;
    uint32_t length;
    int8_t contents[];
} intset;

It stores values as bytearray with different encodings, and queries with binary search algorithm.

  • ziplist
<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>

<prevlen> <encoding> <entry-data>

See more detail about its memory efficiency at hash.

  • quicklist
/* quicklistNode is a 32 byte struct describing a ziplist for a quicklist.
 * We use bit fields keep the quicklistNode at 32 bytes.
 * count: 16 bits, max 65536 (max zl bytes is 65k, so max count actually < 32k).
 * encoding: 2 bits, RAW=1, LZF=2.
 * container: 2 bits, NONE=1, ZIPLIST=2.
 * recompress: 1 bit, bool, true if node is temporarry decompressed for usage.
 * attempted_compress: 1 bit, boolean, used for verifying during testing.
 * extra: 10 bits, free for future use; pads out the remainder of 32 bits */
typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

/* quicklist is a 40 byte struct (on 64-bit systems) describing a quicklist.
 * 'count' is the number of total entries.
 * 'len' is the number of quicklist nodes.
 * 'compress' is: -1 if compression disabled, otherwise it's the number
 *                of quicklistNodes to leave uncompressed at ends of quicklist.
 * 'fill' is the user-requested (or default) fill factor. */
typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* total count of all entries in all ziplists */
    unsigned long len;          /* number of quicklistNodes */
    int fill : 16;              /* fill factor for individual nodes */
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
} quicklist;

The internal data type quicklist is composed with an double linked list, which consists of a ziplist.

High level data type

  • key

The key type is based on a hashtable.

  • list

The list type is based on a quicklist.

  • set

The set type is based on an intset or hashtable.

  • hash

The hash type is based on a ziplist or hashtable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment