06.05.2013 Views

Tema 7: Archivos dispersos

Tema 7: Archivos dispersos

Tema 7: Archivos dispersos

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Tema</strong> 7: <strong>Archivos</strong> <strong>dispersos</strong><br />

1.Introducción<br />

1.En busca de un acceso en tiempo O(1)<br />

2.Similitudes con tablas hash<br />

2.<strong>Archivos</strong> <strong>dispersos</strong> con compartimentos<br />

1.Operaciones con archivos <strong>dispersos</strong><br />

2.Alternativas a la dispersión lineal<br />

3.Limitaciones de los archivos <strong>dispersos</strong> tradicionales<br />

4.Hashing extensible<br />

1.Operaciones con archivos <strong>dispersos</strong> extensibles<br />

2.Consideraciones finales<br />

<strong>Archivos</strong> Dispersos<br />

1


En busca del acceso en tiempo O(1)<br />

Los árboles B y B + consiguen localizar datos en<br />

tiempo óptimo O(log m n) siendo m el orden del árbol<br />

La idea de los archivos <strong>dispersos</strong> es reducir este<br />

tiempo a O(1), utilizando las técnicas de dispersión o<br />

hashing<br />

Este tipo de estructura de ficheros es interesante en<br />

aplicaciones con una frecuencia de búsquedas muy<br />

alta y donde el tiempo de búsqueda sea crítico<br />

<strong>Archivos</strong> Dispersos<br />

2


Similitudes con las tablas hash<br />

Los archivos <strong>dispersos</strong> localizan la información<br />

utilizando una función hash h, tal que h(k)=x, siendo<br />

k el valor de la clave de un registro y x la posición<br />

donde se alberga en fichero el dato<br />

Cuando ocurre que h(k1)=h(k2), k1≠k2, decimos<br />

que k1 y k2 son sinónimos y se ha producido una<br />

colisión.<br />

Al igual que con tablas hash, el objetivo de todo archivo disperso consiste en<br />

encontrar funciones hash que distribuyan lo mejor posible los datos, minimizando<br />

el número de colisiones (ver documentación de Estructuras de Datos I)<br />

La elección del tamaño del fichero depende del<br />

número potencial de datos a albergar y es clave para<br />

su buen funcionamiento<br />

<strong>Archivos</strong> Dispersos<br />

3


Al igual que en memoria, los distintos tipos de<br />

archivos <strong>dispersos</strong> dependen del modo en que se<br />

resuelvan las colisiones<br />

En archivos <strong>dispersos</strong> con colisiones progresivas o<br />

lineal se localiza secuencialmente la siguiente<br />

posición vacía para insertar un nuevo dato<br />

Si se busca el dato con clave k y ocurre que en la posición x=h(k) no está k, se<br />

debe seguir secuencialmente hasta encontrar el siguiente hueco. Si en ese<br />

recorrido no se encuentra a k, el dato no se encuentra en fichero<br />

El problema es que la probabilidad de encontrar<br />

colisiones es elevada y funcionan mal en zonas con<br />

concentración de datos<br />

Una posible solución es utilizar compartimentos o<br />

cubetas<br />

<strong>Archivos</strong> Dispersos<br />

4


<strong>Archivos</strong> Dispersos con Compartimentos<br />

<strong>Archivos</strong> Dispersos<br />

Para evitar colisiones progresivas resulta bastante<br />

eficiente considerar una posición x como una cubeta o<br />

compartimento con espacio para más de un registro<br />

El tamaño es otro factor a estudiar. Cuanto mayor es un compartimento menor es<br />

la búsqueda lineal que se espera realizar aunque mayor es el tiempo necesario para<br />

buscar dentro de un compartimento.<br />

Cuando ocurre que h(k1)=h(k2), k1≠k2, ambos datos<br />

se albergan en el mismo compartimento<br />

Una colisión se produce cuando un compartimento<br />

está lleno<br />

Cada compartimento tiene un contador indicando el<br />

número de registros válidos que mantiene, aunque no<br />

indica cuales son<br />

5


Inicializar un archivo disperso<br />

Se debe estudiar la naturaleza de la clave, elegir la<br />

función hash más adecuada, el tamaño de la cubeta<br />

y el número de éstas en el fichero<br />

Se recorre el fichero de entrada de datos y se<br />

calcula la ubicación de cada dato<br />

Insertar un dato<br />

Encontrar la cubeta x=h(k) para el dato con clave k.<br />

Si dicha cubeta tiene huecos se inserta el dato ahí,<br />

