Parameter: i
Insert( x, recordPtr(x) )
{
k = h(x); // Genenral Hash function value
j = first i bits of k; // Extensible hash function value
Read bucket[j] (1 block) into memory;
if ( bucket[j] block has space for a search key )
{
Insert (x, recordPtr(x) ) into the block;
Write block back to disk;
return; // Done !
}
else
{
/* -------------------------------------
bucket[j] disk block is full
------------------------------------- */
Let i' = integer label of bucket[j] block;
/* ------------------------------------------------------------
Split bucket j (that has overflowed !!)
into 2 buckets: j0 and j1
------------------------------------------------------------ */
Allocate 2 disk block: j0 and j1;
for ( each search key x' ∈ bucket[j] block ) do
{
/* ===============================================================
Re-hash all keys in bucket[j] using (i'+1) bits in hash value
=============================================================== */
k' = h(x'); // Find hash function value
j' = the first i'+1 bits of k'; // Use 1 more bit !
if ( the last bit in j' == 0 )
store (x', recordPtr(x')) in block j0;
else
store (x', recordPtr(x')) in block j1;
}
(Result:
)
/* ------------------------------------------------
Update the tag of the new blocks j0 and j1
------------------------------------------------ */
Tag the blocks j0 and j1 with the value i'+1;
/* ======================================================
Update pointers to the bucket j (it is now 2 buckets)
====================================================== */
if ( i' < i )
{ /* ===============================================
Note: i' < i indicates that bucket[j'] and its
"copy" points to the SAME disk block
=============================================== */
Situation:
/* -------------------------------------------
We have a spare bucket pointer
No need to allocate more pointers !
------------------------------------------- */
bucket[j'<<1 + 0] = block address j0;
bucket[j'<<1 + 1] = block address j1;
Result:
}
else
{
Situation:
/* =============================================
We need more pointers....
============================================= */
double the bucket array (and copy bucket ptrs) as follows:
bucket[j<<1 + 0] = block address j0
bucket[j<<1 + 1] = block address j1
Result:
set i = i + 1; // Use 1 more bit to hash
}
/* =======================================================
We handled the overflow by allocating an extra bucket
Now we can insert the key (and its rec ptr)
======================================================= */
Insert (x, recordPtr(x)) using the new configuration;
}
}
|