When it does not fit

A division chosen before the queries arrive

A levelled store's range-filter memory, divided among its levels by trying every assignment against the store's own queries, captures 99% of a perfect filter's saving on both arrival orders, with the small levels at twelve to sixteen bits a key and the deepest at one. A store writing a level cannot try every assignment, but it knows its levels' sizes, and a rule giving each level δ more bits a key for every factor of four it is smaller was predicted to match the fitted division on the shuffled store and to land near the even split's 94% on the store filled a cluster at a time. It matches the fitted division on both: 97.2% to 99.0% shuffled and 99.7% to 99.9% filled a cluster at a time from one bit a key up, with δ chosen on a sample of queries and charged on others. One δ of four, set before any query, is within a point and a half everywhere from one bit a key up. The rule fails exactly where the proposal said: a δ of six or more at one bit a key gives the deepest level nothing, and the shuffled store falls from 97.2% to 73.9%.

One bit a key, divided gave a levelled store a fixed budget of range-filter memory and divided it among the levels by what each level’s filter would save. The store holds a million keys in sixteen clusters, at full size in three levels of 4,096, 61,440 and 983,040 keys, and each level’s filter is a pair of prefix lengths, a coarse one and a fine one, chosen from the level’s keys when the level is written, the design the filter rebuilt with every write measured. The division was found by trying every assignment of bits a key to levels against the store’s own range queries, on one seed of queries, and charged on another. It gave the two small levels twelve to sixteen bits a key and the deepest level one, captured 99% of what a perfect range filter would save on both arrival orders, and left part of the budget unspent. Divided that way, one bit a key on average did what four bits spread evenly could not.

A store cannot divide its memory that way when it writes a level. It knows its levels’ sizes, and it knows what its filters do on its keys only by asking queries it has not yet been asked. That page’s closing section pointed at a rule the small levels’ share of a range filter and the filter each run carries had both reached for. A query that has to check every level pays each level’s false-positive rate, so for a level’s filter the saving from one more bit is about the same whichever level it is, while the cost of a bit a key is in proportion to the level’s keys. The bits a key should therefore grow by a fixed amount for every factor of four by which a level is smaller. It predicted the rule would come within a point of the fitted division’s 99% on the shuffled store and land at the even split’s 94% or a little above on the store filled a cluster at a time, where it would give the small levels bits they do not need; and it named the failure, the deepest level given less than half a bit, where its curve is steep.

The rule

The store, its filters and the charges are the earlier page’s. Every level’s cost at every value on the earlier grid — 0, ½, 1, 2, 3, 4, 6, 8, 12 and 16 bits a key — is the transfers a range query spends on that level with its filter’s pair of prefix lengths chosen on the choosing seed of queries, and every division is charged on the charging seed, so that no division is scored on the queries it was chosen with.

The rule reads only the sizes. For each level it takes rr, the number of factors of four by which the level is smaller than the deepest: 0 for the deepest, about 2 for the middle level, about 4 for the smallest, since the levels here grow by a factor of sixteen. A level gets b+δrb + \delta r bits a key, rounded down to the grid, with bb the largest value whose division fits the budget. One parameter, δ\delta, is swept from 0, the even split, to 8. A store using the rule would choose δ\delta once; it is chosen here on the choosing seed of queries, which a store could sample, and then charged on the other seed. And a single δ\delta of 4 is charged at every budget, as a store would use it with no queries at all.

Matching the division that tried everything

