Hashing • Teoricamente, técnicas de hashing permitem acesso dinâmico aos dados (inserção/remoção/ recuperação) numa complexidade que independe do número N de registros do arquivo O(1) Hashing estático - para arquivos que não variam de tamanho Função de hashing • Função que gera um endereço aleatório a partir de uma dada chave. • Duas chaves podem definir dois endereços idênticos COLISÃO chave k = Adão Registros 0 h(k) h(k) 1 2 endereço 4 3 4 5 6 Adão Exemplo simples • 75 registros de nomes de pessoas devem ser armazenados num espaço de memória disponível para 1000 destes registros função: transforme os dois primeiros caracteres dos nomes em inteiros, relativos a sua posição na tabela ASCII, multiplique estes valores e utilize os três dígitos menos significativos como endereço. Nome ASCII das duas Produto Endereço priemeiras letras --------------------------------------------------------------------------------------------------------------BALL 66 65 66x65=4290 290 LOWELL 76 79 76x79=6004 004 TREE 84 82 84x82=6888 888 Colisões • Funções de hashing devem gerar poucas colisões Algumas ideias: • distribuir o máximo possível os registros a serem armazenados, no arquivo, de tal forma que dois ou mais registros não sejam atribuídos a um mesmo endereço. • considerar uma grande quantidade de espaço disponível (memória) em relação ao número de registros a serem armazenados (perda de espaço!!) • associar mais de um registro a um único endereço (buckets) Exemplo de um algoritmo de hashing 1. represente a chave numericamente 2. subdivida-a e adicione os diferentes subconjuntos 3. divida o resultado por um número primo (distribuição mais aleatória do resto) e use o resto da divisão como endereço. Para LOWELL: 1. L O W E L L _ _ _ _ _ _ 76 79 87 69 76 76 32 32 32 32 32 32 2. | 76 79 | 87 69 | 76 76 | 32 32 | 32 32 | 32 32 | 7679 + 8769 + 7676 + 3232 + 3232 + 3232 = 33820 Para limitar o resultado a um valor máximo, x, e inserir mais aleatoriedade, podemos utilizar o operador mod: Ex.: x = 19937 número primo distribuição mais aleatória do resto da divisão Assim: 7679 + 8769 = 16448; 16448 + 7676 = 24128; 4187+ 3232 = 7419; 7419 + 3232 = 10651; 10651 + 3232 = 13883; 16448 mod 19937 = 16448 24128 mod 19937 = 4187 7419 mod 19937 = 7419 10651 mod 19937 = 10651 13883 mod 19937 = 13883 3. Objetivo: limitar a faixa de endereço resultante ao número de endereços disponíveis. Seja s a soma obtida no passo 2 anteiror e n o número de endereços disponíveis no arquivo. O endereço resultante, a, pode ser dado por: a = s mod n que gera um valor entre 0 e n-1 Assim: arquivo com 75 registros e n=101 endereços disponíveis: n = 101 primo !!! s = 13883 (LOWELL) 75/101 = 0,743 = 74% do espaço utilizado a = 13883 mod 101 = 84 84 LOWELL Funções de Hashing ideal (uniforme) a b c d e f g 1 2 3 4 5 6 7 8 9 10 aceitável ruim a b c d e f g 1 2 3 4 5 6 7 8 9 10 a b c d e f g 1 2 3 4 5 6 7 8 9 10 Exemplos de funções - Menos aleatória • explora o modelo de definição das chaves: e.g., baseado na informação temporal (data de criação dos registros (dia, mês,ano) • divisão de chaves por um número primo - Mais aleatória • “mid-square”: transforma a chave num grande número decimal, eleva-o ao quadrado e extrai dígitos do meio desta representação, proporcional ao número de casas decimais do maior endereço disponível Ex.: endereços entre 0-99 chave = 342, chave2 = 116964 endereço da chave = 69 • transformação de base: converte a representação numérica decimal da chave para outra base; calcula o mod deste resultado com o máximo endereço disponível. Ex.: Endereços entre 0 – 99 chave10 453 Conversão para a base 11: 453 11 41(resto 2) 41 11 3 (resto 8) 3 11 0 (resto 3) chave11 382 382 mod 100 = 82 Análise da distribuição dos registros no arquivo • Calcula as diversas probabilidades de distribuição dos registros nos endereços disponíveis • Baseia-se na distribuição de Poisson Função de Poisson (r / N ) x e ( r / N ) p ( x) x! Função de Poisson (r / N ) x e ( r / N ) p ( x) x! N = número de endereços disponíveis r = número total de registros a serem armazenados x = número de registros atribuídos a um dado endereço p(x) = probabilidade de a um dado endereço serem atribuídos x registros com uma função de hashing sobre r registros. Exemplo: N = 1000 endereços disponíveis r = 1000 registros a serem armazenados r 1 (grande probabilid ade de colisões) N • Probabilidade de um dado endereço receber x = 0 registro: 10 e 1 p(0) 0,3679 36,79% 0! • Probabilidade de um endereço receber x = 1 registro: 11 e 1 p(1) 0,3679 36,79% 1! • Probabilidade de um endereço receber x = 2 registros: 12 e 1 p(2) 0,184 18,4% 2! • Probabilidade de um endereço receber x = 3 registros: 13 e 1 p(3) 0,061 6,1% 3! Predições de colisão Pela teoria das probabilidades, temos que, para N endereços disponíveis, o número de endereços do arquivo contendo x registros é dado por: N p(x) Assim, para N = r = 1000 r/N = 1 Podemos estimar o número de endereços com: • x = 0 registro: 1000 x p(0) = 367,9 endereço sem registros • x = 1 registro: 1000 x p(1) = 367,9 nenhuma colisão • x = 2 registros: 1000 x p(2) = 183,9 183,9 registros com um sinônimo • x = 3 registros: 1000 X p(3) = 61,3 61,3 registros com 2 sinônimos (2 x 61,3 = 122,6 overflows) Problema: Reduzir o número de colisões e tratar os casos de overflow !! - Redução do número de colisões • boa função de hashing • uso de endereços extras - Fator de carda D: número de registros r D número de endereços disponíveis N Exemplo: r 500 50 0.5 50% do espaço do arquivo utilizado N 1000 100 Questões: 1- Para este fator de carga, quantos endereços ficarão sem registros associados? (0.5) 0 e 0.5 N p(0) 1000 1000 0.607 607 0! 2- Quantos endereços devem receber exatamente 1 registro? (0.5)1 e 0.5 N p(1) 1000 1000 0.303 303 1! 3- Quantos endereços devem receber um registro mais um ou mais sinônimos? 0 N [ p(2) p(3) p(4) p(5) ... ] = 1000[0.0758 + 0.0126 + 0.0016 + 0.002 + 0] = 90 = 1000 – [607 + 303] = 90 4- Considerando-se apenas um registro/endereço, quantos overflows ocorrem no arquivo? p(2) 1 overflow p(3) 2 overflow p(4) 3 overflows .. . Nx1xp(2) + Nx2xp(3) + Nx3xp(4) + Nx4xp(5) + … = 1000 x [1x0.0758 + 2x0.0126 + 3x.0016 + 4x0.0002 + 0] = 107 overflows 5- Qual a porcentagem de overflows? 107 0,214 21,4% 500 Conclusão: Para um fator de carga igual a 50%, e cada endereço com um único registro, podemos obter 21% de todos os registros originando colisões no arquivo. Relação entre fator de carga e overflows Fator de carga (%) 10 % de sinônimos 4.8 20 30 40 50 9.4 13.6 17.6 21.4 60 70 80 24.8 28.1 31.2 90 34.1 100 36.8 Redução de colisões por overflow progressivo • Em casos de overflows, a lista de endereços é percorrida sequencialmente, até que uma área livre seja encontrada. Esta área representa o endereço destino do registro. Novak Rosen York hash(YORK) Jasper Moreley YORK Procurando um registro que não existe: área vázia Blue não existe no arquivo Blue . . . hash(Blue) Jello Se arquivo cheio, a busca sequencial retorna ao ponto de partida (ciclo completo) a busca se torna inviável! Comprimento Médio de Busca (CMB) compriment o totalde busca CMB númerototalde registros Exemplo: Chave Endereço Adams 20 Bates 21 Cole 21 Dean 22 Evans 20 Chave Endereço Adams 20 Bates 21 Cole 21 Dean 22 Evans 20 comprimento da busca 20 Adams 1 21 Bates 1 22 Cole 2 23 Dean 2 24 Evans 5 11 2 2 5 CMB 2.2 5 CMB versus fator de carga para uma função de hashing com um registro por endereço e overflow progressivo empregado no caso de colisões CMB Fator de carga D Abordagem de colisões por buckets • Buckets: conjunto de registros associados a um mesmo endereço. chave Green Hall Jenks King Land Marx Nutt 30 Green endereço 30 30 32 33 33 33 33 cada endereço pode conter 3 registros Hall 31 32 Jenks 33 King Land Marks Nutt é um overflow Densidade de armazenamento por buckets • Considera o número de endereços (buckets), N, e o número de registros, b, possíveis de serem armazenados em cada endereço (tamanho dos buckets): r DB bN Ex.: r = 750 N = 1000 b=1 750/1000 = 75% r = 750 N = 500 b=2 750/1000 = 75% r/N = 0.75 r/n = 1.5 Distribuição de Poisson para os dois tipos de arquivos p(x) Sem buckets (r/N=0.75) Com buckets (r/N=1.5) p(0) p(1) p(2) p(3) p(4) p(5) p(6) p(7) 0.472 0.354 0.133 0.033 0.006 0.001 ------- 0.223 0.335 0.251 0.126 0.047 0.014 0.004 0.001 Comparação de performance: • Para o caso de b=1, r/N=0.75 e N = 1000, o número de overflows é: 1000 x [1xp(2) + 2xp(3) + 3xp(4) + 4xp(5) + 0 ] = 222 registros de overflow 222/750 = 29,6% de overflows • Para o caso de b = 2, r/N = 1.5 e N = 500, o número de overflows é: 500 x [ 1xp(3) + 2xp(4) + 3xp(5) + 4xp(6) + 0 ] = 140 registros de overflow 140/750 = 18,7% de overflows Overflow de registros em função de diferentes tamanhos de buckets e fator de carga Tamanho do bucket Fator de carga Porcentagem de overflows Supressão de registros • a supressão não deve comprometer novas buscas. • o espaço liberado deve poder ser reutilizado, por exemplo, no caso de um overflow progressivo chaves Adams Jones Morris Smith hash(chaves) 5 6 6 5 End. real 5 6 7 8 4 5 Adams 6 Jones 7 Morris 8 Smith Apagando-se Morris chaves Adams Jones Morris Smith hash(chaves) 5 6 6 5 5 6 7 8 6 Adams 6 Jones 7 Morris 8 Smith Adams Jones 7 8 5 observe que Smith não se encontra na melhor posição após a supressão 4 5 4 End. real Smith Smith está no arquivo? 4 5 Adams 6 Jones 7 ######## 8 Smith Hashing duplo Objetivo: diminuir o clustering de registros em torno de um mesmo endereço menor CMB Ideia: “espalhar” aleatoriamente os registros de overflow. Método: Em casos de colisões, considere uma segunda função de hashing cujo resultado será adicionado ao primeiro endereço do registro; repita este procedimento até encontrar uma posição disponível. desvantagem: falta de localidade maior número de seeks eventualmente Overflow progressivo encadeado • Os sinônimos são encadeados a partir de apontadores cada endereço contém um apontador para o próximo registro de mesmo endereço - vantagem: apenas os sinônimos são acessados numa determinada busca. - desvantagem: temos campo de apontadores a mais; é preciso garantir a busca correta aos sinônimos a partir do primeiro registro. Exemplo 1: Overflow progressivo Chave hash(chave) Adams Bates Cole Dean Evans Flint 20 21 20 21 24 20 End. real Comprimento de busca 20 21 22 23 24 25 1 1 3 3 1 6 CMB = (1 + 1 + 3 + 3 + 1 + 6)/6 = 2.5 - Overflow progressivo encadeado 20 Adams CMB = (1 + 1 + 2 + 2 + 1 + 3)/6 = 1.7 22 21 Bates 23 22 Cole 25 23 Dean -1 24 Evans -1 25 Flint -1 Exemplo 2: Chave hash(chave) Adams Bates Cole Dean Evans Flint 20 21 20 22 24 20 - Overflow progressivo encadeado 20 Adams 22 21 Bates -1 22 Cole ? 23 Dean -1 24 Evans -1 25 Flint -1 Área separada de overflow • Objetivo: evitar que registros de overflow ocupem endereços errados. Assim: - área principal de dados contém registros com endereços “corretos”. - área de overflow contém registros de overflows. • Vantagens: os endereços da área principal de dados ficam livres para as novas adições de registros; o espaço no arquivo de overflow é alocado quando necessário; o processamento é simplificado • Desvantagem: se overflow encontra-se em outro cilindro no disco maior tempo de seek Exemplo: Chave hash(chave) Adams Bates Cole Dean Evans Flint 20 21 20 21 24 20 20 21 Adams 0 Bates 1 0 1 22 2 23 3 24 Evans -1 Cole 2 Dean -1 Flint -1 Tabela de Índices • ideia: definir uma função de hashing que consulte um arquivo (tabela) de índices apontando para registros. - Vantagem: a consulta aos índices se dá num único passo. - Desvantagem: necessita de um acesso a mais na estrutura de hashing K 20 Adams Cole 21 Bates Dean 22 h(K) 23 24 25 Evans -1 Flint -1 -1 Análise da frequência de aparição dos dados • Baseia-se na frequência de ocorrência das chaves para decidir quais devem ser armazenadas inicialmente no arquivo (aquelas de maior fdp).