sino hay una colisión<br />

El modo más simple de resolver colisiones es<br />

utilizando dispersión lineal o progresiva<br />

<strong>Archivos</strong> Dispersos<br />

6


En el siguiente ejemplo, la función hash se calcula usando los caracteres 0,3,6 y<br />

7 de la clave<br />

Como el tamaño del compartimento es igual a 3, se produce una colisión al<br />

insertar BenSup01, que se ubica en el compartimento siguiente utilizando<br />

dispersión lineal<br />

BeaCal01<br />

BeaShu01<br />

BemAmo01<br />

BeaIsa01<br />

BenSta01<br />

BeaSur02<br />

BeaIwa01<br />

BeaMyb01<br />

BelTel01<br />

BenSpa01<br />

BenSup01<br />

BeaSur03<br />

BelCom01<br />

BeaSur04<br />

BeaShu01<br />

BenSta01<br />

BenSpa01<br />

BeaIsa01<br />

BeaIwa01<br />

BenSup01<br />

BeaMyb01<br />

Archivo Disperso<br />

0 1 2 3 4 5 6 7<br />

B e a S h u 0 1<br />

h(BeaShu01)=h(BenSta01)=<br />

h(BenSpa01)=h(BenSup01)<br />

<strong>Archivos</strong> Dispersos<br />

7


Borrado de registros<br />

Los borrados son complicados porque:<br />

1 Un borrado en un compartimento puede servir de parada a futuras búsqudas<br />

2 Los huecos de los registros borrados deben ser reutilizados<br />

Para ello deben utilizarse marcas de borrado<br />

especiales indicando que dicha posición tuvo un dato<br />

En el ejemplo: borramos BeaMyb01 y<br />

BenSpa01. La marcha “­­­” representa un<br />

BeaShu01<br />

borrado normal y “///” un borrado especial<br />

BenSta01<br />

///Spa01<br />

BeaIsa01<br />

BeaIwa01<br />

BenSup01<br />

­­­Myb01<br />

Archivo<br />

Disperso<br />

<strong>Archivos</strong> Dispersos<br />

8


De este modo no se rompe la secuencia de<br />

búsqueda<br />

El espacio liberado sirve para futuras inserciones<br />

No será necesario poner estas marcas cuando se realicen borrados en<br />

compartimentos incompletos<br />

Un problema adicional es que para evitar la<br />

inserción de claves repetidas debe realizarse un<br />

proceso de búsqueda completo<br />

Incluso encontrando un hueco con marca especial, se debe seguir la búsqueda<br />

hasta el final, es decir, hasta encontrar una marca de casilla vacía (y nunca usada)<br />

Después de muchos borrados e inserciones el<br />

rendimiento total del fichero se ve afectado<br />

Aunque se sabe que esta situación alcanza cierto equilibrio a partir del cual la<br />

situación no suele agravarse más<br />

<strong>Archivos</strong> Dispersos<br />

9


Alternativas a la dispersión lineal<br />

El problema de trabajar con dispersión lineal es el<br />

sucesivo agrupamiento de los datos<br />

Una posible solución es utilizar una segunda función<br />

hash o dispersión doble<br />

El problema es que se necesita un esfuerzo adicional para acceder a disco en<br />

posiciones no cercanas (lo que no es un inconveniente en memoria)<br />

El tratamiento de colisiones con encadenamiento<br />

progresivo es similar al lineal pero encadenando las<br />

siguientes posiciones a modo de listas enlazadas<br />

El siguiente compartimento está situado en una dirección distinta de la contigua<br />

que se guarda en el propio compartimento<br />

Como inconvenientes está el espacio adicional para guardar dichas posiciones y<br />

de nuevo el tener que hacer lecturas en posiciones alejadas unas de otras<br />

<strong>Archivos</strong> Dispersos<br />

10


Más utilizado que las alternativas anteriores resulta<br />

el encadenamiento con área de saturación separada<br />

El archivo disperso está compuesto de dos áreas:<br />

(1) el área primaria y (2) el área de saturación<br />

El área de saturación se ubica en un nuevo fichero que almacena únicamente las<br />

colisiones producidas<br />

En el área de primaria (normalmente agrupados en compartimentos) añaden la<br />

dirección donde se encuentran los siguientes sinónimos en el área de saturación<br />

A su vez, el área de saturación encadena las sucesivas colisiones que se sigan<br />

produciendo<br />

....<br />

11 BeaCal01 ­1<br />

12 BeaShu01 0<br />

13 BemAmo01 ­1<br />

14 BeaIsa01 2<br />