Charged on queries it was not chosen on, the rule at a δ the store picks from its own sample matches the fitted division at every budget on the shuffled store; one δ of 4, set before any query, is within 1.5% of it from one bit a key up there, and within -0.0% on the store filled a cluster at a timeThe share of a perfect filter's saving captured at budgets of 0.5, 1, 2, 4 bits a key, both orders: the fitted division, the even split, the size rule at the δ with the least cost on the choosing seed, and the size rule at δ = 4. shuffled at 0.5: fitted 71.5%, even 37.6%, rule at chosen δ 6 71.5%, rule at δ 4 70.6%; shuffled at 1: fitted 97.2%, even 52.7%, rule at chosen δ 4 97.2%, rule at δ 4 97.2%; shuffled at 2: fitted 99.0%, even 67.5%, rule at chosen δ 8 99.0%, rule at δ 4 97.5%; shuffled at 4: fitted 99.0%, even 83.5%, rule at chosen δ 6 99.0%, rule at δ 4 98.5%; a cluster at a time at 0.5: fitted 78.9%, even 69.8%, rule at chosen δ 3 78.9%, rule at δ 4 78.9%; a cluster at a time at 1: fitted 99.8%, even 82.4%, rule at chosen δ 4 99.8%, rule at δ 4 99.8%; a cluster at a time at 2: fitted 99.6%, even 94.2%, rule at chosen δ 6 99.7%, rule at δ 4 99.9%; a cluster at a time at 4: fitted 99.6%, even 98.8%, rule at chosen δ 4 99.7%, rule at δ 4 99.7%.40%60%80%100%shuffled, 0.5 bits a keyshuffled, 1 bits a keyshuffled, 2 bits a keyshuffled, 4 bits a keya cluster at a time, 0.5 bits a keya cluster at a time, 1 bits a keya cluster at a time, 2 bits a keya cluster at a time, 4 bits a keybar: even split · large dot: fitted · dark dot: rule, δ chosen · small dot: rule, δ = 4charged on unseen queriesshare of the saving
Fig. 1 The share of a perfect filter’s saving at budgets of 0.5, 1, 2 and 4 bits a key on both orders: the fitted division, the even split, the size rule at its chosen δ and at δ = 4. Shuffled at 2 bits a key: fitted 99.0%, even 67.5%, rule 99.0%, δ = 4 97.5%. A cluster at a time at 2 bits a key: fitted 99.6%, even 94.2%, rule 99.7%, δ = 4 99.9%.

Charged on queries it was not chosen on, the rule matches the division that tried every assignment at every budget on both arrival orders: on the shuffled store 71.5%, 97.2%, 99.0% and 99.0% at 0.5, 1, 2 and 4 bits a key, where the fitted division captures the same, and on the store filled a cluster at a time 78.9%, 99.8%, 99.7% and 99.7%, against 78.9%, 99.8%, 99.6% and 99.6%. The prediction for the shuffled store holds exactly. The prediction for the store filled a cluster at a time is wrong in the rule’s favour: it does not land near the even split’s 94%, it lands on the fitted division and at two budgets a tenth of a point above it.

That a one-parameter rule can beat the fitted division at all is a statement about fitting. The fitted division chooses three grid values from ten on the choosing seed, a thousand candidate divisions, and the best of a thousand on one sample is a little worse than the best on another. The rule chooses one value from eight, and its choice transfers. At two and four bits a key on the store filled a cluster at a time, the difference is a tenth of a point, inside what a second seed would move; the claim is that the rule is not worse, not that it is better.

A single δ\delta of four, set with no queries at all, does nearly as well. On the store filled a cluster at a time it captures 99.7% to 99.9% from one bit a key up. On the shuffled store it captures 97.2%, 97.5% and 98.5% at one, two and four bits a key, within a point and a half of the fitted division, and 70.6% at half a bit, within one point.

The parameter, and where it fails

At 2 bits a key, a division read off the levels' sizes captures 99.0% on the shuffled store at δ = 8 and 99.9% on the store filled a cluster at a time at δ = 4, against the fitted division's 99.0% and 99.6% and the even split's 67.5% and 94.2%The share of the perfect range filter's saving each division captures at 2 bits a key on average, charged on queries it was not chosen on, against δ, for both arrival orders; the fitted division and the even split as levels. Shuffled: δ 0 67.5% (2/2/2 bits a key, smallest level first), δ 0.5 78.2% (3/3/1 bits a key, smallest level first), δ 1 83.5% (4/4/1 bits a key, smallest level first), δ 2 93.7% (8/6/1 bits a key, smallest level first), δ 3 96.6% (12/8/1 bits a key, smallest level first), δ 4 97.5% (16/8/1 bits a key, smallest level first), δ 6 98.5% (16/12/1 bits a key, smallest level first), δ 8 99.0% (16/16/1 bits a key, smallest level first); fitted 99.0%, even 67.5%. A cluster at a time: δ 0 94.2% (2/2/2 bits a key, smallest level first), δ 0.5 96.8% (3/3/1 bits a key, smallest level first), δ 1 98.8% (4/4/1 bits a key, smallest level first), δ 2 99.5% (8/6/1 bits a key, smallest level first), δ 3 99.8% (12/8/1 bits a key, smallest level first), δ 4 99.9% (16/8/1 bits a key, smallest level first), δ 6 99.7% (16/12/1 bits a key, smallest level first), δ 8 99.8% (16/16/1 bits a key, smallest level first); fitted 99.6%, even 94.2%.0.7000.8000.9001extra bits a key for every factor of four a level is smallershare of a perfect filter's saving00.5123468a cluster at a timeshuffledfaint levels: the fitted division2 bits a key
Fig. 2 The share of a perfect filter’s saving at 2 bits a key against δ, both orders, with the fitted division as a faint level. Shuffled: 67.5% at δ = 0, 83.5% at 1, 93.7% at 2, 97.5% at 4, 99.0% at 8. A cluster at a time: 94.2% at 0, 98.8% at 1, 99.5% at 2, 99.9% at 4.

