Concept

Blocked filter — where it appears

A Bloom filter divided into blocks about the size of a cache line, where a first hash picks one block and all of a key's bits are set inside it. A lookup then reads one block instead of scattered positions, and pays for it with a higher false-positive rate, because blocks receive unequal numbers of keys.

Named by 9 essays across one field — each of them below, with the objects they name alongside it.

0%1.1%2.1%3.2%4.2%the whole filterblocks of 64blocks of 5120123456distinct 512-bit lines a lookup readsabsent keys answered yes16,384 bits, 2,048 keys, k = 6one line is what a block buys

Positions confined to one line

A Bloom filter lookup reads 5.55 cache lines because its six positions are scattered across the whole filter. Confining them to a 512-bit block makes it exactly one, and costs 7% more false positives at eight bits a key. At sixteen bits a key the same block costs 91%, and the two-value trick that is free across a whole filter costs another 135% inside one — because a block is a small filter, and small filters are where the penalty lives.

randomness · Randomness
8121620240.000010.00010.0010.01bits a keyfalse-positive ratethe whole filterone block of 512 bitsthe emptier of two 512-bit blocksone block of 1,024 bits2,048 keys · 24 filters a pointdashed: no blocks

Two blocks and the chances they add

Send each key to the emptier of two 512-bit blocks and the busiest block of a filter at sixteen bits a key holds 35 keys instead of 51. The false-positive rate gets worse: 0.0997% against 0.0854%. At eight bits a key it nearly doubles. A lookup cannot tell which block a key went to, so it has to ask both, and asking twice is two chances to be wrong. At every density a filter is commonly built at, the repair that tames a hash table's worst bucket buys a filter nothing that a block twice as wide does not.

randomness · Randomness
8121620240.00010.0010.01bits a keyfalse-positive rateone blockthe emptier of two blocksone block, chosen by athreshold2,048 keys · 24 filters a pointblocks of 512 bits · same total budgetbest from 12 bits a key

A block the lookup can work out

Sending each key to the emptier of two blocks flattens the load and doubles the chance of a false positive, because a lookup cannot know which block was chosen. Give each block a threshold on a hash of the key instead and the lookup can work it out: one block read, one chance, and 46% of the load balance kept. At sixteen bits a key that is 0.0618% against one block's 0.0854% and two blocks' 0.0997%. The threshold costs 1.5% of the budget and two bits of it are nearly as good as sixteen.

randomness · Randomness
10,000100,000keys in the filtershare of absent keys answered yes0.04%0.05%0.06%0.08%0.10%the emptier of twoone blockone block, Poisson averageone block, by threshold16 bits a key, 512-bit blocks2,000,000 absent queries a point

A penalty set by the block

A blocked Bloom filter pays a penalty for its uneven block loads, and a threshold that lets a lookup work out its block repays about a third of it — measured on 2,048 keys, with a prediction that larger filters would widen the gain. From 2,048 keys to 131,072 nothing moves: one block holds 0.086% to 0.090% against a computed 0.086%, and the threshold design 0.060% to 0.065%. The busiest block grows and the rate does not follow it. What sets both the penalty and the repair is the keys a block holds. A threshold turns out to be worth one doubling of the block's width, and its advantage shrinks from 40% at sixteen keys a block to between 5% and 13% at 128.

randomness · Randomness
0.00%0.05%0.10%0.15%256 bits · one block0.148%256 bits · a threshold on the first0.089%256 bits · thresholds on both0.095%512 bits · one block0.089%512 bits · a threshold on the first0.062%512 bits · thresholds on both0.066%1024 bits · one block0.066%1024 bits · a threshold on the first0.058%1024 bits · thresholds on both0.052%with no spreadwhat the spread adds16 bits a key, 8,192 keysno spread: every block at its mean load

The bits a second threshold costs

