Dicionário: é uma estrutura de dados abstrata que contém pares chave-valor.
Em um dicionário, uma chave (Chave) pode ser associada a um valor (valor) (as chaves são mapeadas para valores), e essas chaves e valores associados tornam-se pares chave-valor.
Cada chave no dicionário é única e o programa pode pesquisar o valor pela chave, atualizar o valor pela chave ou excluir todo o par chave-valor pela chave.
Aplicação do dicionário Redis:
(1) O banco de dados Redis usa o dicionário como a implementação subjacente, e as operações de adicionar, excluir, modificar e consultar o banco de dados também são construídas na operação do dicionário.
(2) Dicionário é uma das implementações subjacentes de chaves de hash.
Implementação do dicionário Redis:
O dicionário usa uma tabela de hash como implementação subjacente. Pode haver vários nós de tabela de hash em uma tabela de hash, e cada nó de tabela de hash armazena um par chave-valor no dicionário.
Definição da estrutura da tabela de hash:
typedef struct dictht{
//哈希表数组
dictEntry **table;
//哈希表大小
unsigned long size;
//哈希表大小掩码,用于计算索引值
//总是等于size-1;
unsigned long sizemask;
//该哈希表已有节点的数量
unsigned long used;
}dictht;
● table é um array, cada elemento no array é um ponteiro para um nó de tabela de hash e cada estrutura dicEntry contém um par chave-valor.
● O atributo size registra o tamanho da tabela de hash, ou seja, o tamanho da matriz da tabela.
●o atributo usado registra o número atual de pares chave-valor na tabela de hash.
A máscara de tamanho junto com o valor de hash determina em qual índice na matriz da tabela uma chave deve ser colocada.
Definição do nó da tabela de hash:
typedef struct dictEntry{
//键
void *key;
//值
union{
void *val;
uint64 _t u64;
int64_t s64;
}
//指向下个哈希表节点,形成链表
struct dictEntry *next;
}dictEntry;
● A propriedade key contém a chave no par chave-valor
A propriedade v contém o valor no par chave-valor
O próximo atributo é um ponteiro para outro nó de tabela de hash. Esse ponteiro pode conectar várias tabelas de hash com o mesmo par chave-valor para resolver o problema de colisão de hash.
Definição do dicionário:
O atributo type é um ponteiro para uma estrutura dictType, cada estrutura dictType contém um conjunto de funções para manipular pares chave-valor de um tipo específico.
A propriedade privatedata contém parâmetros opcionais que precisam ser passados para essas funções específicas
O atributo ht é um array contendo dois itens. Cada item no array é uma tabela de hash dictht. Em geral, o dicionário usa apenas ht[0], e a tabela de hash ht[1] só será usada no ht[1 ] tabela de hash 0] A tabela de hash é usada para rehash.
Se rehash estiver em andamento, o valor de rehashindex será o progresso atual de rehash;
Se rehash não estiver em andamento, o valor de rehashindex será -1;
Algoritmo de hash:
Ao adicionar um novo par chave-valor ao dicionário, o programa precisa primeiro calcular o valor de hash e o valor de índice de acordo com a chave do par chave-valor,
Então, de acordo com o valor do índice, o nó da tabela de hash contendo o novo par chave-valor é colocado no índice especificado da matriz da tabela de hash.
Para resolver colisões de chaves (colisões de hash):
Uma colisão é enviada quando duas ou mais chaves são atribuídas ao mesmo índice na matriz da tabela de hash.
A tabela de hash do Redis usa o método zipper para resolver conflitos de chave. Cada nó da tabela de hash tem um próximo ponteiro. Vários nós da tabela de hash podem usar o próximo ponteiro para formar uma lista vinculada individualmente, que é atribuída a vários nós no mesmo índice. Os nós podem ser conectado usando esta lista vinculada individualmente.
Como a lista encadeada composta de nós de hash não possui um ponteiro para o final da lista encadeada, o programa sempre adiciona novos nós ao início da lista encadeada por motivos de velocidade. A complexidade de tempo é O(1).
Repita:
Com a execução contínua da operação, os pares chave-valor armazenados na tabela hash aumentarão ou diminuirão gradualmente. Para manter o fator de carga da tabela hash dentro de um intervalo razoável, quando o número de pares chave-valor armazenados a tabela de hash é muito grande Quando há muitos ou poucos, o programa precisa expandir ou diminuir o tamanho da tabela de hash de acordo.
Estender e reduzir o tamanho da tabela de hash pode ser feito executando uma operação de rehash.
refaça os passos:
Aloque o espaço ht[1] e transfira todos os nós de ht[0] para ht[1]. ht1,0 troca
Rehash progressivo:
A ação de refazer não é feita de uma só vez, mas refaz o nó de ht[0] para ht[1] em várias etapas.
Se todos esses pares de valores-chave forem refeitos para ht[1] de uma só vez, isso poderá fazer com que o servidor pare de servir por um período de tempo.
Operações de hash durante a execução de rehash progressiva:
Durante a repetição progressiva, operações como excluir, localizar, atualizar etc. do dicionário são executadas nas duas tabelas de hash.
O par chave-valor recém-adicionado sempre será salvo em ht[1], e ht[0] não executará mais nenhuma operação.