At two bits a key the share captured climbs with δ on both orders and flattens past four: on the shuffled store from 67.5% at δ = 0, the even split, to 97.5% at δ = 4 and 99.0% at 8; on the store filled a cluster at a time from 94.2% to 99.9% at four. The climb is steeper on the shuffled store because there the even split is worse: every level holds keys from every cluster, a coarse prefix cannot rule the small levels out of most queries, and their filters need many bits a key to do it with a fine one.

The failure the proposal named is visible at one bit a key. There a δ of four gives the levels 16, 8 and half a bit a key, smallest first, and captures 97.2% on the shuffled store. A δ of six asks for more bits in the small levels than half a bit a key can pay for while the deepest keeps anything, and the rounding to the grid takes the deepest level’s filter away entirely: 16, 12 and nothing. The share captured falls to 73.9%, and on the store filled a cluster at a time from 99.8% to 78.8%. The deepest level holds 94% of the keys, and with no filter every range query reads it; its half bit a key was doing more than the small levels’ extra four.

A store choosing δ\delta from a sample of its queries never chooses six at one bit a key, because the sample shows the collapse. A store setting δ\delta in advance has to know where its deepest level’s curve turns, and on these stores a δ of four leaves it half a bit at one bit a key and a full bit at two, which is enough.

How much the budget forgives

On the shuffled store every δ from two up beats the even split at every budget, and the gap closes as the budget grows: at half a bit a key the even split captures 37.6% and δ = 4 70.6%; at four bits 83.5% and 98.5%; the fitted division is 71.5%, 97.2%, 99.0%, 99.0%The share of a perfect filter's saving against the budget, 0.5, 1, 2, 4 bits a key, on the shuffled store, for the size rule at δ = 0, 1, 2, 4, 8 (δ = 0 is the even split) and the fitted division. δ 0: 37.6%, 52.7%, 67.5%, 83.5%; δ 1: 53.9%, 81.6%, 83.5%, 91.1%; δ 2: 66.4%, 90.8%, 93.7%, 95.0%; δ 4: 70.6%, 97.2%, 97.5%, 98.5%; δ 8: 71.5%, 74.4%, 99.0%, 99.0%; fitted 71.5%, 97.2%, 99.0%, 99.0%.0.4000.6000.8001bits a key of filter memory, on averageshare of a perfect filter's saving0.5124δ = 8δ = 4δ = 2δ = 1δ = 0, the even splitfaint: the fitted divisionshuffled
Fig. 3 The share of a perfect filter’s saving against the budget on the shuffled store, for the rule at δ = 0 (the even split), 1, 2, 4 and 8, beside the fitted division. At half a bit a key: 37.6%, 53.9%, 66.4%, 70.6% and 71.5%. At four bits: 83.5%, 91.1%, 95.0%, 98.5% and 99.0%.

On the shuffled store every δ from two up beats the even split at every budget, and the advantage shrinks as the budget grows: at half a bit a key the even split captures 37.6% and δ = 4 70.6%; at four bits 83.5% and 98.5%. A generous budget forgives a poor division because every level then has enough bits to do most of its job, and the division only decides who gets the surplus. A tight budget forgives nothing. At half a bit a key there is not enough memory to give every level a working filter, and the right division gives the small levels everything and the deepest level nothing: the fitted division at half a bit is 16, 6 and 0 bits a key, and the rule at δ = 4 is 12, 6 and 0.

That is the regime where a store most needs to be told how to divide, and where the rule does least well against the division that tried everything: 70.6% against 71.5%, the largest gap at any budget. The gap is the grid’s: a δ of six or eight reaches 71.5% by putting the smallest level at sixteen bits instead of twelve. At one bit a key and above, the curves for δ from four to eight sit within a point and a half of the fitted division, except where a δ is large enough to starve the deepest level, and the budget at which a store’s filters stop being the cost that matters is the budget past which the division stops mattering too.

