What the libraries do

The floor was the marks

A saving reported as about a sixth of a bidirectional index, falling to an eighth and levelling off. Represent one array properly and it falls to a fiftieth instead — most of what was being dropped was a badly encoded bit vector.

A bidirectional index is two self-indexes and one interval. The reverse half exists to be counted in — an extension asks it for ranks and never for a position, because its rows are positions in a text written backwards and the occurrences a search reports come out of the forward interval.

So the reverse half’s locating apparatus can go. An index that cannot locate is the structure and the half that is never asked where is the measurement, which put the saving at 16.7% of both halves at one sampled position in thirty-two — the sixth the deferral naming it had predicted.

That essay also drew the saving across the sampling dial and reported it flattening: 31.2% at one in four, 16.9% at one in thirty-two, 13.5% at one in two hundred and fifty-six, and levelling. Its own prose named the reason correctly: the marks are n bits however rarely a row is kept, and that is the floor the curve flattens onto.

The floor was the marks, the marks did not have to be n bits, and with them represented properly the saving is a fiftieth.

The floor the half-index curve flattens onto, removedWhat dropping the reverse half's locating apparatus saves, against the sampling rate, with the marks held two ways. The published curve is the upper one: it falls by 2.31x across the dial and then flattens at 13.5%, because the marks are n bits whatever the rate and are the whole of what is left to drop. Represent them sparsely and the flat term goes with them: the saving falls by 17.59x, to 1.8% at one in 256. So the celebrated sixth was mostly an artefact of how one array was stored — at one in 4 the two curves are within 0.2% of each other, and by the sparse end they differ by a factor of 7.6.0102030100200one sampled position in every …of both halves saved, per centplain marks: 13.5%Elias-Fano: 1.8%16,384 characters17.6x against 2.3x
Fig. 1 What dropping the reverse half’s locating apparatus saves, against the sampling rate, with the marks held two ways. The upper curve flattens; the lower does not.

The two curves

With plain marks: 31.2% at one in four, 25.1%, 20.2%, 17.0%, 15.1%, 14.0%, 13.5% at one in two hundred and fifty-six. A fall of 2.31 across the dial, and the last three points are within one and a half percentage points of each other.

With Elias–Fano marks: 31.4%, 23.8%, 16.3%, 10.2%, 5.9%, 3.3%, 1.8%. A fall of 17.6, and still falling at the sparse end.

At the dense end the two are within two tenths of a per cent, because at one in four the sparse representation costs the same as the plain vector. At the sparse end they differ by a factor of 7.5.

The two curves crossing at the dense end and diverging at the sparse one is the signature of a constant term being removed, and it is worth recognising because it is what such a removal always looks like. Two quantities that agree where the constant is a small share and diverge where it is most of the total.

If the two curves had been parallel, the sparse representation would be saving a fixed fraction and the floor would still be there at a lower level. If they had crossed and swapped, something would be wrong. Diverging monotonically from a common point is the shape of “one of these has a term the other does not”.

What was actually being dropped

The reverse half’s locating apparatus is two arrays: the sampled positions, (n/s)⌈log₂ n⌉ bits, and the marks, n bits.

At one in thirty-two those are 7,695 and 16,385. Sixty-eight per cent of what the earlier essay was dropping was the marks.

At one in two hundred and fifty-six: 963 and 16,385. Ninety-four per cent.

So the flat part of the published curve was almost entirely one array, and the array was a dense encoding of a set with n/s elements. The saving being celebrated was the saving from not storing a badly stored thing.

Represent it well and there is much less to drop, which is what the lower curve is.

One row in 32 is sampled, and the array saying which is n bitsThe 129 marked rows of an FM-index over 4,097 characters of english, one square per marked row, 128 rows to a line. The marks are the rows whose suffix-array value is a multiple of 32, and the transform scatters them — which is why the picture has no pattern in it and why a representation that exploits runs has little to work with. Stored plainly this is one bit for every row whether it is marked or not: 4,097 bits to record 129 numbers, which is 32x more bits than there are marks.4,097 rows · one in 32 marked3.1% of the rows
Fig. 2 The array that was most of the saving: the marked rows of an index, one square each, stored as one bit for every row whether marked or not.

Putting those percentages into bits makes the earlier result read differently. At one in two hundred and fifty-six, the reverse half’s locating apparatus is 17,348 bits, of which 963 are the sampled positions the apparatus exists for and 16,385 are the array saying which rows they are.

So the essay reporting “the reverse half’s locating apparatus is worth 13.5% of both halves” was reporting, in substance, that a sixteen-thousand-bit index over nine hundred and sixty-three bits of data can be deleted. Which is true and is a strange thing to celebrate.

Is the earlier result wrong

No, and the distinction is worth being careful about because “wrong” and “superseded” are different.

Every number in the earlier essay is a correct measurement of the structure it was measuring: a bidirectional index whose marks are plain bit vectors, which is what every implementation of one has. Dropping the reverse half’s locating apparatus from that structure saves 16.7% at one in thirty-two, and it does.

What has changed is that the structure has a better version. On the better version the same operation saves 10.2%, and at sparser rates far less.

So the earlier essay’s measurement stands and its conclusion does not travel. “Dropping the reverse half’s locating apparatus is worth about a sixth” was a claim about a structure; it is now a claim about a structure nobody should build.

That is the ordinary way a result ages and it is worth saying explicitly because the alternative — quietly updating a number — loses the information that the two structures are different.

What the locating apparatus is, and what it becomesThe two locating parts of an FM-index over 16,384 characters, as a share of the whole structure, against the sampling rate. Plainly represented the share flattens at 18.5% however rarely a row is kept, because the marks are n bits and do not follow the rate at all. With the marks as an Elias-Fano array the share keeps falling, to 3.8% at one in 128. At one in 32 — the rate every published size in this collection is quoted at — the whole index goes from 104,720 bits to 89,150, a saving of 14.9% for a change to one array.02040255075100125one sampled position in every …of the index, per centplain marks: 18.5%Elias-Fano: 3.8%16,384 characters14.9% off at one in 32
Fig. 3 The component that was doing the flattening: the locating apparatus’s share of one index, with the marks held both ways.

What the deferral had asked for

The strand that produced the earlier result ended with a list of what it had not done, and one item was: a sparse representation of the sample marks, which is the floor under the half-index saving and is a bit vector with one bit in s set.

That sentence is exactly right. It names the component, names why it matters, and names what would fix it.

What it does not say is that fixing it would reduce the saving the strand had just reported — and it would not have been reasonable to expect that. A deferral is written to say what is left, and this one describes a floor as a limit on how much better the result could get. It is a limit on how much of the result was real.

That reversal is worth noticing because it says something about how deferrals should be read. A deferral naming a component as a floor is a deferral naming a component that is large, and a large component being replaced changes every number it was part of — including the ones in the essay that named it.

A price with no structure under itTwo objects that agree about space and disagree about time. The upper pair is bits: the size model charges 3,591 and the built Elias-Fano array costs 3,905, the difference being the directory a select needs — 8.0% of the structure, and exactly the omission that reporting a plain bit vector as n bits makes. The lower pair is one rank: the structure does a select on its high vector and then walks 0.70 entries of a bucket, because the low width is chosen so a bucket holds about one; the model does a binary search over 599 positions, which is 10 steps. The accounting was right and the object was not there.bits heldthe model3,591the structure3,905one rank, in operationsbinary search10 stepsselect and walk1 select + 0.7016,385 rows · one in 32 marked14x on the operation
Fig. 4 The other thing building the structure exposed: an accounting that had priced this encoding for several strands without an object behind it.

What the corrected number is

The saving from dropping a counting-only half’s locating apparatus, with marks properly represented:

At one in four: 31.4%. At one in eight: 23.8%. At one in sixteen: 16.3%. At one in thirty-two: 10.2%. At one in sixty-four: 5.9%. At one in a hundred and twenty-eight: 3.3%. At one in two hundred and fifty-six: 1.8%.

The number a reader should carry is a range and a direction: between a tenth and a fiftieth, falling steeply with the sampling rate, and negligible on any index sampling sparsely.

The old summary — about a sixth, flattening at an eighth — is replaced by a summary with no flat part in it, which is a worse summary in the sense that it cannot be reduced to one number, and a better one in that the number it replaces was about an artefact.

What the reverse half is still worth dropping

The retraction should not be read as saying the half-index idea was empty, and the numbers say why.

At one in thirty-two, 10.2% of a bidirectional index is still a tenth of a structure, removed by not building something. That is a better return than almost anything in this field costs to obtain: no new machinery, no query slowdown, no compromise — the reverse half genuinely is never asked for a position, and the arrays genuinely are not needed.

What has changed is the ordering of the improvements available to a bidirectional index. Before this strand, dropping the reverse half’s locating apparatus was the largest single thing anybody could do to one. Now representing the marks is larger at sparse rates and comparable at dense ones, and the two together are larger than either.

That ordering matters to somebody deciding what to implement. A tenth for a deletion and a fifteenth for an encoding, or a sixth for the deletion alone as the earlier essay would have suggested — the second reads as one improvement being clearly dominant and the first as two of comparable size.

A sixth of what, exactly is the essay that established this collection’s rule about quoting a share with its denominator, and it was written about this same saving one strand earlier. The rule it produced was right and insufficient: the share was quoted with its sampling rate, correctly, and the thing it was a share of had a badly represented component in it that nobody had questioned.

So the rule wants a second clause. A share carries its denominator, and a denominator carries what it is made of.

Four prices for one set of marked rowsThe same 513 marked rows out of 16,385, held four ways, at a sampling rate of one in 32. The plain vector spends one bit a row and is 19,475 bits. Elias-Fano splits each position into a 4-bit low part and a high part written in unary, and is 3,905 — 20.1% of the plain vector. Compressed blocks reach 4,557, which at this density is close but not equal. The fourth row is not a structure: it is the accounting this collection has charged for Elias-Fano since the repetition strand, and it is 314 bits under the built object because it omits the directory a select needs.plain bit vector19,475compressed blocks4,55723.4%Elias–Fano3,90520.1%positions, priced as Elias–Fano3,59118.4%16,385 rows · one in 32 markedElias-Fano at 20.1%
Fig. 5 The component the denominator was made of: four prices for one set of marked rows, at the rate the sixth was quoted at.

What a reader of the earlier essay should do

The practical question a retraction raises is what to do with the thing being retracted, and there are three defensible answers.

Leave it and link. The measurement stands, the structure it measured is one people build, and a reader who arrives at it from a search engine should find the number and the correction together. That is what this collection does.

Rewrite the number. Tempting, and it destroys the information that two structures exist. A reader who finds 10.2% in an essay about dropping the reverse half’s apparatus cannot tell whether that is a measurement of a plain-marked index or a sparse-marked one, and the difference is the entire point.

Withdraw it. Appropriate for a measurement that was wrong. This one was not: it correctly measured a structure that correctly implemented what every published account describes.

The first is right and it has a cost worth naming, which is that the collection now contains two numbers for one saving and a reader has to notice which structure each is about. That is a real burden and the alternative burdens are worse.

The composition, which is the useful half

There is a way of reading the two savings together that makes both worth having, and it is the one this strand ends on.

The half-index saving removes an array from one of two halves. The sparse representation shrinks an array in both. They are not alternatives; they compose, because one is a deletion and the other is an encoding.

Applied cumulatively at one in thirty-two on a bidirectional index over sixteen thousand characters: the plain structure is 250,584 bits; dropping the reverse half’s locating apparatus takes it to 226,504 (90.4%); representing the surviving marks sparsely takes it to 210,934 (84.2%).

The second step is worth 15,570 bits against the first step’s 24,080 — which is to say the encoding is worth nearly two thirds of what the deletion was, on a structure where the deletion was the headline.

The ladder, and the rung that spends is where that cumulative accounting is drawn, and it has a third rung: the whole saving spent on sampling the surviving half four times as densely, which lands at 96.4% of the original size with a locate several times faster.

The sparse representation is not always the smaller oneThree representations of the marked rows of one 16,384-character index, against the sampling rate. The plain vector is flat, because it spends a bit a row whether the row is marked or not — that flatness is the whole reason the locating apparatus does not vanish as the sampling thins. Elias-Fano falls with the density and crosses the plain line at one in 4; at one in 1 it is 2.00x the plain vector, because a low width of zero puts every position in the high vector. Compressed blocks and Elias-Fano meet at one in 16, 20 bits apart: below that the blocks win and above it the split does.01e+42e+43e+44e+450100one sampled position in every …bitsplain, one bit a rowcompressed blocksElias-Fano16,384 rowscrosses at one in 4
Fig. 6 The representations the saving depends on: the marks alone, across the dial, where the plain line’s flatness is the whole of the effect.

Other flattening curves in this collection

If the habit is worth having then it should have somewhere to be applied, so it is worth naming the curves in this collection that flatten and saying whether their asymptotes have been priced.

A sampling that costs more than the array draws a run-length index’s parts against the copy count and finds one of them not shrinking. That asymptote was priced — it is the regular suffix-array sampling — and the answer was to change the sampling policy entirely, which is what the sampling that follows the runs is.

What is still proportional to n is the same question asked systematically of one structure, and it is the closest thing this collection has to the habit already being a habit.

The threshold that reaches zero draws a filter’s selectivity flattening, and the asymptote there is a property of the data rather than of a representation — so there is nothing to price.

Two of the four have been chased and two have not, which is a better rate than this strand’s own history suggested. What distinguishes the ones that were chased is that their asymptote was a structure rather than a term: a sampling policy is a thing to replace and “the marks are n bits” reads as a fact.