A blocked Bloom filter whose first block carries a threshold was proposed a second threshold on each key's second block, with a third block for keys both refuse. It does what it was meant to: at 512-bit blocks it removes nearly a third of the load spread the first threshold left. And the rate does not fall — 0.066% against 0.062% — because the second table, paid for in blocks, raises the rate the filter would have with no spread at all by more than the narrower spread saves. The threshold was stored in more bits than it needs: at four to six bits, one threshold beats the eight-bit design by about a tenth on one run, and a second threshold of the best width ties it at 512-bit blocks.

randomness · Randomness
124816adjacent blocks sharing one thresholdfalse-positive rate0.06%0.08%0.10%0.12%0.14%256-bit blocks512-bit blocks256: one block, no threshold256: one block twice as wide8,192 keys, 16 bits a keyfour-bit thresholds

A threshold knows only its own block

A blocked Bloom filter that gives each block a threshold on a hash of the key lets a lookup work out which of two blocks a key went to, and it spends a small table to do it. Sharing one threshold among a group of blocks would shrink the table, and was proposed as the next saving. It is a loss at every group size. With one four-bit threshold a block, 512-bit blocks reach a false-positive rate of 0.061%; shared by a pair, 0.071%; shared by sixteen, 0.100%, worse than no threshold at all. Neighbouring blocks fill at unrelated moments, so a shared threshold closes when the first of its group does, and every key it turns away lands in a second block chosen at random.

randomness · Randomness
0.0%0.1%0.2%0.3%0.4%0.5%0.6%false-positive rate64-bit blocks1927 blocks128-bit blocks992 blocks256-bit blocks504 blocks512-bit blocks254 blocksreduced by a moduloreduced by its top bitseach dot: one seedupper row of a pair: modulo; lower: top bits

Two hashes that shared their low bits

Two pages on blocked Bloom filters with thresholds each recorded an instability they could not explain: a false-positive rate that collapsed on one seed at 256-bit blocks, and a pair of four-bit thresholds measuring 0.169% where its neighbours measured 0.08%. Both came from how a hash was brought into range. Every filter took its block and its ordering value as a modulo of a multiply-shift hash, and the low bits of such a hash depend only on the low bits of the key, so the two values were dependent whenever the block count had a factor of two to spare. At 992 blocks the threshold filter measures anything from 0.185% to 0.645%; read from the hash's top bits, 0.126% to 0.133%.

randomness · Randomness
22.5033.504block width, bitstable bits a block64128256512four bits eachcoded, a line each, offsetscoded, a line eachcoded, with an indexthe entropyabout two thousand blocks at each widthdashed: the closing distribution's entropy

A code that has to fit its worst line

A blocked Bloom filter's four-bit thresholds are far from uniform: two blocks in five never close, and the rest crowd into the upper values, an entropy of 2.4 to 2.8 bits. A table coded from that distribution was predicted to match the four-bit rate on under three bits a block. Packed end to end it does, at 2.65 to 3.03 bits, and it costs every lookup a second read for the index. Packed a fixed number to a cache line it needs no index, but every line must hold its worst run of long code words, which costs 3.19 bits at 64-bit blocks and eighty-three code words decoded a lookup. Where the table is large enough for the saving to show, a plain three-bit table gets part of it with none of the costs.

randomness · Randomness
2.5033.504block width, bitstable bits a block64128256512four bits eacha bit and four, a line eacha bit and four, end to endcoded, a line eachthree bits eacha bit and three, a line eachmean of four seeds, about two thousand blockslabels at 64-bit blocks

A bit for whether it closed

Almost half of a blocked filter's threshold table says one thing: this block never closed. Store that answer as a bit a block, and a closing value only for the blocks that did, found by counting the ones before it. At 64-bit blocks the prediction was 3.1 bits a block and two cache lines. Packed end to end it lands at 3.15 bits and 2.5 lines; packed a line at a time it reads two lines and counts one word, and costs 3.64 bits, because every line must hold the most closings any line happens to draw. At 512-bit blocks, where three blocks in five close, it saves under a tenth of a bit.

randomness · Randomness

Named alongside it

The objects these essays reach for when they reach for this one.

Design parameterFalse-positive rateBloom filterThresholdBalls in binsTwo choicesLoad balancingCacheLocalityMaximum loadSpace time tradeCache line

All concepts