You are on page 1of 13

Arquivos Diretos: Hashing

Estático (Revisão)
Prof. Kristian Magnani
(Baseado em Folk 11.1, 11.2,
11.3.1-2, 11.4.1+poisson, 11.6.2)
2007 / 2
Atenção: A leitura destes slides
não dispensa a leitura da
bibliografia da disciplina.
Hash
• Um tipo de indexação a custo O(1)
• hash (moer) - é uma função h(k) que transforma
uma chave k em um endereço.
• O endereço retornado é usado como base para
armazenar e recuperar registros.
• Diferenças do hash em relação à indexação:
1. endereços gerados parecem ser aleatórios
(randomizing);
2. duas chaves distintas podem ser mapeadas em um
mesmo endereço (colisão). Neste caso as chaves
são ditas sinônimos.
Um primeiro exemplo
• 75 registros
• chave = nome da pessoa
• Espaço disponível para 1000 registros
• h(k) = pegar o código ASCII dos dois
primeiros caracteres de k e multiplicar
estes valores, e considerar apenas os
últimos 3 dígitos.
J|O|Ã|O 74 (J) * 79 (O) = 846

Problemas:
• muitas colisões;
• combinações desperdiçadas (ex.: xz).
Hash perfeito
• Hash perfeito: h(k) que não gera colisões.
• Encontrar hash perfeito é um problema difícil.
(ex.: 4000 registros, 5000 posições disponíveis,
1 em cada 10120.000 algoritmos [Hanson, 1982])
• Solução prática: reduzir o número de colisões a
um nível aceitável:
1. espalhar os registros (no exemplo, talvez usar mais
do que usar as duas primeiras letras);
2. usar mais memória (mais espaço disponível para
colocar registros);
3. colocar mais de um registro em um mesmo endereço
(buckets).
Um exemplo melhorado
• Passo 1: Representar a chave em forma de
número.

74 79 65 79 32 32 32 32 32 32 32 32
J | O | A | O | | | | | | | |

• Passo 2: Separa e somar


7479 + 6579 + 3232 + 3232 + 3232 + 3232 = 26986

Atenção: cuidado com overflow! (escolher um limite


superior e a cada etapa da soma, tomar o resto da
divisão por este limite.)
Ex.: limite superior = 19937 (primo)
(7479 + 6579) % 19937 = 14058
(14058 + 3232) % 19937 = 17290
(17290 + 3232) % 19937 = 585
(585 + 3232) % 19937 = 3817
(3817 + 3232) % 19937 = 7049

• Passo 3: Dividir pelo tamanho do espaço


de endereçamento e tomar o resto

endereço = soma % tamanho


(Se possível, escolher tamanho primo.)

Tamanho = 101 → 7049 % 101 = 80 → h(JOAO) = 80


Distribuição de registros

1 1 1
A 2 A 2 A 2
B 3 B 3 B 3
C 4 C 4 C 4
D 5 D 5 D 5
6 6 6

Melhor caso Pior caso Aceitável


(uniforme) (poucos
sinônimos)
Algumas táticas de hashing
(Deve-se sempre considerar as características do conjunto de chaves caso-a-
caso.)

1. Examinar as chaves e encontrar um padrão útil


(ex.: no matrícula)
2. Juntar as partes de uma chave (ex.: separar
em pedaços e somar)
3. Dividir por um número (primo) e usar o resto da
divisão
4. Elevar chave ao quadrado e pegar o meio (ex.:
453 → 4532 = 205209 → 52 (0 a 99))
5. Transformação de base (radix) (ex.: 453, de 0
a 98 → 45310 = 38211 → 38210 % 9910 = 85)
Estimando o número de colisões
• p(x) = função de Poisson = probabilidade de um
endereço qualquer receber x registros

p(x) = ((r/N)x . e(-r/N))/x!

onde:
• r = no. de registros a serem armazenados
• N = no. de endereços disponíveis
• x = no. registros atribuídos a um mesmo
endereço
Densidade de empacotamento
• densidade
= no de registros / no de endereços
=r/N

• Se couber mais de um registro por


endereço:
densidade = r / (b . N), onde b = no de registros
por endereço
Detalhes de implementação
• Arquivos que usam hash são baseados em
registros de largura fixa, ou em buckets de
largura fixa.
• Como h(k) não muda para uma chave k,
operações de adicionar, remover ou modificar
registros devem acontecer sem quebrar o
vínculo entre k e o endereço do registro cuja
chave é k.
• Registros livres devem ser marcados como tal.
• Arquivo geralmente é alocado de uma vez,
preenchidos com espaço ou outro caracter.
(Isso geralmente garante que registros ficarão
fisicamente próximos no disco, otimizando o
acesso).
• Tomar cuidado com tentativas de inserir uma
chave que já existe.
• Gerenciar o no de registros em cada bucket.
1 byte

100 bytes 100 bytes 100 bytes 100 bytes 100 bytes
0000 0| | | | |
0501 2|JOAO |ANTONIO | | |
1002 5|MARIA |JOSE |MARTA |PEDRO |ANA
1503 3|PRISCILA |FATIMA |SANDRA | |