Read the next block while the program is busy with this one

A file is read front to back, so when something asks for a block, the one after
it is almost certainly wanted next. sbfsReadOne asks the disk for it straight
away and hands back the block that was wanted - so the transfer happens while
the caller is busy, and the waiting is mostly over by the time it comes back.

Printing a fourteen kilobyte file: 1,064,498 cycles at two thousand a block
becomes 976,882, and 1,576,562 at ten thousand becomes 1,032,889. The second
figure barely moves between those - seven per cent from an instant disk to a
slow one, where without it the same change costs sixty eight. A machine that
reads ahead stops caring very much how fast its disk is.

NOT FOR DIRECTORY SEARCHES, and that was tried first and thrown away. A scan
stops the moment it matches, so the block it would read ahead is one nobody
will ever look at - a transfer to fetch and another wait to throw away. It was
nineteen per cent SLOWER on a lookup at ten thousand cycles a block. Reading
ahead is a bet that the next block is wanted, and a search is exactly the case
that hopes it is not. The scan loop is untouched.

Three per cent is what it costs when the disk is instant, which is the
bookkeeping with nothing to hide behind it, and the default.

The disk has one buffer, so the only way to know what is in it is to remember
what was last asked for. Every read records that; a write clears it, because a
write fills the buffer from memory and no read asked for what is in it. Getting
that wrong would blit whatever happened to be there and call it the block
somebody wanted.

The read ahead is bounded by the file's own length, so reading the last block
does not fetch whatever follows the file on the disk - which belongs to somebody
else and would be paid for twice, once to fetch and once to discard.

It cost one bug, and an instructive one: the next index was worked out by
stepping SbfsIndex, which is the CALLER'S and is still wanted after the return -
handleFileBlock compares it against the file's length to see whether this was the
short last block. Every block reported the wrong number of bytes, and the output
of Type skipped five lines in the middle. It has a place of its own now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-08-25 22:36:22 -04:00
co-authored by Claude Opus 5
parent d4cba36c5e
commit db3d349da8
2 changed files with 123 additions and 4 deletions
+29
View File
@@ -701,6 +701,35 @@ end of the file - files are contiguous, so block nine of a three block file is a
belonging to something else, and writing it would put one file's bytes inside another with
nothing anywhere saying so.
### Reading Ahead:
A file is read front to back, so when a program asks for a block, the one after it is
almost certainly wanted next. `sbfsReadOne` asks the disk for it straight away and hands
the caller the block it wanted - so the transfer happens while the program is busy with
what it already has, and the wait is mostly gone by the time it comes back.
Nothing is done differently and nothing is done out of order. The machine simply stops
standing still.
**It is not done for directory searches, and that is not an oversight.** A scan stops the
moment it matches, so the next block is one nobody will ever look at: it costs a transfer to
fetch and another wait to throw away. Tried there, it was nineteen per cent *slower*. Read
ahead is a bet that the next block is wanted, and a search is exactly the case that hopes it
is not.
What it is worth, printing a fourteen kilobyte file:
| Cycles a block | Without | With |
| -- | -- | -- |
| 0 | 936,626 | 962,959 |
| 2,000 | 1,064,498 | 976,882 |
| 10,000 | 1,576,562 | 1,032,889 |
The second column barely moves. From an instant disk to a slow one the cost rises seven per
cent, where without it the same change costs sixty eight - which is the point: **a machine
that reads ahead stops caring very much how fast its disk is.** The three per cent it costs
at zero is the bookkeeping, paid when there is nothing to hide behind it.
### Saving Something Twice:
Which is why saving a document is not the same as writing a file, and why sbfsSaveFile exists rather than each tool doing it. A file that has grown will usually not fit where it was, so saving it means putting it somewhere else and letting go of where it was - and **the obvious order is a trap**: