[Redis Notes] Estruturas de dados e objetos: dicionários

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.

Acho que você gosta

Origin blog.csdn.net/m0_52043808/article/details/124285194
Recomendado
Clasificación