|
|
|
|
![]() |
![]() |
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:
|