What each level gets

The rule reproduces the fitted division's shape — the two small levels near the grid's top, the deepest under a bit or two — because the levels are about two factors of four apart and the grid is coarse: at two bits a key on the shuffled store the fitted division is 16/16/1 bits a key and the rule 16/16/1Bits a key for the store's three levels, of 4,096, 61,440, 983,040 keys, smallest first, under the fitted division and the size rule at its chosen δ, at every budget and both orders. shuffled at 0.5: fitted 16/6/0, rule (δ 6) 16/6/0; shuffled at 1: fitted 16/8/0.5, rule (δ 4) 16/8/0.5; shuffled at 2: fitted 16/16/1, rule (δ 8) 16/16/1; shuffled at 4: fitted 16/16/1, rule (δ 6) 16/16/3; a cluster at a time at 0.5: fitted 12/6/0, rule (δ 3) 12/6/0; a cluster at a time at 1: fitted 12/8/0.5, rule (δ 4) 16/8/0.5; a cluster at a time at 2: fitted 12/12/1, rule (δ 6) 16/12/1; a cluster at a time at 4: fitted 12/12/1, rule (δ 4) 16/12/3.smallest levelmiddle leveldeepest levelshuffled, 0.516166600shuffled, 11616880.50.5shuffled, 21616161611shuffled, 41616161613a cluster at a time, 0.512126600a cluster at a time, 11216880.50.5a cluster at a time, 21216121211a cluster at a time, 41216121213left: fitted · right: the rulebits a key
Fig. 4 Bits a key for the three levels, smallest first, under the fitted division and the rule at its chosen δ, at every budget and both orders. Shuffled at 2 bits a key: fitted 16/16/1, rule 16/16/1. A cluster at a time at 2: fitted 12/12/1, rule 16/12/1.

The rule reproduces the fitted division’s shape at every budget — the two small levels near the top of the grid, the deepest at nothing to three bits — and at two bits a key on the shuffled store it gives exactly the fitted division’s 16, 16 and 1 bits a key. Where the two differ, they differ in the small levels, which hold six per cent of the keys between them: a few bits a key more or less there moves the memory by a few per cent and the cost by almost nothing, because the small levels’ filters are already near-perfect at twelve bits a key.

The shape is forced by the arithmetic of a levelled store more than by anything about these keys. The deepest level holds 94% of the keys, so every bit a key it gets costs the budget almost a bit a key. The small levels hold six per cent between them, so sixteen bits a key there costs about one bit a key of budget. Any division that makes the small levels’ filters good and leaves the deepest a little uses the budget well, and the rule’s one parameter only has to say how good the small levels’ filters should be.

A δ from the other store

A δ chosen on one arrival order and charged on the other loses at most 0.9% of the saving against the δ the store would have chosen for itself: the levels' sizes, which both orders share, carry most of what the division needs to knowFor each budget and each order, the size rule at the δ chosen on that order's own choosing seed, and at the δ chosen on the other order, both charged; the fitted division beside. shuffled at 0.5: own δ 6 71.5%, δ 3 from the a cluster at a time store 70.6%, fitted 71.5%; a cluster at a time at 0.5: own δ 3 78.9%, δ 6 from the shuffled store 78.9%, fitted 78.9%; shuffled at 1: own δ 4 97.2%, δ 4 from the a cluster at a time store 97.2%, fitted 97.2%; a cluster at a time at 1: own δ 4 99.8%, δ 4 from the shuffled store 99.8%, fitted 99.8%; shuffled at 2: own δ 8 99.0%, δ 6 from the a cluster at a time store 98.5%, fitted 99.0%; a cluster at a time at 2: own δ 6 99.7%, δ 8 from the shuffled store 99.8%, fitted 99.6%; shuffled at 4: own δ 6 99.0%, δ 4 from the a cluster at a time store 98.5%, fitted 99.0%; a cluster at a time at 4: own δ 4 99.7%, δ 6 from the shuffled store 99.8%, fitted 99.6%.40%60%80%100%shuffled, 0.5 bits a keya cluster at a time, 0.5 bits a keyshuffled, 1 bits a keya cluster at a time, 1 bits a keyshuffled, 2 bits a keya cluster at a time, 2 bits a keyshuffled, 4 bits a keya cluster at a time, 4 bits a keydark: δ chosen on this order · green: δ from the other order · small: fittedcharged on unseen queriesshare of the saving
Fig. 5 For each budget and order, the rule at the δ chosen on that order’s own sample and at the δ chosen on the other order’s, both charged, with the fitted division beside. The largest loss from borrowing the other order’s δ is 0.9 of a point, on the shuffled store at 0.5 bits a key.

A δ chosen on one arrival order and charged on the other loses at most a point of the saving against the δ the store would have chosen for itself, and from one bit a key up at most half a point. At one bit a key both orders choose four. At two bits a key the shuffled store chooses eight and the clustered store six, and each does within half a point of its own choice with the other’s. The sizes, which both orders share, carry what the division needs; the arrival order, which decided how much a filter could do, does not decide how its memory should be split.

That is the result the earlier pages had been circling. The filter rebuilt with every write found that arrival order mattered more than when the filter’s lengths were chosen, and one bit a key, divided found the division that tried everything gave the same shape on both orders. Here the shape needs no trying. A store can divide its filter memory from the sizes of its levels, which it knows the moment it writes them, and a constant it can carry from one store to another.

Why the sizes are enough

The rule’s premise was that a level’s saving from a bit is about the same per query at every level, so that only the cost of the bit differs. These measurements do not test that premise directly, but they test its consequence, and the consequence holds better than the premise would suggest. The levels’ curves are not alike, on the earlier page’s evidence: the fitted division never gave the deepest level more than three bits a key at any budget, and never gave the small levels fewer than six above half a bit, which says the deepest level’s filter does most of its work in its first bit or two and the small levels’ keep earning into double figures. What the rule needs is not that the curves be alike but that the optimum put the deepest level near the bottom of its steep stretch and the small levels near the top of theirs, and that is what any curves of these shapes do when the levels differ in size by a factor of sixteen.

So the rule is less a model of the filters than a model of the store. A levelled store’s levels grow by a fixed ratio, the arrangement whose writes the writes nobody counted counted against a B-tree’s, and that ratio is what the rule reads; the runs a range query can skip found that what a range query pays is set by how many of those levels it has to enter. A store with a ratio of four between levels, rather than sixteen, would have more levels of more similar size, and a rule that reads sizes would have more to say about how to divide among them.

What one store cannot say

One store shape. Every number is a store of three levels at full size, sixteen times apart. A store with more levels of closer sizes, or one partway through its fill, has a different distribution of keys among its levels; the earlier page measured its division through the fill, and the rule was measured here only at the end.

One grid. The bits a key are rounded to the earlier page’s grid, and the collapse at a δ of six is partly the grid’s doing: a deepest level allowed a quarter of a bit would keep a filter. A finer grid would soften the failure and could not remove it.

Two seeds of queries. The choosing and charging seeds are one each. A tenth of a point between the rule and the fitted division is inside what a third seed would move, and the claim the plates support is that the rule is as good as the division that tried everything, not better. The queries themselves are the earlier pages’ mix of range widths; a workload of point lookups alone would value the deepest level’s filter differently, and the δ it wants is not measured here.

Still open: a store whose levels are not yet full

The rule was measured on the full store, where three levels hold 4,096, 61,440 and 983,040 keys. Through the fill the deepest level is smaller, sometimes smaller than the middle one is at the end, and the ratio between levels changes at every merge. A store writing a level mid-fill would apply the rule to the sizes it has then, and those sizes are what the rule must be right about.

The measurement that follows applies the rule, with δ fixed at four, at every point of the fill the earlier page measured — an eighth, a quarter, three eighths, a half, three quarters and the whole of the keys — on both orders at every budget, against the division fitted at that point. The prediction is that it stays within a point and a half of the fitted division throughout, since the ratio between levels never falls below four in a levelled store and the rule’s arithmetic holds at any ratio that large. It could fail early in the fill, where the deepest level is the newest and smallest relative to its own eventual size, and the store has fewer keys than its budget was sized for; the rule’s half bit for the deepest level could then be too little at a moment when that level is most of the store. The question is whether a rule that reads sizes is right at every size a store passes through, or only at the size it ends at.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

The objects this essay names

Each one links to every other essay that touches it.

Bloom filterDesign parameterLsm treePer levelPredictionRange queryRead amplificationSpace accounting