Diccionario de notas de estudio de Redis (3)

El diccionario de Redis utiliza una tabla hash como implementación subyacente. Una tabla hash puede tener varios nodos de tabla hash, y cada nodo hash se almacena en un par clave-valor en el diccionario.

La tabla hash utilizada por el diccionario redis está definida por la estructura de disht.

typedef struct dictht{
    
    
    dictEntry **table;//哈希表数组
    unsigned long size;//哈希表大小
    unsigned long sizemask;//哈希表大小掩码,用于计算索引值 ,总是等于size -1
    unsigned long used;//该哈希表已有节点数量
}

El atributo de la tabla es una matriz. Cada elemento en la matriz es un puntero a una estructura dictEntry. Cada estructura dictEntry contiene un par clave-valor. No hay mucho que decir sobre otros atributos.

Nodo de tabla hash

Los nodos de la tabla hash se identifican mediante la estructura dictEntry y cada dictEntry almacena un par clave-valor.

typedef struct dictEntry{
    
    
    void *key;//键
    union{
    
    
    void *val;
    uint64_tu64'
    int64_ts64'
    } v;//值
    struct dictEntry *next;//指向下个哈希节点,形成链表
} ductEntry;

El atributo * next es un puntero a otro nodo de la tabla hash. Este puntero puede conectar varios pares clave-valor con el mismo valor hash para resolver el problema de los conflictos de claves. Por lo tanto, cada índice hash es una lista enlazada individualmente.

El diccionario en Redis está representado por la estructura dict:

typedef struct dict{
    
    
    dictType *type;//类型特定函数
    void *orivdata;//私有数据
    dictht ht[2];//哈希表
    int trehashidx;//rehash 索引 ,当rehash不再进行时,值为-1
} dict;

Redis calcula el valor hash y el valor del índice:

hash = dict->type->hashFunction(key);
index = hash & dict->ht[x].sizemask;

Resolver conflictos clave:

Cuando dos o dos claves del mismo número se asignan al mismo índice en la matriz de la tabla hash, se denomina conflicto de estas claves para nosotros. La tabla hash de Redis utiliza el método de dirección en cadena para resolver conflictos. El siguiente puntero de cada nodo de la tabla hash forma una lista enlazada individualmente para resolver conflictos clave.

Además, debido a que la lista vinculada no tiene un puntero al final de la lista vinculada, para considerar la velocidad, el nodo recién agregado se coloca al principio de la lista vinculada cada vez (la complejidad es O (1)).

Refrito

A medida que las claves almacenadas en la tabla hash aumentan o disminuyen, con el fin de mantener el factor de carga de la tabla hash dentro de un rango razonable, el programa repetirá (re-hash) el tamaño de la tabla hash.

1、为字典表的ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作以及ht[0]包含的键值对数量

    (1)如果执行扩展,ht[1] =第一个>=ht[0].used * 2 的2的n次方幂。

    (2)如果收缩 ht[1] = 第一个>=ht[0].used 的2的n次方幂

2、h[0] 迁移至h[1]。

3、清空h[0],将h[1]设置为h[0],新建h[1]。

Refrito progresivo

La tabla de diccionario utiliza simultáneamente ht [0], ht [1] y ht [0] para migrar a ht [1] en lotes a través del contador de índice, con el fin de resolver el problema de demasiados pares clave-valor contenidos en ht [0].


Aprende un poco todos los días, siempre habrá ganancias.

Nota: Respete los derechos de propiedad intelectual del autor, consulte "Diseño e implementación de Redis" para ver el contenido del artículo y solo aprenda aquí para compartirlo con usted.


Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/xuetian0546/article/details/106882585
Recomendado
Clasificación