|
|
|
|
|
|
Fact:
|
|
Notice that:
|
|
|
Hash index:
|
|
|
Example:
|
|
Parameter: n = current number of buckets in use
i = ⌈ log(n) ⌉
Lookup( x )
{
k = hash(x); // General hash function value
m = last i bits of k; // Linear hash function value
if ( m ≤ n−1 )
{
/* =========================================
m is a "real" bucket
========================================= */
Search (x, recordPtr(x)) in bucket m
(including the overflow block);
}
else
{
/* =========================================
m is a "ghost" bucket
Use Suffix-1(m) to map !!
========================================= */
m' = Suffix-1(m);
// I.e.: m = 1xxxxxxxxxx
// m' = 0xxxxxxxxxx
// Note: m' is a "real" bucket !!!
Search (x, recordPtr(x)) in bucket m'
(including the overflow block);
}
}
|
|
if ( Avg occupancy of a bucket > τ )
{
n++; // Increase # physical buckets
}
|
|
Example:
|
r
if ( -------- > τ )
n × γ
{
n++;
}
|
Parameter: n = current number of buckets in use
i = ⌈ log(n) ⌉ (= # bits used in RandomNumGen( x ) )
Insert( x , recordPtr(x) )
{
k = h(x); // h(x) = RandomNumGen(x)
m = k % 2i ; // Last i bits = Linear hash function value
/* -----------------------------------------------
Insert (x, recordPtr(x)) in "bucket m"
----------------------------------------------- */
if ( m ≤ n−1 )
{
/* =========================================
m is a "real" bucket
========================================= */
Insert (x, recordPtr(x)) into bucket m
(if overflow, use an overflow block)
}
else
{
/* =========================================
m is a "ghost" bucket
========================================= */
m' = Suffix-1(m);
// I.e.: m = 1xxxxxxxxxx
// m' = 0xxxxxxxxxx
// Note: m' is for sure a "real" bucket !!!
Insert (x, recordPtr(x)) into bucket m'
(if overflow, use an overflow block)
}
/* =============================================
Check if we need to adjust n
============================================= */
if ( r/(n*γ) > τ )
{
Add bucket n; // Now bucket n is not longer a ghost bucket !!!
n' = Suffix-1(n);
/* ================================================
Note: Bucket[n'] was also used to store keys that
were hashed into the "ghost" bucket n !!!
We must re-hash all keys in Bucket[n'] into:
Bucket[n'] and Bucket[n]
================================================ */
j = ⌈ log(n+1) ⌉ ; // The range of hash bucket index is now [0..n]
// j = number of binary digits to express n
for ( every search key k ∈ bucket n' ) do
{
if ( (last j bits of k) == n )
{
move search key k into the new bucket n;
}
}
}
}
|
Max # search keys in 1 block (γ) = 2 Threshold avg occupance (τ) = 0.85 |
|
Average occupancy:
r 3
------- = ------- = 0.75 (< 0.85)
n × γ 2 × 2
|
|
Average occupancy:
r 4
------- = ------- = 1 > τ (0.85)
n × γ 2 × 2
|
|
Average occupancy:
r 4
------- = ------- = 0.6666 ≤ τ (0.85)
n × γ 3 × 2
|
Notice that:
|
|
Average occupancy:
r 5
------- = ------- = 0.833333 ≤ τ (0.85)
n × γ 3 × 2
|
No need too add another bucket.....
|
Average occupancy:
r 6
------- = ------- = 1 > τ (0.85)
n × γ 3 × 2
|
|
Average occupancy:
r 6
------- = ------- = 0.75 ≤ τ (0.85)
n × γ 4 × 2
|
Notice that:
|
Hint:
|