Tema 7: Archivos dispersos
Tema 7: Archivos dispersos
Tema 7: Archivos dispersos
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