Proofs: Extendible hashing
These are the human proofs of Extendible hashing, at full length.
Extendible hashing keeps its invariant and implements a dictionary full
This proof shows: correctness, termination.
We write , and for the set of pairs in the buckets that the directory points to. The invariant is the one of the page: (E1) each bucket has a pattern with , and exactly when ; (E2) each pair in has ; (E3) the keys are distinct; (E4) ; (E5) unless . The hash values are in .
Theorem. Start with and one empty bucket of depth 0, and apply any sequence of EH-INSERT, EH-SEARCH and EH-DELETE. Each operation ends, keeps (E1) to (E5), and keeps equal to the map that the same sequence gives on an abstract dictionary. Each search returns the value of its key in that map, or NIL.
Proof. At the start, the one bucket has pattern 0 of depth 0, and points to it, so (E1) holds; the bucket is empty, so (E2) to (E5) hold.
Step 1 (the right bucket). Assume (E1) and (E2), and let . If a pair with key is in a bucket , then by (E2) . Since , , so by (E1) . Hence lines L1, L4 and L13 find the only bucket that can hold key , and if it holds no pair with key , then is not a key.
Step 2 (search and delete). By Step 1 and (E3), lines L2 and L3 return the value of or NIL. Lines L13 and L14 remove the only pair with key , if there is one, and lower by 1. Removing a pair keeps (E1) to (E5), and the map loses exactly .
Step 3 (doubling, line L7). Let the directory have entries with (E1), and set for , then . For , the new is the old . For a bucket with , the new exactly when , which is . So (E1) holds for the new depth. No pair moves, so (E2) to (E5) hold.
Step 4 (split, lines L8 to L10). Let have depth and pattern ; line L7 ensures before line L8, since it doubles when . Lines L8 to L10 set both depths to , move to the pairs whose hash has bit equal to 1, and move to the directory entries with and bit of equal to 1. Give the pattern and the pattern , both with bits. An index with has when bit of is 0, and when it is 1. So after line L10, exactly when , and exactly when , and . The other buckets and their entries do not change, so (E1) holds. A pair of had , and the same case split on bit of shows that it now satisfies (E2) in or in . The set does not change, so (E3) and (E4) hold. The two new buckets have at most the old size of , and (E5) is used only at line L12.
Step 5 (insert). If line L5 finds , by Step 1 this is its only pair, and the value is replaced; nothing else changes. Else is not a key. While the bucket of is full and , a round of the loop does Steps 3 and 4 and then, by Step 1 applied to the new state, line L11 finds the bucket where a pair with key must go. Each round raises the local depth of the bucket of by 1: after the split, 's bucket is or , both of depth . Since this depth is at most , the loop runs at most rounds and ends. At its end, the bucket of has fewer than pairs, or . Line L12 adds to . By (E1), , so (E2) holds. was not a key, so (E3) holds, grows by 1, so (E4) holds, and now has at most pairs or depth , so (E5) holds. The map is the old map plus .
By induction on the number of operations, the theorem holds.