16 BeaSur02 ­1<br />

18 BeaMyb01 ­1<br />

19 BelTel01 ­1<br />

24 .....<br />

Área Primaria<br />

....<br />

0 BenSta01 1<br />

1 BenSpa01 3<br />

2 BeaIwa01 ­1<br />

3 BenSup01 ­1<br />

4 ....<br />

Área de Saturación<br />

<strong>Archivos</strong> Dispersos<br />

11


Limitaciones de los archivos <strong>dispersos</strong><br />

tradicionales<br />

Los archivos <strong>dispersos</strong> descritos hasta el momento<br />

poseen normalmente un comportamiento peor que<br />

los árboles B<br />

Una colisión puede implicar en el peor de los casos:<br />

La lectura de un compartimento completo<br />

Desplazamientos lineales o encadenados sobre el mismo fichero o sobre el área<br />

de desbordamiento<br />

El denominado hashing extensible evita en gran<br />

medida estos problemas<br />

<strong>Archivos</strong> Dispersos<br />

12


Hashing Extensible<br />

El objetivo del hashing extensible es evitar al<br />

máximo los recorridos secuenciales o encadenados,<br />

así como un área de saturación separada<br />

Los datos se guardan en un archivo disperso con<br />

compartimentos de tamaño n, similar a los<br />

estudiados anteriormente<br />

Pero se va a mantener un archivo adicional o<br />

directorio a modo de árbol localizador de<br />

compartimentos<br />

<strong>Archivos</strong> Dispersos<br />

13


El directorio sólo contiene las direcciones del<br />

archivo disperso donde encontrar los datos. Al tener<br />

un tamaño mucho más pequeño, es más fácil y<br />

eficiente de manejar y modificar<br />

Las colisiones se tratan duplicando compartimentos,<br />

y en ocasiones, duplicando el espacio de direcciones<br />

(el directorio)<br />

De igual forma, los borrados pueden provocar la<br />

unión de compartimentos y reducción del espacio de<br />

direcciones<br />

<strong>Archivos</strong> Dispersos<br />

14


La función hash ahora debe proporcionar un valor<br />

binario de tamaño b correspondiente a una entrada<br />

del directorio. El valor de b es la profundidad global<br />

del directorio<br />

Ejemplo: se tienen tres compartimentos que se pueden direccionar con 2 bits<br />

Supongamos que introducimos los siguientes datos:<br />

h(BenShu01,BenSta01,BenSpa01,BenSup01)=0=000,<br />

h(Bealsa01)=h(BeaIwa01)=7=111, h(BeaMyb01)=5=101, h(BenCal01)=2=010<br />

Profundidad global<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Directorio<br />

2<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

1<br />

BeaIsa01 BeaIwa01<br />

2<br />

Profundidad local<br />

BeaCal01<br />

BeaMyb01<br />

<strong>Archivos</strong> Dispersos<br />

15


Pero a veces dos direcciones del directorio<br />

comparten la misma cubeta de datos<br />

Esto ocurre cuando en un compartimento caben los datos de dos direcciones<br />

distintas pero que coinciden en los bits menos significativos<br />

Por ejemplo, h(BeaIsa01)=h(BeaIwa01)=111 y h(BeaMyb01)=101. Sus funciones<br />

hash devuelven direcciones distintas, pero acabando en 1 (el resto de claves se<br />

posicionan en direcciones acabadas en 0)<br />

Como se necesita un solo bit para direccionar este compartimento, la profundidad<br />

local es 1<br />

Profundidad global<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Directorio<br />

2<br />

1<br />

2<br />

Profundidad local<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

BeaIsa01 BeaIwa01<br />

BeaCal01<br />

BeaMyb01<br />

<strong>Archivos</strong> Dispersos<br />

16


Buscar un dato<br />

La búsqueda es directa, sólo se necesita visitar un<br />

compartimento<br />

1 Se calcula x=h(k) y se toma el número de bits menos significativos que indique la<br />

profundidad global<br />

2 El compartimento resultante debe tener el dato, en caso contrario se sabe que el<br />

dato no se encuentra<br />

El número máximo de accesos es de dos<br />

h(BeaMyb01)=5=101<br />

Profundidad global<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Directorio<br />

2<br />

1<br />

2<br />

Profundidad local<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

BeaIsa01 BeaIwa01<br />

BeaCal01<br />

BeaMyb01<br />

<strong>Archivos</strong> Dispersos<br />

17


Insertar un dato<br />

La inserción de un dato puede implicar:<br />

