Proofs: Quotient filter
These are the human proofs of Quotient filter, at full length.
The false positive rate and the cost of a quotient filter full
This proof shows: complexity.
Model. Assume ideal hashing: for a key , the fingerprint is uniform on and independent of the fingerprints of the keys of . Let be the number of distinct fingerprints stored, at most , and .
Theorem 1. For each , .
Proof. By Theorem 1 of the correctness proof, QUERY is true exactly when is one of the stored fingerprints. Fix the stored fingerprints; there are at most distinct values, and hits each with probability . The union bound gives the claim.
Theorem 2 (cost). Let be the number of slots of the cluster that contains slot , or 1 if that slot is empty. Then QUERY, INSERT and DELETE of take time on the word RAM, and the table takes bits.
Proof. Line L2 moves left inside the cluster, and lines L4 to L10 move and right inside the cluster, so the query reads at most slots. Lines L11 to L17 read and write the slots from to the empty slot after the cluster, at most of them, and sorting is not needed when it is read in order, since the runs are already sorted.
Cluster length. The set of non-empty slots after any sequence of operations equals the set of slots used by linear probing with hash values of the stored fingerprints: in both, the number of used slots in each interval of slots that starts after an empty slot is determined by the quotients in it. So the cluster lengths have the law of linear probing at load , with expected length for the cluster of a random slot under ideal hashing, which this page takes from the analysis of linear probing.
A quotient filter finds each stored fingerprint full
This proof shows: correctness, invariant, termination.
All slot indices are modulo , and "between", "before" and "after" are taken in the cyclic order that starts at the first slot of the cluster in question. Invariant (Q) of the page is assumed in the following precise form. The stored pairs (quotient, remainder) are the multiset of the fingerprints of . Each cluster, with first slot and slots before the empty slot , is split into runs with and . The occupied slots among are , run holds the remainders of quotient in sorted order, and . The first slot of a run has continuation = 0 and the others have 1, shifted[p] = 1 exactly when slot holds a remainder whose quotient is not , and empty slots have all three bits 0.
Lemma 1. If occupied[Q] = 1, then slot is non-empty and lies in the cluster that holds the run of .
Proof. occupied[Q] = 1 only for a slot of some cluster, by the form of the invariant.
Lemma 2. If slot is non-empty and shifted[p] = 0, then for some run of its cluster.
Proof. Slot lies in some run , so it holds a remainder of quotient , and shifted[p] = 0 gives . The run starts at and contains , so .
Lemma 3 (line L2). If occupied[f_q] = 1, the loop of line L2 ends at a slot of the cluster of , at or before , with for some .
Proof. By Lemma 1 the walk starts at a non-empty slot of the cluster. If shifted[p] = 1, then is not the first slot of the cluster, since holds a remainder of quotient . So is in the same cluster. The walk moves left inside the cluster and stops at the latest at , which is unshifted. Lemma 2 gives the form of .
Lemma 4 (lines L4 to L6). Let . The loop keeps and for some , and ends with .
Proof. By Lemma 3 this holds at the start with . Suppose , so . Line L5 moves to the next slot with continuation = 0. The slots are continuations of run , and is the first slot of run , which exists since ; so becomes . Line L6 moves to the next occupied slot, which is , because no slot strictly between and is occupied. So the claim holds for . The index grows by 1 in each round and is at most , so the loop ends, with .
Theorem 1 (query). QUERY returns true exactly when the fingerprint of is in . So it returns true for each key of , and each query ends.
Proof. If occupied[f_q] = 0, no stored pair has quotient and line L1 returns false. Otherwise, by Lemma 4, lines L7 to L10 start at , the first slot of the run of . They read slots and stop at the first later slot with continuation = 0, which is , either the start of the next run or the empty slot . So they compare with exactly the remainders of quotient .
Lemma 5 (decoding). Let in a cluster ending before the empty slot . The slots hold exactly the runs , and the occupied slots among them are , in the same order. No run of another quotient, and no other occupied bit, lies in these slots.
Proof. The runs are consecutive and , . The occupied slots of the cluster from on are , because and the increase.
So line L12 reads back the pairs of runs to : the -th slot with continuation = 0 from starts the run of the -th occupied slot from .
Theorem 2 (insert and delete keep the invariant). Assume at most stored fingerprints before an insert. After INSERT the stored multiset is , and after DELETE for a present fingerprint it is , and in both cases the invariant holds.
Proof. Let be the slot of line L11 or L15. If slot is empty, then and is empty. Otherwise slot is non-empty, and by the argument of Lemma 3 the walk ends at a slot of the same cluster, at or before ; by Lemma 5 the list is the multiset of the pairs stored in slots to , and all their quotients are between and . In both cases is between and .
Line L14 or L17 clears the old slots and writes the new list greedily: the runs in increasing order of quotient, from , each run at the later of its quotient and the slot after the previous run, with the bits set as in the invariant. The pairs outside are unchanged, so the stored multiset changes by exactly the added or removed pair.
The new runs stay in place. For a delete, removing a pair moves each greedy run start left or leaves it, so the new runs lie inside . For an insert, adding one pair moves each greedy run start right by at most 1, so the new runs lie inside . Slot was empty, and the slot after it either is empty or starts a cluster whose first run starts at its own quotient; neither changes, so no two runs overlap. There is still an empty slot, since at most pairs are stored.
The invariant holds. Runs before end before and are unchanged. In the rewritten area, the greedy rule puts each run at or after its quotient and right after the previous run unless there is a gap; after a gap, the run starts at its own quotient, which makes it the first run of a new cluster with . If the area now ends at and touches the next cluster, the two join; the runs of the next cluster start at or after their quotients and follow in increasing order, so the joined cluster satisfies the invariant. The occupied bits of the slots are rewritten from , and by Lemma 5 no other quotient had its occupied bit there.