The split is chosen at the flat bottom of a shallow curveWhat each choice of low width costs, for 257 marks over 8,193 positions. The low parts cost m·w and the high vector costs m + n/2^w, so the total falls steeply while the high vector dominates and rises linearly once the low parts do. The textbook split is ⌊log₂(n/m)⌋ = 4, which costs 1,798 bits; rounding it up instead — which is what this collection's own size model has always done — gives 5 and costs 1,799. One bit apart on five thousand. That flatness is why an accounting written years before the structure prices it correctly, and it is a fact about the encoding rather than a coincidence: the minimum sits at 2^w ≈ n·ln2/m, within a factor of 1.44 of the split either way.02e+34e+36e+38e+302468bits kept in the low partbits⌊log₂(n/m)⌋ = 4low partshigh vector257 marks in 8,193 positions1 bits between the two roundings
Fig. 7 What replacing the term required: one parameter, chosen at the flat bottom of a shallow curve, and about two hundred lines.

What a flattening curve means

The reusable part of this is a reading habit and it is short.

A curve that flattens has a constant term in it. The constant is where the next result is.

Both of this neighbourhood’s earlier essays drew a flattening curve, identified the constant correctly, and stopped — because a curve going to a limit reads as a quantity that has been understood, and naming the reason for the limit completes the explanation.

An explanation and a target look identical on the page. What separates them is whether anybody asks what the constant costs to remove, and in this case the answer was a fifty-year-old encoding and about two hundred lines.

The general instruction: when a sweep flattens, price the asymptote. Not “identify” — that had been done twice — but price, which means building the alternative.

The check that would have caught it earlier

There is a check that would have found this at the time and it is not a check anybody would have thought to write, which is the interesting part.

The earlier essay’s rejection test was that a saving needs its sampling rate: it required the saving at two ends of the dial to differ by a factor of three, and found them differing by 2.19 — so the check was wrong and the measurement was the finding, which the essay recorded.

That 2.19 was the flattening. The check was asking “does this saving depend on the rate?” and the answer was “less than expected”, and the reason it was less than expected is the whole of this strand.

So the information was there, in a failed check, correctly recorded, one strand early. What was missing was a step from “this saving depends on the rate less than expected” to “so a rate-independent term is most of it, and what is it?”.

That step is one question and it has a name: when a quantity depends on a dial less than predicted, find the part that does not depend on it. The prediction is the thing that makes it noticeable — a check expecting a factor of three and finding 2.19 is a check that has located a constant without saying so.

This collection’s habit of writing rejection tests that state an expected magnitude, rather than merely a direction, is what made that possible. A check requiring only that the saving fall would have passed and said nothing.

What the locating apparatus is, and what it becomesThe two locating parts of an FM-index over 8,192 characters, as a share of the whole structure, against the sampling rate. Plainly represented the share flattens at 18.3% however rarely a row is kept, because the marks are n bits and do not follow the rate at all. With the marks as an Elias-Fano array the share keeps falling, to 3.7% at one in 128. At one in 32 — the rate every published size in this collection is quoted at — the whole index goes from 52,508 bits to 44,731, a saving of 14.8% for a change to one array.02040255075100125one sampled position in every …of the index, per centplain marks: 18.3%Elias-Fano: 3.7%8,192 characters14.8% off at one in 32
Fig. 8 Where the rate-independent term was: the locating apparatus’s share of an index, flattening plainly and not flattening sparsely.

The three things this strand changed

Collecting them, because they are of decreasing size and increasing generality.

A number. The half-index saving is a tenth rather than a sixth at the usual rate, and a fiftieth at sparse ones.

A structure. An index’s marks are an Elias–Fano array, which is 15% of the whole index at one in thirty-two and 18% at one in a hundred and twenty-eight.

A habit. Two essays named a floor and neither priced it. The instruction is to price it, and the reason it needs to be an instruction is that naming feels like finishing.

The third is the one that would have found this two strands earlier, and it is the one worth carrying to the next flattening curve — of which this collection has several, in fields with nothing to do with text.

There is a fourth thing, and it is about how a collection of essays behaves rather than about indexes. Three essays in this neighbourhood now say different things about the same saving: a sixth, a sixth-with-a-dial, and a tenth-falling-to-a-fiftieth. Each was right about the structure in front of it.

What makes that a collection rather than a contradiction is that the structures differ and each essay says which one it measured. A number without its structure is the failure this whole neighbourhood keeps rediscovering, and it has now been rediscovered at three levels: a share without its denominator, a saving without its dial, and a denominator without its components.

Named alongside this one

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

What links here

Every essay whose body links to this one.

The objects this essay names

Each one links to every other essay that touches it.

Bidirectional indexElias fanoIndex sizeLocatingRetractionSample marksSpace accounting