1 Que un compartimento tenga que ser desdoblado en dos sin afectar al directorio<br />

2 Que el directorio se duplique al duplicarse un compartimento (añadiendo un<br />

nuevo bit al espacio de direcciones)<br />

3 Que directorio y compartimentos asuman el nuevo dato sin modificaciones<br />

La siguiente inserción no modifica la estructura de los archivos<br />

Supongamos que:<br />

h(BenAmo01)=6=110<br />

2 Profundidad local<br />

Profundidad global<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Directorio<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

1<br />

BeaIsa01 BeaIwa01<br />

2<br />

BeaCal01<br />

BenAmo01<br />

BeaMyb01<br />

<strong>Archivos</strong> Dispersos<br />

18


Las dos siguientes inserciones duplican el compartimento referenciado por 01 y<br />

11. Como el reparto sobre de las claves en dos compartimentos es posible, el<br />

espacio de direcciones no necesita duplicarse<br />

Supongamos que se insertan datos con las siguientes claves:<br />

h(BeaSur02)=1=001<br />

h(BelTel01)=7=111<br />

La profundidad local de todos los compartimentos es ahora igual a 2<br />

Profundidad global<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Directorio<br />

2<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

2<br />

BeaMyb01<br />

2<br />

BeaCal01<br />

2<br />

Profundidad local<br />

BeaSur02<br />

BeaAmo01<br />

Bealsa01 BeaIwa01 BeaTel01<br />

<strong>Archivos</strong> Dispersos<br />

19


Cuando la profundidad de un compartimento es igual a la profundidad global y está<br />

lleno, la siguiente colisión implica duplicar el espacio de direcciones<br />

Supongamos que se inserta una nueva clave: h(BelCom01)=4=100<br />

Las claves no caben en la cubeta 00 y se redispersan entre las dos nuevas cubetas<br />

La profundidad local de estos compartimentos se incrementa en 1<br />

Profundidad global<br />

000<br />

001<br />

010<br />

011<br />

100<br />

101<br />

110<br />

111<br />

3<br />

Directorio<br />

3<br />

BenShu01 BenSta01 BenSpa01 BenSup01<br />

2<br />

2<br />

Profundidad local<br />

BeaMyb01<br />

BeaCal01<br />

3<br />

BelCom01<br />

2<br />

BeaSur02<br />

BenAmo01<br />

BeaIsa01 BeaIwa01 BeaTel01<br />

<strong>Archivos</strong> Dispersos<br />

20


Eliminar un un dato<br />

Al igual que un árbol B, un archivo disperso<br />

extensible debe ser capaz de disminuir su tamaño al<br />

eliminar datos. Pueden darse tres situaciones:<br />

Los compartimentos no quedan vacíos<br />

Si al eliminar un dato, el compartimento no queda vacío, no se hace nada<br />

Un compartimento queda vacío<br />

Cuando un compartimento queda vacío, éste deja de ser direccionado<br />

El directorio ahora pasa a apuntar al compartimento que apuntaba antes del<br />

desdoble (aquel cuyos bits menos significativos coinciden)<br />

Finalmente a la profundidad local de dicho compartimento se le resta 1<br />

El espacio de direcciones se reduce<br />

Cuando la profundidad de todos los compartimentos es menor que la profundidad<br />

global, entonces el directorio puede reducirse a la mitad eliminando el bit más<br />

significativo de direccionamiento<br />

Para que la reubicación sea posible, es necesario además que cada pareja<br />

de cubetas pueda reagruparse en una<br />

<strong>Archivos</strong> Dispersos<br />

21


Consideraciones finales<br />

El hashing extensible evita mantener áreas de<br />

desbordamiento y hacer búsquedas con dos lecturas<br />

El directorio puede utilizar igualmente los bits más<br />

significativos, pero es más fácil usar los menos<br />

significativos y copiar el directorio sobre sí mismo<br />

Una mala función de dispersión puede duplicar<br />

innecesariamente el directorio<br />

0<br />

1<br />

1<br />

1<br />

0, 2<br />

1<br />

1, 3<br />

00<br />

01<br />

10<br />

11<br />

Menos significativos<br />

2<br />

1<br />

0, 2<br />

1<br />

1, 3<br />

0<br />

1<br />

1<br />

1<br />

0, 1<br />

1<br />

2, 3<br />

00<br />

01<br />

10<br />

11<br />

2<br />

Más significativos<br />

1<br />

0, 1<br />

1<br />

2, 3<br />

<strong>Archivos</strong> Dispersos<br />

22

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!